> For the complete documentation index, see [llms.txt](https://faction-os.gitbook.io/faction-os-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://faction-os.gitbook.io/faction-os-docs/public-demo/docs_public-demo/architecture.md).

# Architecture

The public demo is a browser-only React application embedded in `public-demo/index.html`.

There is no build graph. Runtime dependency loading happens in the browser through an import map and CDN script tags.

## Runtime Stack

| Layer       | Implementation                                                      |
| ----------- | ------------------------------------------------------------------- |
| App shell   | `index.html`                                                        |
| UI runtime  | React 19 from `esm.sh`                                              |
| DOM mount   | `react-dom/client` from `esm.sh`                                    |
| Battlefield | Generated 2D WebP assets plus DOM/CSS tokens                        |
| Styling     | Tailwind browser v4 runtime from `cdn.jsdelivr.net` plus inline CSS |
| Fonts       | Google Fonts                                                        |
| PWA shell   | `manifest.webmanifest` and `sw.js`                                  |
| Demo media  | local files under `assets/`                                         |

## File Responsibilities

| File or directory       | Responsibility                                                                                                              |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `index.html`            | Entire demo application, import map, styles, state, helpers, React components, 2D battlefield, service worker registration. |
| `sw.js`                 | PWA shell precache and runtime cache for known CDN origins.                                                                 |
| `manifest.webmanifest`  | Install metadata, icons, theme color, scope, and start URL.                                                                 |
| `assets/showcase/`      | Splash and showcase artwork used by the demo.                                                                               |
| `assets/battlefield/`   | Generated battlefield background and hero standee WebP assets used by the demo.                                             |
| `assets/portraits/`     | Faction portrait images used by roster cards.                                                                               |
| `assets/speech/`        | Click-triggered unit voice-line MP3s used by the demo.                                                                      |
| `assets/music/`         | Background-music MP3s looped by the header icon player.                                                                     |
| `icon-*.png`            | PWA and mobile install icons.                                                                                               |
| `docs_public-demo/`     | Standalone project documentation.                                                                                           |
| `README_public-demo.md` | Short public-facing readme for the demo folder.                                                                             |

## Application Flow

1. Browser loads `index.html`.
2. Tailwind browser v4 runtime and Google Fonts load.
3. The import map resolves React and ReactDOM from `esm.sh`.
4. React mounts `App` into `#app`.
5. The splash screen appears.
6. After the user enters the demo, `useDemoLoop()` starts synthetic events.
7. `Battlefield` renders the generated 2D board, hero buttons, labels, and CSS state rings.
8. Entering the demo starts the background-music loop through `assets/music/`.
9. Clicking a seeded orc, human Engineer, elf, or delayed undead reinforcement on the board or roster plays one random local MP3 voice line for that faction.
10. Header controls and keyboard routes open overlays.
11. The service worker registers on HTTPS or local development hosts.

## Synthetic Event Loop

`useDemoLoop()` is the demo's local event engine. It owns generated browser state for:

* heroes
* missions
* notices
* scrolls
* achievements
* toasts

The loop starts only after the splash is dismissed. It periodically:

* spawns or transitions heroes
* starts missions
* completes active missions
* appends tool uses
* posts notices
* drops scrolls
* unlocks achievements

The generated objects resemble the full app's concepts, but they are not received from a server and are not validated against `@factionos/protocol` at runtime.

## Mirrored Helpers

Several helpers are inlined in `index.html` because the demo has no bundler:

* heatmap bucket building
* faction standings math
* metric formatting
* session rollup calculation
* command palette ranking

Treat these as manual mirrors. They are not imports from `apps/web/src/lib`.

## Responsive Layout

Desktop uses a three-column cockpit:

```
mission log | battlefield/about | roster/scrolls
```

Narrow screens switch to a single-column flow:

```
battlefield
mission log
roster/scrolls
about
```

The battlefield section must always have nonzero width and height. The inner 2D board uses a 16:9 container-query layout so the approved background keeps stable framing on desktop and mobile.

## Asset Strategy

Demo art, click voice lines, and background music are local to `public-demo/assets/`. This avoids relying on raw GitHub file URLs at runtime and keeps the deployed artifact self-contained for images and audio.

Background music uses an explicit `BACKGROUND_MUSIC_TRACKS` array in `index.html`; static hosts cannot enumerate `assets/music/` at runtime. The header music button is on by default, but browsers require a user gesture before sound can start, so the first play attempt is tied to the splash screen's Enter button. Stopping music stores the current track index and playback time in `localStorage`, then resume continues from that exact position.

When replacing assets:

* optimize file size before committing
* keep stable relative paths or update `index.html` and `sw.js`
* update the service worker cache version if precached files change
* verify first-load image and audio requests are same-origin

## Browser Storage

The standalone demo does not own durable server state. It uses browser storage only for local presentation behavior:

* Cache Storage stores the PWA shell, local static assets fetched by the demo, and approved CDN responses for offline reload after first visit.
* `localStorage["factionos-demo-background-music-v1"]` stores the background music track index and current time.

The compact replay concept may generate share-link data, but the full replay implementation lives in the main app.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://faction-os.gitbook.io/faction-os-docs/public-demo/docs_public-demo/architecture.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
