PRD-023 · /explore zoom-in detail layer — make planet focus a destination, not just a closeup
Status · Draft (lens + tactical-scan layers shipped on /explore; Science Lens extended to the surface routes — see the 2026-07-08 amendment) Date · 2026-06-03 (original); 2026-07-08 (amendment — Science Lens + Tactical Scan unified across surface routes) Owner · Marko Closes into · GH issue #301 (original /explore scope, closed), #382 (surface-route unification — 2026-07-08 amendment), per-slice implementation issues Builds on · #287 (planet-relative camera + 4K LOD + natural satellites + atmospheric halos)
Why this is a PRD. Spans three subsystems: visual rendering (new 3D primitives + texture swaps + shader-ish overlays), data (fleet entries for active orbiters that aren't yet in
/fleet/orbiter/, plus new "active-around-planet" relations), and UX (decision matrix for what's "always-on detail" vs what's gated by the Science Lens vs what lives in the HUD/panel). One owner, one categorisation decision, one source of truth before per-feature slices start.
What
After #287 the user can fly into a planet, get the 4K texture + atmospheric halo + moons. The view is beautiful but passive — it shows a textured sphere with moons, nothing more. There's no reason to stay zoomed in.
This PRD locks the spec for turning the planet-focus pose into a destination with story-rich layers a user would actually explore:
- Always-on detail — physical features that are simply there (mission spacecraft orbiting, ring shadows, axial tilt, city lights). No toggle.
- Science Lens additions — conceptual physics overlays gated on the existing lens toggle (Hill sphere, Lagrange points, magnetic field, sub-solar point).
- HUD / info-panel additions — text + UI affordances (light-time, scale comparison, planet stats, prograde indicator).
The full set spans ~10 distinct features. This PRD groups them, picks the marquee 4 for the first slice, and surfaces the fleet-data implications.
The META decision
Where does each feature belong — zoom-in detail, Science Lens, or HUD?
The principle:
| Category | What belongs here | Why |
|---|---|---|
| Always-on detail | Things that exist in physical reality at the depicted moment | A user shouldn't have to toggle a layer to see that Jupiter has rings, that Mars has spacecraft around it, or that Earth has city lights. These are facts. |
| Science Lens | Conceptual physics that's invisible to the eye | Magnetic fields, Lagrange points, Hill spheres — you can't see these by looking at the planet. Lens makes the physics-of-the-system visible by user choice. |
| HUD / panel | Reference info, scale anchors, navigation cues | Light-time, gravity, "Earth diameter at this scale" — text + tiny UI affordances. Always-on text-y stuff, not 3D geometry. |
Each candidate feature classified below.
Categorised feature catalogue
Always-on zoom-in detail (Slice A)
These render on every planet at every zoom level below PLANET_LOD_IN_RATIO. No user toggle.
| # | Feature | Per-body specifics | Data needs |
|---|---|---|---|
| 1 | Active orbiters as 3D glyphs | Mars: MRO, MAVEN, Mars Express, ExoMars TGO, Hope, Mangalyaan, Tianwen-1. Jupiter: Juno. Saturn: (none active; historical Cassini ghost path). Venus: Akatsuki. Earth: ISS + Tiangong (already on /earth — link or render here too). | Per-orbiter altitude_km + inclination_deg in /fleet/orbiter/<id>.json. Today partial; need to backfill for missions that lack it. |
| 2 | Spin axis with obliquity tilt | Line through planet centre at real axial tilt. Earth 23°, Uranus 98°, Venus 177°. | axialTilt field in planets.json (already present). |
| 3 | Ring shadow on Saturn | Dark band across Saturn's cloud tops where rings occlude sunlight. Anti-solar projection of ring annulus onto sphere. | None — geometric only. |
| 4 | Galilean shadows on Jupiter | Real-time transit shadow dots for Io/Europa/Ganymede/Callisto on Jupiter's day side when geometrically possible. | None — projection of moon position onto planet surface. |
| 5 | Earth's night-side city lights | Swap to a city-lights texture on the night hemisphere. Standard astro-visualisation trick. | New 4k_earth_lights.jpg texture (NASA Black Marble, public domain). |
| 6 | Hero spacecraft trajectory | Per planet, one notable mission's path drawn as a fading arc. Voyager 2's outbound from Uranus / Neptune. Juno's polar plunge at Jupiter. Cassini grand-finale at Saturn. | Per-mission trajectory polylines — could derive from existing /fly cislunar data or hand-author short arcs per body. |
Marquee 4 for the first slice (highest visual-return per LOC):
- A1 — Active orbiters at Mars (5+ active missions, immediate "you're visiting" feel)
- A2 — Spin axis on Uranus (Uranus on its side is the single most "wait what" fact in the solar system)
- A3 — Saturn's ring shadow (the iconic photo, every Saturn render needs it)
- A4 — Earth's city lights (most viscerally "alive" detail, swaps a texture)
Remaining items (Galilean shadows, hero trajectories, other-planet orbiters) land in Slice C.
Science Lens additions (Slice B)
Toggled by the existing Science Lens button. Conceptual physics overlays that don't appear in nature.
| # | Feature | Description | Where the lens unlocks it |
|---|---|---|---|
| 7 | Magnetic field / radiation belts | Stylised teardrop shell around the planet showing magnetosphere shape. Jupiter's tail extends to Saturn's orbit. Earth Van Allen. | New lens layer magnetosphere |
| 8 | Hill sphere boundary | Translucent wireframe sphere at the gravity-dominance radius. The "you're in this planet's authority" volume. | New lens layer hill-sphere |
| 9 | Lagrange points L1–L5 | Five labeled markers around the orbit. L2 = JWST sits here. L4/L5 = Trojan asteroids. | New lens layer lagrange-points |
| 10 | Sub-solar point + terminator emphasis | Pulsing dot at planet's noon longitude + sharper day/night line. Anchors "the Sun is THAT way". | Currently the gravity arrows do this implicitly — promote to its own layer? |
Marquee 2 for Slice B:
- B1 — Hill sphere (universal, simple geometry, sci-fi-rich)
- B2 — Lagrange points (educational, scientifically real, photogenic markers)
Remaining items (magnetic field, sub-solar point) land in Slice D.
HUD / panel additions (Slice E — polish)
Always-on text + UI. No 3D geometry.
| # | Feature | Description |
|---|---|---|
| 11 | Light-time + distance HUD | "5.2 AU · 43 light-minutes from Sun" overlay near the panel header. |
| 12 | Earth silhouette comparison | Faint Earth-radius ghost sphere in viewport corner. Instant "Jupiter is 11× Earth" read. |
| 13 | Compass rose / prograde indicator | Tiny widget on the planet's orbit showing prograde direction + spin direction. |
| 14 | Planet stats overlay | Floating semitransparent labels — GRAVITY, ATMOSPHERIC PRESSURE, ROTATION PERIOD — sci-fi "tactical scan" feel. |
Slice order
Slice A — Marquee 4 always-on detail (orbiters at Mars + Uranus tilt + Saturn ring shadow + Earth city lights)
Slice B — Marquee 2 lens overlays (Hill sphere + Lagrange points)
Slice C — Remaining always-on detail (Galilean shadows + hero trajectories + other-planet orbiters)
Slice D — Remaining lens overlays (magnetic field + sub-solar point)
Slice E — HUD polish (light-time + Earth-comparison + compass + stats overlay)Each slice ships as its own commit + e2e check. /explore baseline e2e regression suite stays green throughout.
Data implications — fleet additions
Active orbiters that need fleet entries (or backfill of altitude_km + inclination_deg) for Slice A's rendering:
| Planet | Mission | In /fleet/orbiter/? | Notes |
|---|---|---|---|
| Mars | MRO | yes (mro.json) | Verify altitude_km/inclination_deg present |
| Mars | MAVEN | check | If missing, add |
| Mars | Mars Express | yes (mars-express.json) | Verify orbit params |
| Mars | ExoMars TGO | check | If missing, add |
| Mars | Hope (EMM) | check | If missing, add (UAE — flags "global space programs" memory) |
| Mars | Mangalyaan | yes (mangalyaan.json) | Verify orbit params |
| Mars | Tianwen-1 | check | China; verify present |
| Jupiter | Juno | yes (juno.json) | Verify orbit params |
| Venus | Akatsuki | check | If missing, add (JAXA) |
| Earth | ISS, Tiangong | yes (separate route) | Cross-link only |
The "global space programs" memory applies: ensure CNSA / ISRO / JAXA / Roscosmos / UAESA orbiters are present alongside NASA's, not silently dropped.
Out of scope
- Real-time spacecraft positions — pinned orbits are fine for v1; live ephemerides are a separate initiative.
- Surface-route changes — /earth /moon /mars stay independent. /explore zoom-in is the only route touched. [SUPERSEDED 2026-07-08] — the Science Lens now extends to the surface routes, and per #382 the Tactical Scan HUD follows. See the amendment at the bottom of this doc.
- Heliocentric view — wide zoom unchanged. Only the planet-focus pose (below
PLANET_LOD_IN_RATIO) gets the new layers. - i18n strings for the new HUD labels — Slice E ships en-US; locale propagation is a separate slice once strings stabilise.
Risks + open questions
- Crowding. Each layer adds visual weight. The previous Jupiter-focus screenshot was already busy with moons + halo + arrows. Need a clear visibility hierarchy. → Mitigation: per-slice screenshots in PR descriptions; user-pref toggles in Slice E if needed.
- Fleet-data debt. Backfilling orbital params for the missing orbiters is real work — Akatsuki, Hope, MAVEN, ExoMars TGO need accurate altitude + inclination. → Slice A spec includes the data audit as Step 0.
- Decision: do magnetic field + sub-solar lens layers belong in Slice D, or do they actually belong in Slice A? Reasonable counter-argument: magnetic field is a physical thing that exists (Earth's aurora is the visible proof). → Keep in lens for v1; revisit after Slice A ships and we see how busy the focus view feels.
Done definition
- Slices A + B shipped (marquee 4 always-on + marquee 2 lens)
- /explore e2e regression suite green
- /fleet has entries for every orbiter rendered as a 3D glyph in Slice A
- Each planet's zoom-in shows ≥ 1 new layer (orbiter, ring shadow, axial tilt, city lights, hero arc) beyond #287's baseline
- Slices C-E filed as discrete follow-up issues with concrete scope (not "phase 2" hand-waves)
Amendment — 2026-07-08: Science Lens + Tactical Scan unified across surface routes
Reconciles a doc-vs-code divergence and supersedes this PRD's original "surface routes stay independent" non-goal. Tracked by #382.
What changed since the original draft
The original PRD scoped every new layer to /explore's planet-focus pose and explicitly kept the surface routes out. That boundary no longer holds:
- Geophysics lens layers already shipped to the surface routes (commit
49d59e3168).src/lib/surface-scene/SurfaceScene.sveltenow mounts per-body Science Lens overlays viaearth-geophysics-layers.ts/earth-magnetosphere-layer.ts/moon-lens-layers.ts/mars-lens-layers.ts:- Earth —
magnetosphere·axial-tilt·mag-north·tides·hydrosphere - Moon —
sub-earth·far-side - Mars —
axial-tilt·dead-dynamo·polar-caps·mars-moons
- Earth —
- The lens infrastructure was always cross-route —
science-lens.ts(master toggle) +science-layers.ts(per-layer<html>attributes) +ScienceLayersPanel.svelte(per-routelayersprop) are shared by/explore,/fly,/earth,/moon,/mars,/iss,/tiangong. Only the content decision (which overlays live where) was/explore-scoped.
New intent
The Science Lens and the Tactical Scan HUD are one unified cross-route system. Body-level physics and facts (fields, tilt, satellites, gravity, atmosphere) should read the same wherever a body appears — whether you fly to it in /explore or stand on its surface map in /moon / /mars / /earth.
Chosen surface-HUD candidates (three slices — tracked in #382)
The full /explore opportunity set was assessed against surface fit; most of it stays /explore-only (see below). Three body-intrinsic HUD elements were selected to bring to /moon · /mars · /earth:
Slice 1 — Tactical Scan (planet-stats). The one body-level overlay still missing surface-side; renders only on /explore today (src/routes/explore/+page.svelte).
- Extract the inline
PlanetStatstype +PLANET_STATSrecord +.tactical-scanoverlay out ofexplore/+page.svelteinto a shared$libmodule (data + a small component). - Add a Moon stats entry (absent today — the Moon is a satellite; only
SATELLITE_STATSdiameter exists, not the full gravity/atmo/temp set). - Render in
SurfaceScene, gated by the existingplanet-statslayer; add'planet-stats'to the/moon·/mars·/earthpanel filter. - Reuse the existing
explore_scan_*i18n messages (already present in all locales — no new strings).
Slice 2 — Sub-solar point + terminator (sub-solar). Pulsing noon marker + sharpened day/night line — "the Sun is that way," which reads better standing on a surface than in orbit.
- Derive the marker from real geometry (body rotation + Sun direction at load), not merely the aesthetic render-light position — Orrery's scientific-honesty bar applies. The surface scenes already carry a directional Sun light, so the vector is available; the work is anchoring it to the true sub-solar longitude.
Slice 3 — Light-time / distance HUD. "Mars is 13 light-minutes away right now."
- Net-new — not built even on
/explore, and the surface routes have no sim clock. Compute an instantaneous Earth↔body distance at load from the same real-J2000-anchored positions/exploreuses (keplerPospropagated to today), render as a static readout. Heaviest of the three; lowest visual return.
Assessed but not chosen: Earth-comparison ghost (E.2) — weaker on a dedicated single-body route than in /explore's planet lineup.
Still out of scope (intent unchanged, restated for the surface context)
hill-sphere+lagrange-points— orbital-scale gravity-dominance volumes; geometrically outside a body-centered surface scene and meaningless at that zoom. Stay/explore-only./flyFlight Director /coast/conics— mission-in-flight concepts (MET, Δv, trajectory physics) with no meaning on a static surface map. A "surface ops / rover telemetry" HUD would be a separate, larger initiative, not a port.
Risk carried forward
PRD-023 Risk #1 (crowding) is sharper on the surface routes, which already carry the altitude HUD, lat/lon HUD, scale bar, and traverse chrome. Deliberate placement + desktop-and-mobile screenshots gate the surface Tactical Scan slice.