Architecture · LikeC4

Ember Tide

A backend-free, single-screen cooperative deck-builder — React 19 + Zustand + Vite compiled to a static bundle, state in memory only, no accounts and no tracking

built evolving planned research risk

The whole picture

System landscape

The system in context, then opened up into its containers.

Ember Tide — system landscape

Ember Tide — system landscape

index
Ember Tide — containers (content → engine → store → UI, with art, gates & build)

Ember Tide — containers (content → engine → store → UI, with art, gates & build)

embertideSystem

A backend-free, single-screen cooperative deck-builder — React 19 + Zustand + Vite compiled to a static bundle, state in memory only, no accounts and no tracking

Moving parts — evolving, dev-time & planned surfaces

Moving parts — evolving, dev-time & planned surfaces

movingParts

Inside each box

Containers & components

Each part decomposed into the components that implement it. Every box links to its source in the interactive explorer.

Rules engine — pure combat + economy resolver

Rules engine — pure combat + economy resolver

engineContainer

src/core + src/rules — combat and economy as functions over explicit state with no Zustand imports, so the rules stay unit-testable in isolation. Deterministic via seeded RNG; returns new state, never mutates

State store — Zustand slices at the edges

State store — Zustand slices at the edges

storeContainer

src/store — the single source of truth, kept at the edges so the engine stays pure. Domain-partitioned slices mutate board state by composing engine output; the store imports the engine, never the reverse

React board — single-screen UI

React board — single-screen UI

uiContainer

src/ui — a single-screen co-op board. Pure view + dispatch: components read Zustand hooks and fire actions on tap/drag; no game logic lives here. 44px tap targets, icon-first cards, rules text sized never to clip

Art pipeline — SVG composer + fal.ai raster panels

Art pipeline — SVG composer + fal.ai raster panels

artContainer

src/illustration + scripts — a hybrid pipeline: a deterministic SVG composer assembles the structural leaded-glass layers, and a fal.ai briefing system generates reproducible 2K raster panels. Card art falls back composer → committed raster

Quality gates — balance, accessibility & e2e

Quality gates — balance, accessibility & e2e

gatesContainer

The constraints that keep the game shippable and six-year-old-readable: balance simulations, contrast/touch-target accessibility checks, and Playwright e2e — all run on every change

How it runs

Walkthrough flows

Dynamic views — the narrative spine of the system, step by step.

Walkthrough — a tap becomes new state

Walkthrough — a tap becomes new state

playFlow

The clean spine in motion. A tap is a dispatch; the store composes the pure engine output into board state; Zustand notifies subscribers and the view re-renders. No game logic lives in the UI, and the engine never imports the store.

Walkthrough — rendering stained-glass art

Walkthrough — rendering stained-glass art

artFlow

A hybrid pipeline. The deterministic SVG composer always produces structural leaded-glass layers; where a reproducible 2K raster panel exists (generated offline from a committed fal.ai prompt and cached in git), the renderer prefers it. Nothing calls fal.ai at runtime.

Walkthrough — the quality gates

Walkthrough — the quality gates

gateFlow

Balance and readability are correctness properties, not polish. Every change runs balance simulations against the pure engine (win rate in a 40–70% band) and contrast/touch-target checks against the UI; a hosted-CI deploy guard keeps the build local-household only before it ships to the website.

Where it runs

Deployment

What runs where, and the process & data boundaries between the pieces.

Deployment — where each piece runs

Deployment — where each piece runs

deployment

Explore it live

The figures above are static exports. The interactive explorer lets you pan, zoom, follow relationships, and jump from any box to the source.