* state-binding.ts: normalise planet size by the engine's typical
mid-range (`SIZE_NORMALIZER = 100`) so legacy fixtures recording
Size in the hundreds do not blow up the world-unit disc and start
overlapping neighbouring planets. The cube-root growth stays;
Size-800 reads twice as big as Size-100.
* cargo-routes.spec.ts: retire the selection-ring CirclePrim from
the expected primitive count (4 planets + 3 cargo arrow lines = 7).
* map-toggles.spec.ts: bombing-rings → planet outlines (the high-bit
0xc… range is permanently empty); planet-names persist test waits
for the renderer's debug providers and for the IndexedDB write to
flush before reload.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Drains six F8 polish items (parent #43) in one feature:
а) Chrome cleanup
- п.6 — remove the AccountMenu (settings/sessions/theme/language/logout
∼ rudimentary in-game) and replace it with a single icon-button
light/dark theme toggle. The toggle flips an in-memory `theme.override`;
game-shell unmount calls `theme.clearOverride()` so the lobby (and
any re-entry) re-projects the persisted lobby choice.
- п.8 — remove the wrap-scrolling radio from the map gear popover. The
per-game `wrapMode` store and the renderer's no-wrap path stay in
place for a future engine-side topology feature; only the UI surface
is dropped (wrap is a server-side concept, not a per-session UI
affordance).
б) Inspector compact rows (single idiom: select + ✓ apply / ✗ cancel,
or contextual edit/remove/add)
- п.13 — planet name is now click-to-edit: clicking the name opens an
inline `<input>` + ✓ confirm icon; Escape cancels; the explicit
Rename action button and Cancel button are gone.
- п.14 — production becomes one row: primary `<select>` picks
industry/materials/research/ship, conditional secondary `<select>`
picks the target (tech / science / ship class) for research and
ship contexts. Apply is gated until row state differs from the
planet's current effective production; auto-submit-on-click is
replaced by the apply-gate.
- п.16 — cargo routes collapse to one row: a single dropdown
(COL/CAP/MAT/EMP plus a placeholder that absorbs the old section
title) and contextual action buttons (add / edit + remove) to the
right. After a successful pick or remove the dropdown stays on the
type the user just acted on.
- п.32 — stationed ship groups hoist the race column into a dropdown
above the table. The dropdown seeds with the player's own race when
local groups are stationed here, otherwise the first race
alphabetically; rendered only when more than one race is in orbit.
The race column is dropped in both single- and multi-race modes —
the dropdown's value already names the active race.
Tests: unit and Playwright e2e updated for every changed test-id and
flow; new coverage added for `theme.override`, the in-game toggle, the
apply-gate behaviour, and the stationed-race dropdown. i18n keys for
the removed menu items, the wrap radios, the cargo title, and the
explicit `rename.cancel` are dropped from both locales; new
`game.shell.theme_toggle.*`, `production.main/target.*`,
`production.apply/cancel`, `cargo.placeholder`, and
`ship_groups.race_filter.aria` keys land.
Docs synced: `docs/FUNCTIONAL.md` §6.7 + `docs/FUNCTIONAL_ru.md`
mirror drop the torus / no-wrap radio mention; `ui/docs/design-system.md`
documents the lobby-owned persisted picker + the in-game ephemeral
override channel.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Unit: repoint moved screen imports (lib/screens, lib/game), mock
$lib/app-nav (appScreen/activeView) instead of $app/navigation, drop the
removed gameId props, assert screen/view selection.
- e2e: add a dev-only window.__galaxyNav affordance; specs enter a game via
enterGame(...) instead of a /games/:id URL; URL assertions become content
assertions (the URL stays /game/); reload uses waitUntil:"commit" (shallow
routing) and mocks /rpc on game entry.
- Remove the obsolete report scroll-restore test (it relied on a SvelteKit
route Snapshot that no longer exists); update the missing-membership test
to the new lobby-redirect+toast behaviour. Fix a stale report.svelte
docstring.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Serve the whole stack behind one host: site at /, game UI at /game/,
gateway REST at /api + /healthz, Connect at /rpc (prefix stripped by the
edge Caddy). The built artifact is domain-agnostic — the UI talks to the
gateway same-origin via relative URLs, so the same bundle runs under any
host with no rebuild and with CORS disabled.
- Rename the Connect proto service galaxy.gateway.v1.EdgeGateway ->
edge.v1.Gateway; regenerate Go + TS; public path /rpc/edge.v1.Gateway.
- Move the game UI under base path /game (env BASE_PATH); make the
manifest, service-worker scope, WASM loader, and all navigation
base-aware via a withBase helper.
- Relative API + /rpc Connect prefix; Vite dev proxy mirrors the strip.
- Rewrite the edge Caddy (dev + prod) for path-based routing; empty CORS
allow-lists (same-origin); single host.
- New VitePress project site (site/): i18n en/ru with switcher, LaTeX
math, minimal monospace theme; built and served at /.
- dev-deploy compose/Makefile + CI (dev-deploy, prod-build, new
site-build) build and seed the site; probes hit /, /game/, /healthz.
- Sync docs (ARCHITECTURE, gateway README/openapi, dev-deploy &
local-dev READMEs, CLAUDE.md, ui/PLAN).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
Add per-planet cargo routes (COL/CAP/MAT/EMP) to the inspector with
a renderer-driven destination picker (faded out-of-reach planets,
cursor-line anchor, hover-highlight) and per-route arrows on the
map. The pick-mode primitives are exposed via `MapPickService` so
ship-group dispatch in Phase 19/20 can reuse the same surface.
Pass A — generic map foundation:
- hit-test now sizes the click zone to `pointRadiusPx + slopPx` so
the visible disc is always part of the target.
- `RendererHandle` gains `onPointerMove`, `onHoverChange`,
`setPickMode`, `getPickState`, `getPrimitiveAlpha`,
`setExtraPrimitives`, `getPrimitives`. The click dispatcher is
centralised: pick-mode swallows clicks atomically so the standard
selection consumers do not race against teardown.
- `MapPickService` (`lib/map-pick.svelte.ts`) wraps the renderer
contract in a promise-shaped `pick(...)`. The in-game shell
layout owns the service so sidebar and bottom-sheet inspectors
see the same instance.
- Debug-surface registry exposes `getMapPrimitives`,
`getMapPickState`, `getMapCamera` to e2e specs without spawning a
separate debug page after navigation.
Pass B — cargo-route feature:
- `CargoLoadType`, `setCargoRoute`, `removeCargoRoute` typed
variants with `(source, loadType)` collapse rule on the order
draft; round-trip through the FBS encoder/decoder.
- `GameReport` decodes `routes` and the local player's drive tech
for the inline reach formula (40 × drive). `applyOrderOverlay`
upserts/drops route entries for valid/submitting/applied
commands.
- `lib/inspectors/planet/cargo-routes.svelte` renders the
four-slot section. `Add` / `Edit` call `MapPickService.pick`,
`Remove` emits `removeCargoRoute`.
- `map/cargo-routes.ts` builds shaft + arrowhead primitives per
cargo type; the map view pushes them through
`setExtraPrimitives` so the renderer never re-inits Pixi on
route mutations (Pixi 8 doesn't support that on a reused
canvas).
Docs:
- `docs/cargo-routes-ux.md` covers engine semantics + UI map.
- `docs/renderer.md` documents pick mode and the debug surface.
- `docs/calc-bridge.md` records the Phase 16 reach waiver.
- `PLAN.md` rewrites Phase 16 to reflect the foundation + feature
split and the decisions baked in (map-driven picker, inline
reach, optimistic overlay via `setExtraPrimitives`).
Tests:
- `tests/map-pick-mode.test.ts` — pure overlay-spec helper.
- `tests/map-cargo-routes.test.ts` — `buildCargoRouteLines`.
- `tests/inspector-planet-cargo-routes.test.ts` — slot rendering,
picker invocation, collapse, cancel, remove.
- Extensions to `order-draft`, `submit`, `order-load`,
`order-overlay`, `state-binding`, `inspector-planet`,
`inspector-overlay`, `game-shell-sidebar`, `game-shell-header`.
- `tests/e2e/cargo-routes.spec.ts` — Playwright happy path: add
COL, add CAP, remove COL, asserting both the inspector and the
arrow count via `__galaxyDebug.getMapPrimitives()`.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>