---
path: /domains/nyx/sky-conditions
surface: customer
domain: nyx
auth: signed-in
source: apps/oshun/web/src/app/domains/nyx/sky-conditions/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 · Sky Conditions

## Purpose

Observational sky-condition surface — tonight's seeing/transparency, seven-day
forecast, Bortle dark-sky scale reference, and a dark-sky-site finder. Wired via
`apps/oshun/web/src/app/domains/nyx/sky-conditions/page.tsx` ('use client')
which mounts `<NyxSkyConditions 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

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

- **Header**: back button (`aria-label="Go back"`), title
  `<h1>Sky Conditions</h1>`
- **Tab bar**: four tabs from `TABS` — `Tonight` (`overview`, `Gauge` icon),
  `7-Day Forecast` (`forecast`, `Calendar` icon), `Bortle Scale` (`bortle`,
  `Layers` icon), `Dark Sky Sites` (`dark-sites`, `MapPin` icon)
- **Per-tab content**:
  - `overview` — tonight's condition gauges (seeing, transparency, cloud cover,
    moon phase impact, wind)
  - `forecast` — seven-day rolling forecast
  - `bortle` — reference scale 1–9
  - `dark-sites` — list of nearby dark-sky sites

## States

- [ ] **Loading** — bundled fixture; client-only
- [ ] **Default tab** — `Tonight` (verify initial `activeTab`)
- [ ] **Tonight populated** — gauges show current values
- [ ] **Forecast populated** — seven days listed
- [ ] **Bortle reference** — non-interactive scale 1–9
- [ ] **Dark sites populated** / **empty**
- [ ] **Offline** — static bundle; works offline

## Interactions

### Header

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

### Tab bar (four tabs)

- [ ] **Tonight tab** — sets `activeTab='overview'`
- [ ] **7-Day Forecast tab** — sets `activeTab='forecast'`
- [ ] **Bortle Scale tab** — sets `activeTab='bortle'`
- [ ] **Dark Sky Sites tab** — sets `activeTab='dark-sites'`

### Tonight tab

- [ ] **Each gauge** — read-only visual indicator
- [ ] **"How is this measured?" affordance** — verify whether explanation is
      available

### 7-Day Forecast tab

- [ ] **Each forecast day card** — read-only

### Bortle Scale tab

- [ ] **Scale rows 1–9** — read-only reference with class color

### Dark Sky Sites tab

- [ ] **Each site row** — verify whether interactive (detail / directions)

## Data & contracts

- **Reads**: bundled fixture 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 includes a "Mute light
  pollution" chip, which conceptually pairs with Bortle scale
- Sibling tools: [`domains-nyx-solar.md`](./domains-nyx-solar.md) (aurora
  probability is also a condition input)
- Component source:
  `apps/oshun/web/src/components/domains/nyx/NyxSkyConditions.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 forecast data is fixture or fetched from a weather service
      — verify the data source inside the component
- [ ] Document the data sources behind Bortle assignments per site
- [ ] Verify whether `Dark Sky Sites` provides directions / external map links
