# ui — Galaxy Cross-Platform Client `ui/` hosts the new cross-platform Galaxy client. A single TypeScript + Svelte source tree builds to five targets: web, web-mobile, standalone PC (mac/win/linux), iOS, and Android. A shared Go module (`ui/core`) carries envelope cryptography, the FlatBuffers codec, keypair management, and a thin bridge over `pkg/calc/` for UI-side game math; it is compiled to WASM for the web targets, gomobile native libraries for mobile, and embedded directly in Wails on desktop. All network I/O lives on the TypeScript side via ConnectRPC, so the Go module is a pure compute boundary on every platform. The web target is a finalized, installable PWA: a shared design-token system with light/dark themes, WCAG 2.2 AA accessibility, en/ru localisation with a persisted choice, a central error surface, and offline tolerance — see the topic docs below. The legacy Fyne client under `client/` is reference-only. Nothing in `ui/` imports from it. The strategic rationale (why Svelte, why PixiJS, why Go-as-WASM, why Wails+Capacitor) lives outside the repo at `~/.claude/plans/buzzing-questing-fountain.md`. This README is a quick orientation; deeper design notes live under `ui/docs/`. ## Targets | Target | Wrapper | Toolchain | Status | | --------------- | ---------------- | ----------------------- | ------------------------------ | | web | browser tab | Vite + WASM | implemented | | web-mobile | mobile browser | Vite + WASM | implemented | | desktop (mac) | Wails v2 | Go + Wails CLI | planned (see ROADMAP.md) | | desktop (win) | Wails v2 | Go + Wails CLI | planned (see ROADMAP.md) | | desktop (linux) | Wails v2 | Go + Wails CLI | planned (see ROADMAP.md) | | iOS | Capacitor | gomobile + Xcode | planned (see ROADMAP.md) | | Android | Capacitor | gomobile + Gradle | planned (see ROADMAP.md) | ## Layered architecture - **TypeScript + Svelte 5 frontend**, shared across all five targets, scaffolded with SvelteKit + Vite. - **PixiJS v8** with dual WebGPU/WebGL backend for the world map renderer. - **Go module `ui/core/`** as a compute-only library (canonical bytes, Ed25519 sign/verify, FlatBuffers codec, keypair, thin bridge to `pkg/calc/`) compiled to WASM, gomobile, and Wails-embedded native. - **TypeScript-side `Core` interface** with three adapters (`WasmCore`, `WailsCore`, `CapacitorCore`) selected at build time. - **`GalaxyClient`** on top of `Core` performs all network I/O via ConnectRPC (`@connectrpc/connect-web`) on every platform. - **Per-platform storage:** WebCrypto + IndexedDB on web, OS keychain + SQLite on desktop, iOS Keychain / Android Keystore + SQLite on mobile, all behind a single `KeyStore` and `Cache` TypeScript interface. - **Single-URL app-shell navigation:** the game UI is one route served at `/game/`; the screen (login / lobby / game) and the in-game view are in-memory state (`lib/app-nav.svelte.ts`), not URLs, so the address bar never changes. Browser Back/Forward move between screens via shallow routing without touching the URL — a model that also suits the bundled standalone targets (Wails / Capacitor) that have no URLs. One active view occupies the main area at a time; the sidebar holds a single tool (calculator, inspector, or order) with persistent state on switch. See [`docs/navigation.md`](docs/navigation.md). ## Repository layout ```text ui/ ├── PLAN.md staged implementation plan ├── ROADMAP.md planned desktop / mobile / multi-turn features ├── PLAN-finalize.md PWA, accessibility, localisation, error UX ├── Makefile wasm / ts-protos / web / mobile / desktop targets ├── README.md this file ├── buf.gen.yaml local-plugin TS Protobuf-ES generator ├── docs/ topic-based design notes │ ├── auth-flow.md email-code login, session store, revocation │ ├── i18n.md translation primitive, native-name picker, extensibility │ ├── order-composer.md order draft model, persistence, history-mode wiring │ ├── storage.md web KeyStore/Cache, IDB schema, baseline │ ├── testing.md per-PR / release test tiers │ └── wasm-toolchain.md TinyGo build, JSDOM loading, bundle budget ├── core/ ui/core Go module (canonical bytes, keypair) ├── wasm/ TinyGo entry point exposing Core to JS ├── mobile-bridge/ gomobile bindings (planned — see ROADMAP.md) ├── desktop/ Wails project (planned — see ROADMAP.md) ├── mobile/ Capacitor project (planned — see ROADMAP.md) └── frontend/ SvelteKit / Vite source ├── src/api/ GalaxyClient + typed Connect client + auth + session ├── src/lib/ app-shell nav + screens + game shell, env config, session store, stores ├── src/platform/core/ Core interface + WasmCore adapter ├── src/platform/store/ KeyStore/Cache interfaces + web adapter ├── src/proto/ generated Protobuf-ES + Connect descriptors + FlatBuffers TS bindings ├── src/routes/ single-URL app-shell: `/game/` dispatcher (+page.svelte) + `/__debug/*` └── static/ core.wasm + wasm_exec.js (built by `make wasm` / CI; gitignored) ``` Linked topic docs: - [`docs/navigation.md`](docs/navigation.md) — single-URL app-shell, screens and views as in-memory state, screen history, sidebar tools. - [`docs/auth-flow.md`](docs/auth-flow.md) — email-code login, session store state machine, revocation watcher. - [`docs/lobby.md`](docs/lobby.md) — lobby UI sections, application / invite lifecycle, create-game form defaults. - [`docs/i18n.md`](docs/i18n.md) — translation primitive, native-name language picker, recipe for adding a new locale. - [`docs/storage.md`](docs/storage.md) — web KeyStore/Cache, IndexedDB schema, browser baseline. - [`docs/order-composer.md`](docs/order-composer.md) — local order draft store, persistence, history-mode wiring. - [`docs/wasm-toolchain.md`](docs/wasm-toolchain.md) — TinyGo build, loading recipe, bundle size budget. - [`docs/design-system.md`](docs/design-system.md) — design tokens, light/dark theming, component conventions. - [`docs/a11y.md`](docs/a11y.md) — WCAG 2.2 AA approach, axe + keyboard gates, shared a11y primitives. - [`docs/error-state-ux.md`](docs/error-state-ux.md) — central error surface, shared loading/empty/error states, selection marker, sheet dismissal. - [`docs/pwa-strategy.md`](docs/pwa-strategy.md) — installable, offline PWA: service worker, manifest, icons. - [`docs/testing.md`](docs/testing.md) — Tier 1 per-PR + Tier 2 release test tiers. ## Build pipeline Every cross-target build flows through `make` at this level. Native targets are placeholders until their platform work lands; running `make` with no arguments prints the current placeholder map. ```text make web Vite production build make wasm TinyGo → core.wasm make ts-protos Connect-ES + Protobuf-ES gen make fbs-ts FlatBuffers TS bindings via flatc make gomobile gomobile bind → ios + android (planned — see ROADMAP.md) make desktop-mac Wails build for darwin (planned — see ROADMAP.md) make desktop-win Wails build for windows (planned — see ROADMAP.md) make desktop-linux Wails build for linux (planned — see ROADMAP.md) make ios Capacitor + xcodebuild (planned — see ROADMAP.md) make android Capacitor + gradle (planned — see ROADMAP.md) make all every target above ``` ## Local development For UI work against a real stack, the `tools/local-dev/` docker compose brings up postgres + redis + mailpit + backend + gateway in one command, and `ui/frontend/.env.development` is already wired to talk to it: ```sh make -C tools/local-dev up # build + start, wait for healthy pnpm -C ui/frontend dev # Vite on the host # UI: http://localhost:5173 # Mailpit: http://localhost:8025 ``` The stack accepts a fixed dev code (`123456`) in addition to the real Mailpit-delivered one. Full runbook in [`../tools/local-dev/README.md`](../tools/local-dev/README.md). For testing the production-shaped surface — Caddy in front of the gateway, statically served UI bundle, real `https://*.galaxy.lan` hostnames — use the long-lived dev environment at [`../tools/dev-deploy/`](../tools/dev-deploy/README.md). It is redeployed by Gitea Actions on every merge into `development`. ## Topic docs Topic docs live under `ui/docs/` (testing tiers, WASM toolchain, navigation shell, renderer internals, sync protocol, auth flow, and so on). ## Cross-references - [`PLAN.md`](./PLAN.md) — staged implementation plan (historical record of completed work). - [`ROADMAP.md`](./ROADMAP.md) — planned desktop / mobile / multi-turn projection features. - [`PLAN-finalize.md`](./PLAN-finalize.md) — PWA, accessibility, localisation, error UX finalization work. - [`../docs/ARCHITECTURE.md`](../docs/ARCHITECTURE.md) — platform architecture and the transport security model (§15) the client envelope contract derives from. - [`../docs/FUNCTIONAL.md`](../docs/FUNCTIONAL.md) — per-domain user stories that drive the UI flows. - [`../docs/TESTING.md`](../docs/TESTING.md) — project-wide testing layers; UI-specific test tiers (Vitest, Playwright) live in `ui/docs/testing.md`.