- Wrap main.js body in async main() to eliminate top-level await deadlock in Rollup
- Add npc.lastPlan so clouds persist after hidden arrival/destruction until analytic envelope expires
- Add maxEnvelopeArrival() helper; rewrite playerClouds() to use lastPlan for envelope-gated clouds
- Block markSeen() while player is mid-lane (no observation from hyperspace)
- Pass obsSys=null to playerClouds when player is in a lane (don't exclude visible band from hyperspace)
- Galaxy map clicks now select-only (intel); jumps via Nav buttons / gate diamonds only
- Add preview script, favicon no-op, .playwright-mcp/ and *.png to .gitignore, update README controls text
- Add src/ui/panel.js: sidebar with status, time controls (⏸/1×/4×/16×/Map-System toggle), navigation buttons, market table with buy/sell, cargo display, intel panel with price age tags, and a 10-entry log (newest first).
- Replace src/main.js: wires Panel + GalaxyView + SystemView together; game clock driven by PixiJS ticker at configurable DAYS_PER_SEC; panel DOM refresh at 4 Hz; VICTORY/SHIP LOST banner on end state; speed/view state via controls closure.
- Amendment A (systemView.js): gateXY uses canvas-proportional radius (min(GATE_RADIUS, min(c.x,c.y)-40)) so gates stay on-screen on small canvases.
- Amendment B (main.js): keydown handler guards e.target !== document.body to avoid hijacking keys from focused panel buttons.
- Amendment C (main.js): renderer resize event rebuilds GalaxyView static geometry and clears SystemView cache so cached transforms don't go stale.