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>
Backend now owns the turn-cutoff and pause guards the order tab
relies on: the scheduler flips runtime_status between
generation_in_progress and running around every engine tick, a
failed tick auto-pauses the game through OnRuntimeSnapshot, and a
new game.paused notification kind fans out alongside
game.turn.ready. The user-games handlers reject submits with
HTTP 409 turn_already_closed or game_paused depending on the
runtime state.
UI delegates auto-sync to a new OrderQueue: offline detection,
single retry on reconnect, conflict / paused classification.
OrderDraftStore surfaces conflictBanner / pausedBanner runes,
clears them on local mutation or on a game.turn.ready push via
resetForNewTurn. The order tab renders the matching banners and
the new conflict per-row badge; i18n bundles cover en + ru.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>