Skip to content

PRD-013 — Landing page (root / orientation)

Orrery · Product Requirements · v0.1 · May 2026

Status: Draft Depends on: Issue #74 (this PRD); minor routing-decision note inline (no separate ADR — see §technical considerations). Slice: v0.6.x (post-Fleet) Screens affected: new / landing route (replaces the existing 307 redirect to /explore); logo href in Nav.svelte already points to / so no Nav change. Principles: physics first, attribution is design, mobile-first, share by URL (PA §principles). Why this is a PRD · Today / does a 307 → /explore (src/routes/+page.ts). New users land directly in the 3D solar-system viewport with zero context: ten primary nav destinations, a Science encyclopedia, two station explorers, mission planner — none of which surface themselves on entry. Returning users get a cool view; first-timers get bewildered. This PRD defines a real orientation page that replaces the redirect.


§why

A first-time visitor today opens orrery.app, the 307 fires, and they're dropped into a black canvas with planets orbiting a sun. The nav bar shows eleven labels — EXPLORE · MISSIONS · FLEET · PLAN · FLY · EARTH · MOON · MARS · ISS · TIANGONG · SCIENCE — and they have ~5 seconds to decide what's worth their attention before bouncing.

Returning users get the immediate-into-the-app behaviour they want (great). New users get nothing telling them:

  • What is Orrery? A simulator? An encyclopedia? A planner? (Yes, all three — but they can't tell.)
  • Why does it exist? (Inspired by Artemis II, built to make spaceflight comprehensible. None of that surfaces.)
  • What can they actually do here? (The eleven nav labels are not self-explanatory — PLAN could be anything; FLY reads as a generic verb; SCIENCE is unspecific.)
  • Who built it, and what's the scope? (The footer's Credits | Library | v0.3.0 lives in the corner and is monospaced 10 px — useful but not a substitute for an intro.)

The site is small enough that we don't need a marketing page. We need an orientation page — a 1-screen scrollable narrative that explains the project in the same engineering-blueprint tone as /science's landing, then hands the user off to the right nav destination for whatever they actually wanted.

Marko's framing: "like 101 for this project — what is this, what are all the tabs, how to use it, motivation, goal. Make sure users can find their way."

This is the entrance, and right now there isn't one.


§audiences

Primary — first-time visitor (curious lay person). Found Orrery via a link, search result, social media share, or word-of-mouth. Has a vague interest in space but no idea this app exists or what it does. Will spend 30–60 seconds deciding whether to engage further. Mobile-likely (search/share-link behaviour).

Primary — first-time visitor (mission-curious enthusiast). Knows the difference between a Hohmann transfer and a free-return. Wants to find the parts of Orrery that surface real physics. Will scan for "porkchop", "ΔV", "Kepler", "EDL". Desktop-likely (this audience reads).

Secondary — returning user. Has been here before. Doesn't want to read the intro again. Should be able to skip past it in one click — either via the nav (which is always-on) or via a prominent "Explore now" button.

Secondary — educator / journalist. Wants the project's positioning, scope, and provenance for a reference or article. Will read more carefully than the curious visitor. Needs the credits/library/repo links visible.

Out of audience. Astrodynamicists doing real work — they go straight to /plan or /fly. We don't optimise for them on the landing.


§promises

The landing page promises:

  1. 30-second comprehension. A first-time visitor knows what Orrery is, why it exists, and what they can do here within the first 30 seconds (the hero + first scroll).
  2. All 11 nav destinations explained in one place. Each route gets a one-line "what it does" plus a deeper line of why it matters, in a single grid the user can scan.
  3. Honest about scope. The intro names what Orrery is not (not real flight planning, not a video game, not a marketing site for a space company), and links to the engineering decisions that constrain it (TA.md, ADR index in /library).
  4. Returning users skip past in one click. A prominent CTA at the top ("Explore the solar system") goes straight to /explore. The nav stays sticky. No friction.
  5. Mobile parity. Same content, single column, same speed. No "view full version on desktop" prompts.
  6. All 14 supported locales. Every string goes through Paraglide; full editorial overlay coverage on day one. No locale falls back to en-US for the landing copy.
  7. Honest provenance footer. The existing Credits | Library | v<version> strip stays, plus inline links to GitHub, the README, and the Tech Authority doc.

§scope

In scope (V1)

Hero. Wordmark (ORRERY 64–96 px), one-line tagline, two-line subhead, primary CTA ("Explore the solar system" → /explore), secondary CTA ("How does it work?" → scrolls to the encyclopedia preview lower on the page or links to /science).

Section: What is this? 2–3 short paragraphs. "Orrery is a browser-based solar system explorer, mission simulator, and encyclopedia. Real orbital mechanics, no backend, runs offline, in 14 languages." Honesty about what it isn't (not a flight planner; not a real-time sky chart; doesn't predict tomorrow's launch windows).

Section: Why this exists. 2–3 short paragraphs on motivation. Inspired by Artemis II. Open source. No ads, no tracking, no accounts. Designed to be share-able by URL.

Section: How to use it (guided tour). A short multi-paragraph walk-through naming the rough flow: start at /explore to see the system, click any planet to read its details, jump to /missions to find a real mission, hit /plan to see launch windows, follow it through to /fly, and use /science whenever a term confuses you. Each /route mention is a link.

Grid: 11 nav destinations (10 primary nav + 1 supplementary /library). Each card:

  • Route slug (/explore)
  • One-line "what it is" (e.g., "The solar system in 3D")
  • One-line "why you'd use it" (e.g., "Real orbital mechanics, click any planet for live position data")
  • Single icon or small SVG (engineering-blueprint style, matches /science diagrams)
  • Click → navigates to the route

The eleven cards in canonical order: /explore · /plan · /fly · /missions · /earth · /moon · /mars · /iss · /tiangong · /science · /fleet. (Fleet is in the nav; we list it.)

Footer block. Bigger than the always-on Credits | Library | v0.3.0 strip. Inline links: GitHub repo, README, License (MIT), Credits, Library, Privacy note ("No accounts. No tracking. One functional cookie for explicit locale override per ADR-057").

Locale picker remains accessible (sticks in nav per existing pattern). Language is auto-detected per #73 Gap 1; explicit picks persist per #73 Gap 2.

Out of scope (V1)

  • Onboarding tour overlays / coachmarks / interactive tutorials.
  • A separate /about or /privacy route. The landing absorbs both.
  • Marketing imagery / animated hero (engineering-blueprint tone stays — no parallax, no lottie, no video bg).
  • Newsletter signup, contact form, anything requiring backend.
  • A/B testing scaffolding. Single canonical landing.
  • "Sign in" or any account UI.
  • Locale-specific landing variants beyond translation. Same structure for every locale.
  • Cookie-banner or "we use cookies" prompt — there is one strictly-necessary cookie per ADR-057, no consent required, prose disclosure in the footer block is sufficient.
  • A separate "what's new in this version" changelog feed — /library already serves this purpose for the link-provenance side; the GitHub releases page is the source of truth for changes.

§design hints

Layout (desktop ≥ 1024 px)

  • Single centred column, max-width ~880 px.
  • Vertical stack: Hero → What is this → Why this exists → Guided tour → 11-card grid (3 cols on ≥ 1024, 2 cols on 768–1023, 1 col on < 768) → Footer block.
  • Top edge anchored to the existing 52 px nav. No nav changes.
  • Generous vertical rhythm — this page is supposed to feel like a real read, not a feature list.
  • Background: same #04040c as the rest of the app. No starfield decoration, no parallax (anti-pattern for the engineering-blueprint tone).

Layout (mobile 375 px)

  • Same vertical order. Single column throughout. Cards stack to 1-up.
  • Hero scales: wordmark 48 px, tagline 18 px, body 14 px.
  • CTAs full-width buttons with 44 px touch targets per ADR-018.
  • No carousels, no horizontal scroll regions.

Typography

  • Hero wordmark: var(--font-display) (Bebas Neue), 96 px desktop / 48 px mobile, letter-spacing 8 px.
  • Section headings: Bebas Neue, 28–36 px, letter-spacing 3 px.
  • Body copy: var(--font-editorial) (Crimson Pro, italic per design system) for the why/what/tour paragraphs — lends the editorial weight the engineering-blueprint tone wants.
  • Card labels: var(--font-display) for route slug, var(--font-mono) (Space Mono) for the descriptions.

Colour

  • Primary text: var(--color-text) (off-white).
  • Body text dim: rgba(255,255,255,0.78).
  • Card borders: rgba(255,255,255,0.12), hover rgba(78,205,196,0.4) (teal accent).
  • Primary CTA button: teal accent border + transparent fill, hover fills.
  • Secondary CTA button: ghost (just text + border).
  • No new colour tokens; uses existing tokens.css palette.

Card design

┌───────────────────────────────┐
│  [icon]    /explore           │
│                               │
│  The solar system in 3D       │
│                               │
│  Real orbital mechanics,      │
│  click any planet for live    │
│  position data.               │
└───────────────────────────────┘

Each card is an <a> with the full card hit-area as the click target. Hover: border tints teal, slight lift (4 px translateY transition).

Patterns

  • Buttons match the existing .lens-toggle / .contrast-toggle visual style for consistency with the nav chrome.
  • Section dividers: thin 1 px rule in rgba(255,255,255,0.08) between major sections; no heavy boxes or panels.
  • Reduced-motion (prefers-reduced-motion: reduce) disables the card-hover translateY transition — same pattern as the rest of the app.

§non-goals

  • Not a marketing page. No "Try Orrery now!" buttons, no testimonials, no feature showcases, no pricing (it's free), no sign-up funnel.
  • Not a documentation page. Anything beyond a paragraph belongs in /science, the README, or the docs site.
  • Not a project status page. Build version is in the footer; live release notes belong on GitHub.
  • Not a replacement for the README. The README is for people considering forking or contributing. The landing is for people who want to use the app.
  • Not a tutorial. It points toward the parts of the app that are tutorials (/science Space-101, /explore exploration). It doesn't try to be one itself.
  • Not a feature comparison. No "Orrery vs Stellarium" tables. We are what we are.

§technical considerations

Routing decision (no separate ADR needed)

Today: src/routes/+page.ts does redirect(307, '${base}/explore'). This route was never locked by an ADR (verified: no ADR text mentions //explore as a binding decision). The redirect was an informal default while the landing was deferred.

Decision: delete src/routes/+page.ts, add src/routes/+page.svelte. No new ADR — this is a pure addition rather than a supersede of a locked decision. The change is documented inline in this PRD; the routing index in TA.md gets a single-line update noting / is the landing.

Logo href in Nav.svelte already points to / via withLang(\${base}/`, activeLocale)` — no Nav change needed.

Implementation surface

  • src/routes/+page.svelte (new) — the landing component.
  • src/routes/+page.ts (delete or replace with export const prerender = true; — same as other routes; SvelteKit will use the default load).
  • messages/en-US.json — add ~30–60 keys under the landing_* prefix (matches science_* / iss_* / tiangong_* convention).
  • messages/{es,fr,de,pt-BR,it,nl,zh-CN,ja,ko,hi,ar,ru,sr-Cyrl}.json — add the same keys, translated. Manual rollout per the v0.5.x Dutch wave pattern.
  • tests/e2e/landing.spec.ts (new) — covers: page loads, hero renders, primary CTA navigates to /explore, all 11 cards render with correct slugs and descriptions, mobile 375 px layout (cards single-column), Lighthouse accessibility ≥ 95.
  • scripts/capture-screenshots.ts — add a 01-landing.png shot at the top of the deck; renumber existing shots accordingly.
  • docs/screenshots/ — regenerate all shots after numbering shift.
  • README.md — update the screenshot reference if numbering changed; add a one-line note that / is now the landing.
  • docs/guides/user-guide.md — same one-line note.
  • IMPLEMENTATION.md — add v0.6.x slice entry for #74.
  • CHANGELOG.md[Unreleased] entry under Added.

Locale flow

  • Landing copy goes through Paraglide like every other route. Auto-detect (per #73 Gap 1) gives a German-browser visitor German landing text on first paint. URL canonicalisation rewrites / to /?lang=de.
  • Cookie persistence (per #73 Gap 2) is unaffected — the landing doesn't write any new state.

Performance budget

  • Total page weight under 80 KB (HTML + CSS + 11 inline SVG icons). No heavy images, no fonts beyond the already-loaded Bebas Neue + Crimson Pro + Space Mono. No client-side JS beyond what +layout.svelte loads.
  • LCP target: < 1.0 s on a fast 3G profile (the page is mostly text + small SVG; should easily clear).
  • No new third-party assets.

URL structure

  • Canonical landing is /. Locale-stamped form is /?lang=<code>.
  • Card-clicks navigate to the canonical route URLs (/explore, /plan, etc.) using the same withLang(...) helper as the Nav.
  • The landing page is HTML at the root URL. Already prerendered via adapter-static; no extra SEO work needed beyond a sensible <title> (Orrery · A solar system explorer for the browser) and <meta description> (~150 chars).
  • Localised <title> and <meta> per locale (already supported by the existing <svelte:head> pattern).

Accessibility

  • Single <h1> (the wordmark or the tagline). Subsequent sections use <h2> / <h3>.
  • Card grid is a <ul> with each card as a <li> containing an <a> (semantic, screen-reader-friendly).
  • All decorative SVGs have aria-hidden="true".
  • Primary CTA is a <button> styled as a button (or <a> with role appropriate to the nav target).
  • Lighthouse a11y target ≥ 95 (parity with the rest of the app per ADR-025).
  • Reduced-motion respected.
  • RTL (Arabic) renders correctly — verified via existing [dir="rtl"] CSS hooks.

§definition-of-done

  • [ ] PRD-013 (this doc) reviewed and approved.
  • [ ] UXS-013 reviewed and approved.
  • [ ] src/routes/+page.svelte implemented; +page.ts updated to remove the redirect.
  • [ ] All landing strings live in messages/en-US.json under the landing_* prefix.
  • [ ] All 14 locales have full translations of the landing strings (no en-US fallback gaps).
  • [ ] npm run preflight clean (typecheck + lint + test + validate-data + build).
  • [ ] tests/e2e/landing.spec.ts green on desktop-chromium + mobile-chromium.
  • [ ] Mobile 375 px verified — single-column card layout, hero scales, no horizontal scroll.
  • [ ] Lighthouse accessibility ≥ 95 on the new route.
  • [ ] Screenshots regenerated; README updated if numbering shifted.
  • [ ] CHANGELOG entry under [Unreleased].
  • [ ] IMPLEMENTATION.md updated with the v0.6.x slice entry.
  • [ ] docs/guides/user-guide.md updated with the one-line "what's at /" note.
  • [ ] TA.md routing table touched if relevant.
  • [ ] Logo click in Nav still goes to the landing (verified — already does via href={withLang('${base}/', activeLocale)}).
  • [ ] CTA "Explore the solar system" navigates to /explore?lang=<active> correctly.

Draft v0.1 · awaiting review.

Orrery — architecture documentation · MIT · No tracking