Skip to content

PRD-014 — Surface Hotspots · progressive-quality landing-site exploration

Orrery · Product Requirements · v0.1 · May 2026

Status: Draft Depends on: PRD-006 (Moon Map), PRD-009 (Mars Surface Map), PRD-012 (Spaceflight Fleet) — this PRD layers on top of all three. Closes into: RFC-017 → ADR-059 (LOD architecture), ADR-060 (orbital-imagery texture pipeline + provenance), ADR-061 (ground-view skybox + panorama sourcing), ADR-062 (per-mission hand-authored hardware models). Slice: v0.7 (post-v0.6 mobile-UX polish). Screens affected: /moon (V1 + V2), /mars (V1 + V2), /iss (V3 reach for orbital hardware), /earth (V3 reach for crewed-spacecraft callouts). Principles: physics first, attribution is design, mobile-first, share by URL, no compromise on imagery fidelity (this is the headline feature). Why this is a PRD · Today, Apollo 11's Tranquillity Base is a small dot on a textured Moon sphere. Curiosity at Gale Crater is a small dot on a textured Mars sphere. The user clicks the dot, a panel opens with a photo gallery. The gallery photos are world-class — Aldrin in front of the LM, the Solar Wind Composition foil unfurled, Earth rising over Schmitt's helmet at Apollo 17, Curiosity's selfie at Mont Mercou. But the map view itself never improves. The user cannot fly down to the landing site, see the lander on the actual regolith, walk around the rover. This PRD defines that capability.


§why

Orrery already ships the world's most carefully-attributed solar-system encyclopedia in the browser. Every photograph carries a provenance row. Every mission has its real flight events. The /science integration explains every term. And yet, when the user clicks Tranquillity Base on the lunar near-side disc, the visual response is identical to clicking any other dot: the dot lights up, a panel opens, the photo gallery loads. The map stays at its 50,000-km wide-angle view forever.

The data exists to do dramatically more. NASA's Lunar Reconnaissance Orbiter Camera (LROC) has imaged every Apollo landing site at 0.5 m/pixel — you can see the descent-stage shadow, the discarded gold-foil from the LM, the rover tracks at Apollo 15/16/17, the astronauts' footprint paths. NASA's Mars Reconnaissance Orbiter HiRISE camera has imaged Curiosity, Perseverance, InSight, Phoenix, every Viking and Soviet lander — at 25 cm/pixel. NASA has panorama datasets from every Apollo EVA, from Curiosity, from Perseverance, in equirectangular form, in the public domain. The 3D shapes of every lander and rover are documented to engineering tolerance.

None of this surfaces in /moon or /mars today.

The vision: a user clicks Apollo 11 on the Moon. The camera descends. As it descends, the dot doesn't just enlarge — it morphs through three quality tiers. At wide zoom: a tiny three-leg silhouette (Tier 0, what we have). At medium zoom: a recognisable 3D Apollo LM with descent + ascent stages, four splayed legs, gold foil, ladder, S-band antenna (Tier 1). At close zoom: the camera is hovering 80 m above the actual surface, and the moon texture under the LM has been replaced by a high-resolution circular patch of the real LROC orbital mosaic showing the descent-stage shadow, Buzz's MESA, the footprint trail (Tier 2). One more click — "Visit" — and the camera transitions to ground level. The user is standing 5 m from the LM. Around them, the actual Aldrin/Armstrong panorama photographs wrap as a skybox. They can look around. Annotations appear: Tranquillity Base · Apollo 11 · July 20, 1969 · Mare Tranquillitatis (Tier 3).

This is the moment Orrery becomes irreplaceable. Not "another solar-system explorer" — the place where you can stand at Tranquillity Base in 14 languages, on a phone, offline, sharing by URL.

Marko's framing: "WIRED is a baby compared to what we'll build here. National Geographic will call us. NASA will hire us." This PRD codifies the no-compromise promise that gets us there.


§audiences

Primary — curious lay person who has heard of Apollo and Curiosity. The "I saw something on TV about Mars" visitor. Knows roughly that humans landed on the Moon and rovers are on Mars; has no detailed sense of where, how, or what those sites look like. Wants to be transported — not lectured. Mobile-likely, attention-budget low. The hotspot system is the single feature designed for this audience — it turns abstract dots into a place they can stand.

Primary — space enthusiast / educator. Knows the Apollo missions by number, knows the rover names, has seen the famous photos. Wants the comparison — six Apollo landing sites side-by-side at the same scale, six Mars rovers across 25 years of exploration, the failed Soviet attempts as ghost markers. Wants the fidelity — every detail correct, every photo dated and credited, the regolith at the right brightness.

Primary — astrodynamicist / scientist. Comes from /plan or /fly, occasionally checks where a real landing actually happened versus a porkchop target. Cares less about visual fidelity, more about positional accuracy — latitude/longitude must match published coordinates, the orbital-imagery overlay must be georeferenced correctly against the moon-projection / mars-projection mesh.

Secondary — first-time visitor on landing page. They never reach a hotspot directly. But the existence of hotspots is the answer to "what makes Orrery different." The landing page (PRD-013) will mention "Visit Tranquillity Base, Mont Mercou, Hadley-Apennine" with three thumbnails that deep-link to those hotspots. This is where the curiosity-to-engagement funnel terminates.

Out of audience. Users actively planning real spacecraft missions — they're not coming to Orrery for landing-site reconnaissance; they use NASA's Mars Trek / LRO Quickmap / planetary data system directly. We are emphatically not competing with those tools. We are bringing 5% of their fidelity to 100% of the lay-audience reach.


§promises

The hotspot system promises seven things:

  1. Progressive disclosure, not modal interruption. Zooming is the gesture that reveals more detail. The user is never forced through a dialog or a "click here to see more." The camera flies in, the model swells, the texture sharpens, the panorama unfurls — all on a single continuous wheel/pinch.
  2. Photo-realistic at the close tier. When a hotspot reaches Tier 2 it shows the real LROC or HiRISE orbital mosaic of that specific landing site, georeferenced to within 50 m of published coordinates. Tier 3 shows the actual NASA panorama photographs from the actual mission. Nothing illustrative; nothing speculative; nothing "artist's impression."
  3. Engineering-correct 3D models. Each landing-site model is hand-authored from public engineering drawings — Apollo LM descent + ascent stage proportions per NASA TN D-7700, Curiosity wheelbase per JPL drawings, Viking tripod-leg geometry per LARC reports. No artist-license; every dimension citable.
  4. Full provenance. Every orbital texture, every panorama, every 3D model carries a row in image-provenance.json / text-sources.json per ADR-046. License + agency + Commons-or-equivalent URL + date. The Credits page shows them all. A new license category — "georeferenced orbital mosaic" — is added.
  5. Mobile parity. Every tier renders on a 375 px viewport at 30 fps minimum on a mid-range Android. Asset budgets are mobile-first; the desktop just gets unused headroom.
  6. All 14 supported locales. Every annotation label, every panorama caption, every "Visit landing site" CTA goes through Paraglide. 13 sites × 14 locales = 182 overlay strings minimum (estimate: ~6 strings per site → ~1,100 total).
  7. No degradation of the existing experience. Today's /moon and /mars pages work. The hotspot system is additive — Tier 0 is what we have today, Tier 1+ unlocks progressively. A user who never zooms past the wide view sees no change. Performance, accessibility, mobile, and i18n behaviour at Tier 0 are protected.

§scope

In scope (V1 — "the seven iconic sites")

Moon hotspots, full Tier 0–2:

  • Apollo 11 (Tranquillity Base) — the canonical demo site.
  • Apollo 17 (Taurus-Littrow) — last crewed lunar mission, deepest exploration.
  • Chang'e 5 (Mons Rümker) — most recent sample return.
  • Luna 9 (Oceanus Procellarum) — first soft landing on any celestial body, 1966.

Mars hotspots, full Tier 0–2:

  • Curiosity (Gale Crater) — longest-running active surface mission.
  • Perseverance (Jezero Crater) — most recent rover, most ambitious mission.
  • Viking 1 (Chryse Planitia) — first US Mars landing, 1976.

For each V1 site:

  • A hand-authored 3D model of the lander/rover (Tier 1).
  • A circular orbital-imagery patch (1 km × 1 km on the surface, 2048×2048 px JPEG from LROC NAC / HiRISE), Tier 2.
  • 3–6 ground-level annotation markers within the patch (LM, US flag, Solar Wind Composition, MESA, descent-engine scorch).
  • Provenance rows for the patch + model + annotations.

Tier transitions drive on camera distance to the surface point. Smooth fade-in via THREE.LOD (or equivalent manual dispatcher per RFC-017). Both /moon and /mars get a "Visit landing site" button in the existing detail panel that animates the camera into the Tier 2 close-up; user can wheel out at any time.

Per-route layer chip. Both /moon and /mars get a new chip in the existing hud-controls strip: HOTSPOT QUALITY · AUTO / LOW / HIGH. AUTO is the default progressive system. LOW pins Tier 0 (today's behaviour, for low-power devices). HIGH forces Tier 2 on the selected marker regardless of camera distance.

Build-pipeline integration. New scripts/fetch-hotspot-imagery.ts downloads + crops + JPEG-encodes the orbital mosaic per V1 hotspot. New static/data/hotspots/{moon|mars}/{id}.json carries the manifest (centre lat/lon, patch radius, annotation list, model id, source URLs). scripts/build-image-provenance.ts extends to register the new asset family.

Smoke + e2e. Per-hotspot Playwright test: click the marker, click Visit, assert canvas is no longer at far-zoom, assert annotations are rendered, assert canvas pixels at the patch centre are non-uniform (the LROC mosaic vs. solid-color regolith texture). Mobile + desktop variants. Console-error-free.

Out of scope (V1)

  • Ground-view skybox / panorama mode (Tier 3) — this is V2. Walking around inside the LM. Looking around at Mont Mercou. Whole separate UX shell with its own controls and audio. Promised, not in V1.
  • Tracking video — Perseverance has hours of Ingenuity flight video and rover-traverse video. A "watch the rover drive" UI is V3.
  • /earth + /iss + /tiangong hotspots — we'd add ISS module-by-module zoom (V2 reach), DSN station hotspots (Goldstone / Madrid / Canberra) on /earth (V3 reach). Out for V1.
  • Mid-zoom auto-rotation, fly-around — the camera goes in once and out once. No orbital flythrough animation. V2 idea.
  • Audio — astronaut voice clips at sites are an obvious next move (Apollo 11 "the Eagle has landed", Apollo 17 "we leave as we came"). Royalty + provenance discipline + multilingual subtitle review = its own ADR. V2.
  • VR / WebXR — the panorama framework in V2 is stereoscopy-ready. Actual VR mode (controllers, room-scale) is v0.9+.

V2 — "the immersive promise"

Tier 3 (ground-view) for the seven V1 sites: NASA panoramas as skybox. User clicks Visit → existing camera animates down; new Stand at site chip appears → second camera transition to ground level + panorama loads. ESC or Return to orbit flies back up. Single panorama per site for V1.5 (the canonical "where they planted the flag" view); multiple panorama waypoints (Apollo 17 has 50+) is V2.5.

V3 — "the full inventory"

All 12+ moon sites, all 12+ Mars sites at Tier 2. Failed landings as ghost hotspots (Beagle 2, Schiaparelli, Mars Polar Lander — coordinate-best-estimate + "site unconfirmed" provenance row). ISS modules at module-by-module zoom on /iss (Tier 2 = climb into Cupola, see the actual ISS-mounted cameras' image-of-the-day stream as a skybox). DSN station hotspots on /earth.

V4 — "the network of operators"

JAXA, ESA, ISRO, CNSA, Roscosmos partner imagery. Chang'e Yutu rover ground panoramas. ISRO Chandrayaan-3 site (the IMAGE-OF-AMBIGUITY moment — the lander is at the south pole; HiRISE has imaged it). India + China + Russia open imagery. Same provenance discipline; new agencies in defaultLicenseForAgency per ADR-046.


§non-goals (locked)

We commit to these constraints:

  1. No content we can't attribute. If a photograph doesn't have a clear NASA / ESA / JAXA / CNSA / Roscosmos / ISRO / Commons URL with a public-domain or compatible licence, it does not ship. Even if it would look great.
  2. No artist's-impression imagery. "Mars surface" backdrops painted by an artist or AI do not ship at any tier. Tier 2 = real orbital mosaic; Tier 3 = real panorama. Period.
  3. No telemetry, no accounts, no backend. Hotspot system is fully static. All assets ship in the gh-pages bundle (or are lazy-loaded from gh-pages). No "log in to unlock." No analytics on which hotspots get visited.
  4. No promotional language. No "Experience the Moon in unprecedented detail." Engineering-blueprint tone, same as /science. Marketing copy goes in the landing-page intro (PRD-013), not in feature UI.
  5. No false fidelity claims. When Tier 2 georegistration drifts beyond 50 m of published coordinates (which it will for some sites whose orbital imagery is older / less calibrated), we surface the uncertainty in the panel ("HiRISE mosaic registered ±150 m"). Honest provenance is design.
  6. No content geo-restricted by IP. Every hotspot is reachable from every country we can serve gh-pages to. No "this content not available in your region."

§UX detail — what each tier looks like

Tier 0 — wide-orbit view (today's behaviour)

Camera 4–25× planet-radius away. Marker = small low-poly silhouette (the existing /earth-quality pin pattern proposed in #121). Label leader line floats outward. Hover tooltip = site name. Click = opens detail panel as today. Nothing changes.

Tier 1 — mid-zoom (camera 1.5–4× planet-radius away)

Marker swaps to a detailed 3D model:

  • Apollo 11 LM at correct 7 m height: descent stage + ascent stage + 4 splayed legs + ladder + RTG + S-band antenna + foil texture.
  • Curiosity rover at 3 m length: chassis + 6 wheels + RTG + camera mast + ChemCam laser + robotic arm + tracks behind it.
  • Viking 1 lander: tripod legs + meteorology boom + S-band high-gain dish + sample arm.

Model is shaded by the route's lighting (sun-position-correct, ADR-058 cislunar work informs the lighting model on /moon). Label scales smoothly via the existing camera-distance scaling pattern. Halo overlay (#119) renders behind, not in front. No texture swap on the surface yet — Mars stays Mars, Moon stays Moon.

Tier 2 — close-zoom (camera 0.05–1.5× planet-radius away)

Camera is now inside the planet-radius — the user has flown in. Three things happen simultaneously over a 600 ms transition:

  1. Surface texture swaps locally. A 1 km × 1 km circular patch of the actual orbital mosaic (LROC NAC for Moon, HiRISE for Mars) fades in over the planet's base texture. The patch is alpha-feathered at the edges so the boundary is invisible. Georegistered to the site's lat/lon ±50 m.
  2. 3D model swells. From Tier 1's ~5-px-on-screen scale to ~50-px scale. Same model — no LOD-2 swap unless authoring effort permits. Camera framing makes the model legible.
  3. Annotation markers appear. Per-site list of ~3–6 named features. Apollo 11: LM Descent Stage, Buzz Aldrin (selfie position), US Flag, Solar Wind Composition Experiment, Passive Seismic Experiment, Tranquillity Base plaque. Each is a small camera-facing sprite with a label, anchored to its real position relative to the LM (within ~5 m). Click an annotation → opens a small popover with one-sentence description + the gallery image showing it.

User can wheel back out at any time; transitions reverse smoothly.

Tier 3 — ground-view (V2, not in V1)

Click "Visit landing site" → camera transitions over 1.2 s from Tier 2 down to ground level, ~5 m from the lander. Skybox replaces the wide-zoom starfield: it's the actual Apollo 11 Buzz beside the flag, Earth visible, Eagle in background panorama, projected as equirectangular onto a 1000-m radius sphere centred on the user's eye. The 3D model of the LM remains rendered — slightly transparent or occluded by the panorama background, depending on the panorama's natural composition.

User can:

  • Click-drag to look around 360°.
  • ESC to return to Tier 2 (camera flies back up).
  • Tap an annotation that's visible in the panorama (the flag pole, the descent stage) for the same popover treatment.
  • Tap "next panorama" if the site has multiple (Apollo 17's 50+ EVA station panoramas are out-of-scope for V2 — that's V2.5).

The skybox panorama is loaded lazily — only after the Tier 2 hotspot has been visited at least once in the session, the panorama prefetch kicks off. The user typically waits 1–3 s for the panorama to land; a small "loading panorama…" toast keeps them oriented. Mobile cellular networks: a data-saver: on check (when connection.saveData is true) suppresses the prefetch — user gets a "tap to load" affordance.


§content tiers and which landings get which treatment

Tier of treatmentTreatmentSites
ShowcaseFull Tier 0–3, hand-authored model, 1 km LROC/HiRISE patch, 4–6 annotations, 1+ ground panoramaApollo 11, Apollo 17, Curiosity, Perseverance, Viking 1
StandardFull Tier 0–2 only (no V2 panorama)Apollo 12, 14, 15, 16, Chang'e 5, Luna 9, Phoenix, InSight, Mars 3, Chandrayaan-3
Marker onlyTier 0 with hand-authored model (#121), no orbital patchFailed landings, recent / pending / Soviet sites with sparse imagery
Fallback (V1 default)Tier 0 with generic silhouette (today's behaviour)Everything not in the above tiers

V1 ships Showcase × 5 + Standard × 7 (12 total hotspots upgraded). V2 ships Showcase × 12 + Standard × 18. V3 ships everything.


§accessibility · mobile · i18n · performance

Accessibility. Every hotspot is reachable by keyboard. The detail panel's "Visit landing site" button is tabbable. Camera animation respects prefers-reduced-motion — if set, the camera does not animate; the view jumps directly to the destination tier. Annotations are aria-labelled. Ground-view panorama has a "describe current view" hidden-text affordance for screen readers (e.g., "You are standing at Tranquillity Base. The lunar module Eagle is 5 metres ahead. Earth is visible in the upper left of the sky."). The describe-text goes through Paraglide.

Mobile. All assets sized for ≤ 4 MB per hotspot patch (2048×2048 JPEG ~3–4 MB at quality 80). Tier-2 patch lazy-loaded on first approach (≥ 0.5× planet-radius camera distance). Tier-3 panorama lazy-loaded on Visit click. connection.saveData and connection.effectiveType === '2g' both suppress eager prefetch. Touch gestures: pinch = zoom (Tier transitions happen mid-pinch); two-finger drag = pan (ground view).

i18n. Per-site overlay schema: name, tagline, tier3_describe, plus annotations[].name and annotations[].body. 7 V1 sites × ~7 strings = ~50 strings per locale. argos covers 12 locales; sr-Cyrl manual; es manual via the existing wave-23 toolchain. Same pattern as /fleet space-suit batch — locked in by RFC-017.

Performance budget. Tier 0 today is ~200 KB total scene mass. Tier 1 adds ~5 KB per hand-authored model × 12 hotspots = ~60 KB scene-resident. Tier 2 patches are ~3 MB each, lazy-loaded (not in scene mass). Tier 3 panoramas are ~5–8 MB each, lazy-loaded on demand. No prefetch on mobile saveData. Service worker caches everything once fetched (per existing ADR-016).


§metrics

V1 success looks like:

  • All 12 V1 hotspots render Tier 2 cleanly on a Pixel 6 (mid-range Android) at 30 fps minimum during the transition.
  • Provenance manifest grows by ~36 entries (12 patches + 12 models + 12 annotation-strip aggregates).
  • e2e smoke for each hotspot passes: dot exists at Tier 0, model renders at Tier 1, patch renders at Tier 2, transitions return cleanly.
  • i18n parity 13/13 locales day one for the V1 sites' strings.
  • No regression on /moon or /mars Tier 0 rendering speed (measured by existing perf marks).
  • Zero new dependencies. Three.js LOD + existing texture pipeline. No glTF loader. No new image format.

V2 success adds:

  • Ground-view panorama loads in under 3 s on a typical 25 Mbps connection (mobile 4G typical) for all five Showcase sites.
  • Tap-to-load fallback kicks in for saveData: true and never preloads.
  • Cross-locale describe-text reviewed for each Showcase site in at least the 4 hand-reviewed locales (en-US, es, sr-Cyrl, ja).

V3 success is qualitative — "every landing on the public record reachable in 30 seconds from the homepage" — and is a v1.0 readiness criterion.


§risks + open items

  1. LROC NAC mosaic licensing. The mosaics live in the Planetary Data System (PDS); NASA public-domain status is unambiguous for the imagery, but the processed mosaic products may have a co-author (e.g., Arizona State University LROC team). RFC-017 / ADR-060 handle the per-product attribution. Best-case: existing PD-NASA category applies; worst-case: new category PD-ASU-LROC with rationale + verified URL.
  2. HiRISE georegistration drift. HiRISE images are calibrated to ±5 m on flat ground, ±50 m on slopes; the published rover-track imagery for Curiosity and Perseverance is georeferenced by JPL to the rover's own location estimate, which itself has 30 m uncertainty pre-cap. Aggregate ±100 m in worst case. We commit to the public number and surface uncertainty.
  3. Asset-budget enforcement. A 3–4 MB lazy texture per hotspot is mobile-comfortable, but if 12 V1 hotspots are visited in a single session that's ~40 MB of texture memory. Three.js doesn't auto-evict. Manual eviction policy (LRU based on visit order) lives in RFC-017 / ADR-059.
  4. Apollo 17 panorama selection. Cernan & Schmitt shot 50+ panoramas across 3 EVAs. V1.5 ships one. Which one? Likely the EVA-3 "South Massif and the LRV" panorama — most cinematic, Earth visible, clear LM in frame. ADR-061 picks per-site.
  5. WebGL feature support. Tier 2 patches use anisotropic-filtered textures (sharpness when viewed at glancing angle). Some Android browsers don't expose anisotropic > 4×. Fallback: mipmap-only, accept slight blur. No new shader code.
  6. The "uncanny valley" of mid-fidelity 3D models. A hand-authored Apollo LM at 200 polygons looks great at Tier 1 size. The same model at Tier 2 size starts to look toy-ish. Mitigation: Tier 2 framing zooms in on the terrain (where the high-res mosaic carries the visual interest); the model is supporting cast, not hero. Cinema-style — we never linger on the toy-poly.
  7. Hand-authoring volume. 12 V1 hotspots × ~3 hours per model = ~36 person-hours. Plus 12 patch authoring + provenance = ~12 person-hours. Plus i18n × ~50 strings × 14 locales = 1 day for argos + manual review. Realistic V1 build: 2 person-weeks, plus a week of polish + smoke. The work is mostly Marko-supervised model authoring per the existing pattern.
  8. Risk of feature creep. "Stand at site" leads naturally to "drive the rover," "watch the rover drive," "see what the rover sees." Each is a different feature with its own ADR. The PRD commits to the hotspot-tier transition as the V1 promise — not "make Orrery a flight simulator."

§provenance budget

This feature alone will roughly double the imagery footprint of the project:

Asset classPer hotspot× V1 (12)× V2 (30)× V3 (60+)
Orbital-mosaic patch3–4 MB36–48 MB90–120 MB180–240 MB
Ground panorama (V2+)5–8 MB60–96 MB (5 only)300–480 MB
3D model code~5 KB60 KB150 KB300 KB

The orbital-mosaic patches alone fit under gh-pages' 100 GB-month transfer cap with comfortable margin. The panoramas at V3 reach (60 sites × 8 MB) push toward 500 MB total which still ships fine but warrants CDN consideration. ADR-060 picks a delivery strategy.

Every asset gets a row in image-provenance.json. The existing fail-closed validator catches anything unattributed at build time. No exceptions, including for "obviously" public-domain NASA imagery — every row is filled.


§what success feels like

A 12-year-old in São Paulo opens Orrery on her mom's phone, taps MOON, sees the lunar disc. She taps a small pin that says Apollo 11. The pin enlarges into a tiny silver pyramid with legs. She pinches in. The pyramid swells into a recognisable spacecraft. Two more pinches and the moon under it has become photographs — actual photographs — of grey rock. Small labels float around the spacecraft: Buzz Aldrin (1969), American flag, Solar Wind, Where Eagle landed. She taps Visit landing site. The camera drops. Now she is standing on the Moon. The lunar module is in front of her. The sky is black. Above the horizon, half-lit, hangs Earth. She turns her phone. Boulders. Footprints. A discarded boot-cover. Tranquillity Base. She has never been outside Brazil.

The Portuguese caption at the bottom of the screen reads: "Tranquillity Base · 20 de julho de 1969. Você está vendo o ponto exato onde a Apollo 11 pousou."

She screenshots it, sends it to her dad.

That's V1.


PRD-014 · v0.1 draft · May 2026 · Marko Dragoljevic

Orrery — architecture documentation · MIT · No tracking