---
path: /domains/nyx/solar-system
surface: customer
domain: nyx
auth: signed-in
source: apps/oshun/web/src/app/domains/nyx/solar-system/page.tsx
status: walked
last_walked:
  '2026-05-29 automated runtime walk (Playwright) — hydration fix verified: 0
  page/console errors, render+data OK; live SR/touch/offline/telemetry pending
  manual AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md'
---

# Nyx · Solar System Explorer

## Purpose

Top-down solar-system explorer — interactive orbital view, per-planet detail
panels, side-by-side compare, and an events tab for upcoming planetary
encounters. Wired via `apps/oshun/web/src/app/domains/nyx/solar-system/page.tsx`
('use client') which mounts `<NyxSolarSystem onClose={() => router.back()} />`.

## Entry points

- **Direct URL / bookmark** — yes (signed-in)
- **In-app navigation** — verify Nyx hub link
- **Browser back affordance** — in-component back button calls `router.back()`

## Layout regions

`NyxSolarSystem`
(`apps/oshun/web/src/components/domains/nyx/NyxSolarSystem.tsx`):

- **Header**: back button (`aria-label="Go back"`), title
  `<h1>Solar System Explorer</h1>`
- **Tab bar**: four tabs from `TABS` — `Solar System` (`orbits`),
  `Planet Details` (`details`), `Compare`, `Events`
- **Per-tab content**:
  - `orbits` — interactive orbital diagram with `aria-label="Zoom out"` /
    `aria-label="Zoom in"` controls
  - `details` — per-planet stat panels (selected via planet picker)
  - `compare` — side-by-side comparison cards
  - `events` — upcoming planetary events (oppositions, conjunctions)

## States

- [ ] **Loading** — bundled data; client-only
- [ ] **Default tab** — `Solar System` orbital diagram (verify initial
      `activeTab`)
- [ ] **Zoom in / Zoom out** — orbital scale changes
- [ ] **Planet selected** — switching to `details` shows that planet's stats
- [ ] **Compare populated** — verify default comparison pair
- [ ] **Events populated** — list of upcoming events
- [ ] **Offline** — static bundle; works offline

## Interactions

### Header

- [ ] **"Go back" button** (icon, `ArrowLeft`) — `onClose` → `router.back()`

### Tab bar (four tabs)

- [ ] **Solar System tab** — sets `activeTab='orbits'`
- [ ] **Planet Details tab** — sets `activeTab='details'`
- [ ] **Compare tab** — sets `activeTab='compare'`
- [ ] **Events tab** — sets `activeTab='events'`

### Solar System / orbits tab

- [ ] **Zoom out button** (icon)
  - Screen reader: "Zoom out"
- [ ] **Zoom in button** (icon)
  - Screen reader: "Zoom in"
- [ ] **Planet tap on orbit** — verify whether tapping a planet switches to the
      Details tab and selects it

### Planet Details tab

- [ ] **Planet picker** — verify control type (button group / select)
- [ ] **Stat fields** — read-only (radius, mass, orbital period, day length,
      moons, axial tilt, etc.)

### Compare tab

- [ ] **Each comparison column** — read-only stat list
- [ ] **Planet selector per column** — verify per-column picker

### Events tab

- [ ] **Each event row** — verify whether interactive or read-only

## Data & contracts

- **Reads**: bundled solar-system data inside the component
- **Writes**: none
- **Realtime**: none
- **Caching**: static client bundle
- **Auth/role check**: middleware enforces signed-in for `/domains/*`

## Cross-references

- Domain hub: [`nyx.md`](./nyx.md) — the hub chart highlights Jupiter
- Sibling tools: [`domains-nyx-moon.md`](./domains-nyx-moon.md),
  [`domains-nyx-neo.md`](./domains-nyx-neo.md)
- Component source:
  `apps/oshun/web/src/components/domains/nyx/NyxSolarSystem.tsx`

## Open questions / known gaps

- [x] **Runtime walk (2026-05-29) — defect FIXED & verified:** React 418
      hydration mismatch resolved (time-derived values now deferred to a
      post-mount effect via `useClientNow`/`useIsMounted` from
      `@/hooks/useClientTime`; for `/coordinates` the missed `RiseSetCalculator`
      site was gated). Re-walked against a fresh build: 0 page errors, 0 console
      errors, HTTP 200. React error #418; visit https://react.dev/errors/418?a.
      React error 418 is a hydration mismatch — server-rendered HTML differs
      from the client (this view renders time/position-dependent content, e.g.
      `new Date()`/`toLocale*`, without `suppressHydrationWarning`). Fix:
      compute time-dependent values in an effect or gate with
      `suppressHydrationWarning`. Status kept `drafted` until fixed.
- [ ] Confirm whether the orbital diagram animates planet positions over time or
      is a static snapshot for the current date
- [ ] Document whether the events tab cross-links into
      `/domains/nyx/events/[eventId]` for the same event types
- [ ] Verify keyboard / screen-reader navigation of the orbital diagram
