# 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 legacy Fyne client under `client/` is reference-only.
Nothing in `ui/` imports from it.

The full staged implementation plan lives in `PLAN.md`. 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 per-phase design notes earn their place
under `ui/docs/` as they are introduced.

## Targets

| Target          | Wrapper          | Toolchain               | Phase    |
| --------------- | ---------------- | ----------------------- | -------- |
| web             | browser tab      | Vite + WASM             | 5+       |
| web-mobile      | mobile browser   | Vite + WASM             | 5+       |
| desktop (mac)   | Wails v2         | Go + Wails CLI          | 31       |
| desktop (win)   | Wails v2         | Go + Wails CLI          | 31       |
| desktop (linux) | Wails v2         | Go + Wails CLI          | 31       |
| iOS             | Capacitor        | gomobile + Xcode        | 32+      |
| Android         | Capacitor        | gomobile + Gradle       | 32+      |

## 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.
- **Mobile-first navigation:** 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.

## Repository layout

```text
ui/
├── PLAN.md                 staged implementation plan (Phases 1-36)
├── 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
└── frontend/                SvelteKit / Vite source
    ├── src/api/             GalaxyClient + typed Connect client + auth + session
    ├── src/lib/             env config, session store, revocation watcher
    ├── 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/          SvelteKit routes (/, /login, /lobby, /lobby/create)
    └── static/              core.wasm + wasm_exec.js (committed artefacts)
```

Linked topic docs:

- [`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/testing.md`](docs/testing.md) — Tier 1 per-PR + Tier 2
  release test tiers.

```text
ui/
├── README.md                 this file
├── PLAN.md                   staged implementation plan
├── Makefile                  cross-target build placeholders
├── pnpm-workspace.yaml       pnpm workspace root
├── .gitignore
├── docs/                     per-phase topic docs (added per phase)
├── frontend/                 TS + Svelte source, shared across targets
├── core/                     Go module ui/core (Phase 3+)
├── wasm/                     TinyGo entry point for core.wasm (Phase 5)
├── mobile-bridge/            gomobile bindings (Phase 32+)
├── desktop/                  Wails project (Phase 31)
├── mobile/                   Capacitor project (Phase 32+)
└── web/                      static deploy assets (Phase 30+)
```

## Build pipeline

Every cross-target build flows through `make` at this level. All
named targets are placeholders until the named phase lands; running
`make` with no arguments prints the current placeholder map.

```text
make web             Vite production build                      Phase 5+
make wasm            TinyGo → core.wasm                         Phase 5
make ts-protos       Connect-ES + Protobuf-ES gen               Phase 5
make fbs-ts          FlatBuffers TS bindings via flatc          Phase 8
make gomobile        gomobile bind → ios + android              Phase 32+
make desktop-mac     Wails build for darwin                     Phase 31
make desktop-win     Wails build for windows                    Phase 31
make desktop-linux   Wails build for linux                      Phase 31
make ios             Capacitor + xcodebuild                     Phase 32+
make android         Capacitor + gradle                         Phase 32+
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`.

## Per-phase docs

Topic docs live under `ui/docs/` and are added per phase as they're
needed (testing tiers, WASM toolchain, navigation shell, renderer
internals, sync protocol, auth flow, and so on). The staged plan in
`PLAN.md` names the topic doc each phase produces.

## Cross-references

- [`PLAN.md`](./PLAN.md) — staged implementation plan with goals,
  artifacts, dependencies, acceptance criteria, and targeted tests
  per phase.
- [`../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` from Phase 2 onward.
