The F4 selection ring is a real map primitive. The cargo-route flow has
the source planet selected, so the total primitive count is 8 (7 + the
ring circle), not 7; the line count (3) is unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The planet/ship-group sheets stay mounted on desktop but are hidden by a
media query (`display: none`); the document-level tap-outside listener
fired regardless, so the first click after selecting a planet cleared the
selection — breaking every desktop inspector/select flow in CI. Guard the
handler on the sheet's computed display (`offsetParent` is unreliable for
`position: fixed`). The swipe handle is naturally inert when hidden.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- lib/error/: classify any caught error into a stable ErrorKind from the
transport signal (HTTP status / Connect Code / fetch TypeError /
navigator.onLine); map to translated error.* messages via reportError
(sticky Retry toast for retryable kinds) or errorMessageKey (inline).
Mail compose now surfaces the translated 403/error inline.
- lib/ui/view-state.svelte: shared loading/empty/error placeholder with
the right live-region role + optional action; entity tables
(races/sciences/ship-classes) migrated, rest adopt incrementally.
- map/selection-ring.ts: accent ring around the selected planet, fed into
the map buildExtras alongside the reach circles.
- lib/ui/sheet-dismiss.ts: tap-outside + drag-handle swipe-down dismissal
for the planet/ship-group bottom-sheets (hand-rolled pointer events).
Tests: error, view-state, selection-ring, sheet-dismiss (761 total).
Docs: ui/docs/error-state-ux.md (+ index); F4 marked done.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>