> 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/docs/media/media-assets.md).

# Media Assets

## Current Asset Locations

| Location                           | Purpose                                                                                               |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------- |
| `assets/showcase/`                 | Approved cross-surface showcase media used by README and demo surfaces.                               |
| `assets/battlefield-2d/reference/` | Approved generated battlefield PNG references used for visual review and future regeneration context. |
| `apps/web/public/`                 | Browser-served runtime assets owned by the web app.                                                   |
| `public-demo/`                     | Static demo icons, manifest, service worker, and single-file demo assets.                             |
| `EXAMPLES/`                        | Gitignored quarantined legacy media and build output. Not shippable product content.                  |

## Phase 04 Media Matrix

The Phase 04 routing artifact is `.spec_system/archive/phases/phase_04/media_gap_matrix.md`. Use it before adding catalog records, promotion scripts, app audio playback, public demo cache entries, accessibility gates, or validation closeout evidence.

Current status:

* Approved runtime media: the generated 2D battlefield WebP set mirrored between `apps/web/public/battlefield/` and `public-demo/assets/battlefield/`.
* Approved references: the generated battlefield PNG reference set under `assets/battlefield-2d/reference/`.
* Local runtime audio: full app browser audio controls use code-generated Web Audio cues, plus recorded faction click voice lines served from `apps/web/public/speech/` (see Faction Click Voice Lines (Web App)). No file-backed music, SFX, alert, or celebration assets ship yet.
* Conditional tracked media: portraits, brand files, showcase media, public demo speech clips, and public demo music tracks need catalog fields, provenance, attribution, metadata, size, fallback, accessibility, and privacy checks before expansion or broader release reliance.
* Planned media: remaining file-backed voice lines beyond the shipped faction click set, alerts, SFX, celebration audio, future HUD art, achievement icons, and optional video.
* Prototype-only or rejected evidence: historical media under `EXAMPLES/`.

## Phase 04 Closeout Status

Session 08 validated the Phase 04 media pipeline on 2026-05-29. The closeout evidence lives in `.spec_system/archive/sessions/phase04-session08-media-validation-and-documentation-closeout/`.

Validated commands:

```bash
npm run media:gates:check
npm run media:check
npm run media:visual:check
npm run media:demo:check
npm run media:drafts:check
npm run battlefield:check
npm run test:e2e -- --project=app-desktop --project=app-mobile tests/e2e/app.e2e.ts
npm run test:e2e -- --project=public-demo-desktop --project=public-demo-mobile tests/e2e/public-demo.e2e.ts
```

Release-ready records remain limited to `media.battlefield.background` and `media.battlefield.heroStandees`. The visual promotion gate intentionally keeps metadata-pending and non-release warnings visible for conditional visual media, generated references, generated drafts, and quarantined/deferred records.

Public-demo speech and music are current demo-local media only. They are gesture-compatible or visible-equivalent in browser tests, but source, rights, attribution, metadata, loudness, duration, and budget blockers keep them out of release-ready status. Apart from the recorded faction click voice lines now shipped in the web app (see Faction Click Voice Lines (Web App)), full app file-backed audio remains unshipped; other cues use synthetic Web Audio only.

## Faction Click Voice Lines (Web App)

The web app ships recorded faction click voice lines - the first file-backed audio promoted into `apps/web/public/`. Twenty MP3s under `apps/web/public/speech/` play when a user clicks a hero or faction; all five factions have four clips each. Playback (`apps/web/src/store/useFactionVoiceLine.ts` over the `apps/web/src/lib/factionVoiceLines.ts` catalog) honors the existing audio opt-in, cuts off the still-playing line on a new click, and falls back to a visible toast when playback is unavailable or blocked.

These clips were wired directly through the audio opt-in rather than the Phase 04 catalog/promotion gate. Catalog records, byte-size and accessibility metadata, and service-worker/demo-parity reconciliation for the speech set remain outstanding follow-ups.

## Session 04 Visual Promotion Gate

Run the visual promotion gate from the repository root:

```bash
npm run media:visual:check
```

The gate validates explicit config in `scripts/media-visual-promotion-config.mjs`. It checks repository-relative paths, expected formats, dimensions, byte sizes, max byte budgets, metadata policy, app/public-demo mirrors, `public-demo/sw.js` cache coverage, docs references, draft manifest blockers, and quarantine rules. It does not scan arbitrary media directories and it does not promote generated drafts.

The companion gates remain required:

```bash
npm run media:check
npm run media:gates:check
npm run battlefield:check
npm run media:drafts:check
```

## Session 07 Media Release Gate

Run the root media release gate before release claims or Phase 04 closeout:

```bash
npm run media:gates:check
```

`npm run media:gates:check` reconciles the typed app catalog, visual promotion config, public-demo media config, draft manifest, docs, browser evidence, lazy media policy, and privacy redaction checks.

Approved records need accessibility, privacy, metadata, fallback, budget, docs, and browser evidence. Conditional and planned records must keep release blockers.

Current approved catalog records are `media.battlefield.background` and `media.battlefield.heroStandees`. Their runtime paths are `apps/web/public/battlefield/background.webp` and `apps/web/public/battlefield/heroes/orc.webp`, `apps/web/public/battlefield/heroes/human.webp`, `apps/web/public/battlefield/heroes/elf.webp`, `apps/web/public/battlefield/heroes/undead.webp`, and `apps/web/public/battlefield/heroes/lobster.webp`, with matching `public-demo/assets/battlefield/` mirrors. All other catalog records remain conditional, planned, deferred, rejected, or otherwise blocked until their source, rights, attribution, metadata, accessibility, privacy, fallback, budget, and docs evidence closes.

### Phase 08 Session 07 Media And Decommission Review

Session 07 rechecks media release posture while finalizing legacy evidence dispositions. The approval/action record is `.spec_system/archive/phases/phase_08/legacy_decommission_media_release_gate.md`.

Current media disposition by group:

| Group                                                                                    | Release posture                                                                                                                                                          | Gate evidence owner                                                                                         |
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| Approved battlefield runtime records                                                     | Release-ready only for `media.battlefield.background` and `media.battlefield.heroStandees` after the media and battlefield gates pass.                                   | `npm run media:gates:check`, `npm run battlefield:check`, visual promotion config, public-demo cache policy |
| Public-demo speech, public-demo music, portraits, brand, showcase, and install icons     | Conditional tracked media. Keep blockers visible for source, rights, attribution, metadata, duration or dimensions, fallback, accessibility, privacy, and budget review. | `npm run media:gates:check`, `npm run media:demo:check`, `npm run media:visual:check`                       |
| Planned app audio, SFX, alerts, celebration audio, HUD, achievements, and optional video | Planned or deferred. No release-ready claim.                                                                                                                             | Future scoped media promotion session                                                                       |
| Generated battlefield references                                                         | Approved references for the current battlefield runtime set only; not a general draft promotion approval.                                                                | `npm run battlefield:check`, docs review                                                                    |
| Generated media drafts and provider staging                                              | Non-runtime evidence. Tracked manifest records stay redacted; ignored raw staging stays out of runtime and stable docs.                                                  | `npm run media:drafts:check`, sensitive-output review                                                       |
| Unknown-provenance or quarantined `EXAMPLES/` media                                      | Reference-only, blocked from release promotion, import, copy, transform, cache, or runtime use.                                                                          | ADR 0004, Phase 04 media gap matrix, Session 07 action record                                               |

Public-demo cache posture remains unchanged for Session 07 unless tracked precache content changes. The current service-worker cache version remains `factionos-demo-v9`; background music stays lazy-loaded and excluded from `SHELL_ASSETS`. If a later change alters precached content or requires a forced offline-cache refresh, update `public-demo/sw.js`, rerun `npm run media:demo:check` and `npm run battlefield:check`, and record the new cache version in the Session 07 or Session 08 evidence.

Session 07 does not approve broad media promotion. Conditional, planned, generated, unknown, rejected, deferred, and quarantined records remain non-release until a future promotion record closes every blocker.

### Phase 08 Session 08 Media Release-Candidate Revalidation

Session 08 reran the media gates during release-candidate closeout and records the results in `.spec_system/archive/phases/phase_08/release_candidate_validation_record.md`. `npm run media:check`, `npm run media:visual:check`, `npm run media:demo:check`, `npm run media:drafts:check`, `npm run battlefield:check`, and `npm run media:gates:check` passed locally. The visual gate retained expected warnings for metadata-pending and non-release records, so those warnings are not broad media approval.

Release-ready media remains limited to the approved battlefield runtime records and their app/public-demo mirrors. Public-demo speech, public-demo music, portraits, brand, showcase, install icons, generated references, generated drafts, unknown-provenance rows, and quarantined `EXAMPLES/` media remain conditional, planned, deferred, rejected, unknown, or blocked until a future promotion record closes source, rights, attribution, metadata, accessibility, privacy, fallback, budget, and docs evidence.

### Visual Promotion Inventory

Current approved battlefield runtime paths:

```
apps/web/public/battlefield/background.webp
apps/web/public/battlefield/heroes/orc.webp
apps/web/public/battlefield/heroes/human.webp
apps/web/public/battlefield/heroes/elf.webp
apps/web/public/battlefield/heroes/undead.webp
apps/web/public/battlefield/heroes/lobster.webp
public-demo/assets/battlefield/background.webp
public-demo/assets/battlefield/heroes/orc.webp
public-demo/assets/battlefield/heroes/human.webp
public-demo/assets/battlefield/heroes/elf.webp
public-demo/assets/battlefield/heroes/undead.webp
public-demo/assets/battlefield/heroes/lobster.webp
```

Current generated battlefield reference paths:

```
assets/battlefield-2d/reference/background.png
assets/battlefield-2d/reference/heroes/orc.png
assets/battlefield-2d/reference/heroes/human.png
assets/battlefield-2d/reference/heroes/elf.png
assets/battlefield-2d/reference/heroes/undead.png
assets/battlefield-2d/reference/heroes/lobster.png
```

Current Phase 3 generated game-design implementation references:

```
assets/generated/game-design/phase03/live-enemies/live-enemy-effects-sheet.png
assets/generated/game-design/phase03/strike-vocabulary/strike-vocabulary-effects-sheet.png
assets/generated/game-design/phase03/reduced-motion/reduced-motion-static-badges-sheet.png
```

Phase 24 Sessions 08 and 09 wire and validate these three sheets in `apps/web` as typed implementation references only. The source-owned ids live in `apps/web/src/lib/generatedPhase3Assets.ts`, and the app media catalog tracks them as blocked records:

```
media.gameDesign.phase3.liveEnemiesEffectsSheet
media.gameDesign.phase3.strikeVocabularyEffectsSheet
media.gameDesign.phase3.reducedMotionStaticBadgesSheet
```

The normal web app still renders DOM/CSS battlefield markers, product labels, screen-reader summaries, and reduced-motion static labels. Runtime code must not load the `assets/generated/game-design/phase03/` paths directly, and these records are not release-ready browser media until app-owned serving paths, slicing or extraction, optimization, metadata cleanup, fallback evidence, and media gates are completed. Session 09 closeout evidence in `.spec_system/specs/phase24-session09-validation-and-documentation/phase-exit-audit.md` records the exact source paths, typed fallback labels, reduced-motion pairings, runtime-load scans, and focused tests; it does not promote these PNGs to browser-served app media.

Current portrait paths:

```
apps/web/public/portraits/orc.jpg
apps/web/public/portraits/human.jpg
apps/web/public/portraits/elf.jpg
apps/web/public/portraits/undead.jpg
apps/web/public/portraits/lobster.jpg
public-demo/assets/portraits/orc.jpg
public-demo/assets/portraits/human.jpg
public-demo/assets/portraits/elf.jpg
public-demo/assets/portraits/undead.jpg
public-demo/assets/portraits/lobster.jpg
```

Current brand and install icon paths:

```
assets/brand/factionos-logo.png
assets/brand/factionos-logo.webp
assets/brand/factionos-logo-square.png
assets/brand/factionos-logo-square.webp
apps/web/public/favicon.svg
apps/web/public/favicon.ico
public-demo/icon-192.png
public-demo/icon-512.png
public-demo/icon-maskable-512.png
```

Current showcase paths:

```
assets/showcase/factionos-strip-cover.jpg
assets/showcase/factionos-strip.webp
assets/showcase/heroes-banner.jpg
assets/showcase/strip-frames/1-dusk_muster.jpg
assets/showcase/strip-frames/2-mid_combat.jpg
assets/showcase/strip-frames/3-victory_chorus.jpg
assets/showcase/strip-frames/4-night_watch.jpg
public-demo/assets/showcase/heroes-banner.jpg
```

### Visual Promotion Policy

* Only `approved` records with no blockers are release-ready.
* `conditionally_promoted` records may stay tracked only with explicit source, rights, attribution, metadata, fallback, accessibility, privacy, or budget blockers.
* `planned`, `deferred`, `prototype_only`, `needs_replacement`, `rejected`, and `unknown` visual records are non-release evidence. Their blocker context must remain visible in the config, docs, or `assets/generated/phase04/draft-generation-manifest.json`.
* `M04-021` and `M04-023` remain DOM/CSS visual treatment rows, not image media.
* `M04-025` and `M04-026` remain quarantine or deferred evidence rows and must not produce runtime imports.
* Public-demo mirror paths must be hash-identical to their source files and listed in `public-demo/sw.js` when they are precached. The current service worker cache version is `factionos-demo-v9`.
* Generated draft records under `assets/generated/phase04/draft-generation-manifest.json` remain non-runtime until a later promotion session approves source, rights, optimization, metadata cleanup, byte budgets, accessibility, privacy, fallback, and parity.

When the visual promotion gate fails, fix the underlying source first. Do not raise byte budgets, suppress docs checks, or mark conditional media approved unless the promotion record has been reviewed and all blockers are closed.

## Session 05 Browser Audio Runtime

Session 05 adds a full app browser audio runtime boundary for synthetic local Web Audio cues only. It does not promote any audio files.

* New app settings snapshots default audio off. Users must explicitly enable audio cues, and persisted volume is bounded from 0 to 1.
* Durable settings store only `audioEnabled` and `audioVolume`. Transient browser policy state, last cue captions, blocked/failed status, and in-flight cue IDs live in `apps/web/src/store/useAudioRuntimeStore.ts` and are not written to localStorage.
* The runtime wrapper in `apps/web/src/lib/audioRuntime.ts` maps muted, unsupported, locked, unlocked, playing, blocked, failed, and unavailable states to stable visible copy.
* The synth helper in `apps/web/src/lib/voiceSynth.ts` remains code-generated Web Audio. It reports structured outcomes and cleans up oscillators, LFOs, gain nodes, filters, and cleanup timers after each cue.
* Settings, hero Speak, hero transition barks, and command palette toggles use visible equivalents. Hero state, notices, captions, badges, and settings status remain authoritative when audio is off or cannot play.
* File-backed full app voice lines, SFX, alerts, celebration clips, and music remain blocked. Future file-backed records need source, rights, attribution, loudness, duration, metadata, byte budget, fallback, accessibility, privacy, and release-gate evidence before runtime use.
* `EXAMPLES/` audio and provider draft outputs remain reference-only or non-runtime evidence and must not be copied, transformed, imported, cached, or played by the full app runtime.

## Session 06 Public Demo Media Parity

Session 06 adds a deterministic public-demo media gate:

```bash
npm run media:demo:check
```

The gate validates explicit inventory in `scripts/public-demo-media-config.mjs`; it does not scan arbitrary directories or promote quarantined media. It checks public-demo media files, byte sizes, MP3 durations through `ffprobe` when available, manifest icon references, `public-demo/sw.js` cache policy, app catalog coverage, docs references, and standalone runtime boundaries.

Current public-demo media groups:

* Approved runtime mirrors: `public-demo/assets/battlefield/background.webp`, `public-demo/assets/battlefield/heroes/orc.webp`, `public-demo/assets/battlefield/heroes/human.webp`, `public-demo/assets/battlefield/heroes/elf.webp`, `public-demo/assets/battlefield/heroes/undead.webp`, and `public-demo/assets/battlefield/heroes/lobster.webp`.
* Conditional portraits: `public-demo/assets/portraits/orc.jpg`, `public-demo/assets/portraits/human.jpg`, `public-demo/assets/portraits/elf.jpg`, `public-demo/assets/portraits/undead.jpg`, and `public-demo/assets/portraits/lobster.jpg`.
* Conditional showcase art: `public-demo/assets/showcase/heroes-banner.jpg`.
* Conditional install icons: `public-demo/icon-192.png`, `public-demo/icon-512.png`, and `public-demo/icon-maskable-512.png`.
* Conditional speech clips: `public-demo/assets/speech/elf-elunebewithyou-01.mp3`, `public-demo/assets/speech/elf-elunebewithyou-02.mp3`, `public-demo/assets/speech/elf-forkalimdor-01.mp3`, `public-demo/assets/speech/elf-forkalimdor-02.mp3`, `public-demo/assets/speech/human-for_the_king-01.mp3`, `public-demo/assets/speech/human-for_the_king-02.mp3`, `public-demo/assets/speech/human-yes_mlord-01.mp3`, `public-demo/assets/speech/human-yes_mlord-02.mp3`, `public-demo/assets/speech/orc-whachyawanmetokill-01.mp3`, `public-demo/assets/speech/orc-whachyawanmetokill-02.mp3`, `public-demo/assets/speech/orc-zugzug-01.mp3`, `public-demo/assets/speech/orc-zugzug-02.mp3`, `public-demo/assets/speech/undead-iamsworn-01.mp3`, `public-demo/assets/speech/undead-iamsworn-02.mp3`, `public-demo/assets/speech/undead-ihunger-01.mp3`, and `public-demo/assets/speech/undead-ihunger-02.mp3`.
* Conditional lazy music: `public-demo/assets/music/01_mythic_battle_theme_take_1.mp3`, `public-demo/assets/music/02_mythic_battle_theme_take_2.mp3`, `public-demo/assets/music/03_noble_heroic_oath_take_1.mp3`, `public-demo/assets/music/04_noble_heroic_oath_take_2.mp3`, `public-demo/assets/music/05_dark_tribal_war_march_take_1.mp3`, `public-demo/assets/music/06_dark_tribal_war_march_take_2.mp3`, `public-demo/assets/music/07_elven_moonlit_overture_take.mp3`, `public-demo/assets/music/08_elven_guardian_hymn_take.mp3`, `public-demo/assets/music/09_elven_blades_dance_take.mp3`, `public-demo/assets/music/10_undead_necropolis_theme_take.mp3`, `public-demo/assets/music/11_undead_lament_of_the_hollow_crown_take.mp3`, and `public-demo/assets/music/12_undead_graveborn_war_march_take.mp3`.

The current service-worker cache version remains `factionos-demo-v9`. Battlefield, portraits, showcase art, icons, and speech clips are shell precache entries. Background music tracks are intentionally excluded from `SHELL_ASSETS`; they are optional, about 44.9 MB total, and lazy-loaded by the browser after playback starts.

Catalog coverage now includes conditional records for current public-demo speech clips, background music, showcase art, install icons, and portraits. Only the battlefield runtime records are release-ready. Conditional records must keep blockers for source, rights, attribution, metadata, duration, loudness, accessibility, privacy, fallback, and budget review until later gates close.

## Typed Catalog Records

Shared catalog contracts live in `packages/protocol/src/mediaCatalog.ts` and are exported through `@factionos/protocol`. The current app-facing fixture lives in `apps/web/src/data/mediaCatalog.ts`, with pure helper functions in `apps/web/src/lib/mediaCatalog.ts`.

Add a typed catalog record before any new runtime media path is referenced by app code, docs, public demo assets, service-worker cache rules, or promotion tooling. A record should include:

* Stable id, matrix id when available, category, status, risk, owner surface, runtime surfaces, and product-use notes.
* Source paths, output paths, optional mirror paths, byte sizes, dimensions or duration, format, browser support, lazy-loading state, optimization state, and metadata state.
* Provenance, rights, attribution state and text when required, fallback behavior, accessibility review, privacy review, release blockers, and release-gate notes.

Only `approved` records can be treated as release-ready, and they must have no open release blockers. `unknown`, `planned`, `prototype_only`, `rejected`, `deferred`, `needs_attribution`, `needs_replacement`, and `conditionally_promoted` records must carry explicit blocker or condition context so they cannot be confused with approved runtime media.

Public demo mirror paths may be listed as repository-relative catalog data, but `public-demo/` remains a standalone artifact and must not import workspace TypeScript or app helper modules. Historical media under `EXAMPLES/` may be cited only as non-release traceability evidence. Do not copy, transform, optimize, or promote `EXAMPLES/` files into product runtime paths.

## Draft Generation Workflow

Phase 04 Session 03 tracks generated-draft planning under `assets/generated/phase04/`. This area is evidence only. It does not make a draft image, audio clip, music loop, SFX cue, HUD study, achievement icon, or optional video release-ready.

Tracked draft files:

* `assets/generated/phase04/README_phase04.md` defines the non-runtime boundary.
* `assets/generated/phase04/draft-briefs.md` contains redacted product briefs, target rows, fallback expectations, and rejection criteria.
* `assets/generated/phase04/draft-generation-manifest.json` records provider, model, date, output metadata, rights, cost, review disposition, and release blockers for generated, rejected, planned, or deferred draft targets.

Ignored staging lives at:

```
tmp/media-generation/phase04-session03/
```

The staging directory may contain local run summaries or raw provider outputs. It is ignored by git and must not be copied to runtime paths during Session 03. When generation is not approved, record an explicit deferral in the manifest instead of fabricating output.

Use these commands from the repo root:

```bash
npm run media:drafts:check
npm run media:drafts -- --dry-run
```

`npm run media:drafts -- --provider-run` is opt-in and must be run only for selected targets with approved budget and local credentials. Provider commands may check whether `FAL_KEY` or `ELEVENLABS_API_KEY` is present, but must never print, commit, or summarize credential values, provider account IDs, raw request payloads, raw response payloads, broad local paths, or sensitive prompt context. Dry-run must continue to work without credentials.

Manifest records must stay non-runtime unless a later promotion session updates them. Required record data includes:

* Matrix row IDs and brief ID.
* Media category and non-release draft status.
* Provider/tool name, model, and date.
* Staged output path, byte size, format, dimensions or duration when generated.
* Non-sensitive run or variation IDs when available.
* Rights, attribution, cost, reviewer disposition, rejection reason, and release blockers.

Session 04 owns visual promotion tooling, optimization, metadata stripping, path checks, parity checks, and size budgets. Session 05 owns synthetic full app browser audio controls, Session 06 owns public-demo media parity and offline loading, and Session 07 owns accessibility, privacy, and performance gates. Until those gates pass, generated drafts remain planned, deferred, rejected, or conditionally promoted evidence only.

## Generated Battlefield Assets

The 2026-05-28 generated 2D battlefield set is approved for current app and public demo runtime use. This section is the stable promotion record for the set; no separate ongoing-project manifest is required.

The assets were generated through the built-in Codex imagegen path with GPT Image 2, reviewed visually, optimized to WebP for runtime, and copied to both surfaces. Raw drafts were kept only under ignored `tmp/battlefield-2d-imagegen/` paths during review. The approved PNG references and optimized runtime copies are the durable repository record.

### Runtime Paths

| Asset                  | Approved reference                                   | Full app runtime                                  | Public demo runtime                                  |
| ---------------------- | ---------------------------------------------------- | ------------------------------------------------- | ---------------------------------------------------- |
| Battlefield background | `assets/battlefield-2d/reference/background.png`     | `apps/web/public/battlefield/background.webp`     | `public-demo/assets/battlefield/background.webp`     |
| Orc standee            | `assets/battlefield-2d/reference/heroes/orc.png`     | `apps/web/public/battlefield/heroes/orc.webp`     | `public-demo/assets/battlefield/heroes/orc.webp`     |
| Human standee          | `assets/battlefield-2d/reference/heroes/human.png`   | `apps/web/public/battlefield/heroes/human.webp`   | `public-demo/assets/battlefield/heroes/human.webp`   |
| Elf standee            | `assets/battlefield-2d/reference/heroes/elf.png`     | `apps/web/public/battlefield/heroes/elf.webp`     | `public-demo/assets/battlefield/heroes/elf.webp`     |
| Undead standee         | `assets/battlefield-2d/reference/heroes/undead.png`  | `apps/web/public/battlefield/heroes/undead.webp`  | `public-demo/assets/battlefield/heroes/undead.webp`  |
| Lobster standee        | `assets/battlefield-2d/reference/heroes/lobster.png` | `apps/web/public/battlefield/heroes/lobster.webp` | `public-demo/assets/battlefield/heroes/lobster.webp` |

### Measurements And Decisions

| Asset                  | Reference dimensions | Runtime dimensions | Chroma key        | Runtime bytes per surface | Decision and caveat                                                                                                                                                                                               |
| ---------------------- | -------------------- | ------------------ | ----------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Battlefield background | 1672x941 PNG         | 1672x941 WebP      | None              | 195,330                   | Approved. Dark readable center, five perimeter faction zones, no baked labels, no UI controls, and no character tokens. The ideal future target remains 2048x1152 if browser critique ever requires regeneration. |
| Orc standee            | 1254x1254 PNG        | 640x640 WebP       | `#ff00ff` magenta | 100,416                   | Approved. Broad silhouette, visible tusks, red forge armor, emblem disk, no baked UI text, and no detected magenta fringe.                                                                                        |
| Human standee          | 1254x1254 PNG        | 640x640 WebP       | `#00ff00` green   | 89,442                    | Approved. Readable commander bust, blue-gold armor, lion-crown shield emblem, no baked UI text, and no detected green fringe.                                                                                     |
| Elf standee            | 1254x1254 PNG        | 640x640 WebP       | `#ff00ff` magenta | 90,204                    | Approved. Readable ears, antlered moon-sentinel shape language, green-gold leaf armor, no baked UI text, and no detected magenta fringe.                                                                          |
| Undead standee         | 1254x1254 PNG        | 640x640 WebP       | `#00ff00` green   | 85,078                    | Approved. Skull face, bone crown, violet crypt palette, emblem disk, no baked UI text, and no detected green fringe.                                                                                              |
| Lobster standee        | 1254x1254 PNG        | 640x640 WebP       | `#00ff00` green   | 107,888                   | Approved. Bold orange shell silhouette, forward claws, quill-and-claw emblem, no baked UI text, and no detected green fringe.                                                                                     |

The runtime set is 668,358 bytes per surface: 195,330 bytes for the background and 473,028 bytes for the five standees. The initial budget was under 3 MB total for one background and five standees, with a target split of 1.2 MB or less for the background and 1.8 MB or less for the standees.

Session 08 reverified the app and public demo runtime copies on 2026-05-29 with `npm run battlefield:check`. The six public demo runtime paths are precached by `public-demo/sw.js`, and the current verified public demo cache version is `factionos-demo-v9`.

### Regeneration Brief

Use this brief when replacing or extending the battlefield set. Treat generated images as candidates until they are reviewed, optimized, measured, browser checked, and approved.

Shared style:

```
High-polish dark fantasy tactical cockpit art for FactionOS, a live
coding-agent battlefield. Painterly but disciplined, cinematic top-lit
materials, readable at small UI scale, dark steel and obsidian base, controlled
faction color accents, sharp silhouette language, premium strategy-game board
feel, no UI text, no labels, no logos, no watermarks, no health bars, no
buttons, no cursors.
```

Background direction:

```
Create a 2048x1152 16:9 tactical battlefield board background for a dark
fantasy coding-agent cockpit. The board is viewed from a slightly elevated
isometric camera, with a darker readable central play area and five subtle
faction zones around the edges: crimson volcanic orc forge, blue-gold human
citadel stone, green moonlit elf grove, violet bone-and-crypt undead quarter,
and orange coral tidepool lobster outpost. Include painterly terrain, small
keeps or banners near the perimeter, soft atmospheric depth, and a clear center
where DOM hero tokens and labels can be overlaid. Avoid tiny busy detail in the
center. Do not include text, UI elements, logos, watermarks, borders, health
bars, or character tokens.
```

Standee direction:

```
Create a single front-facing emblem-backed fantasy hero bust standee for
FactionOS. Use a centered bust portrait with strong silhouette, shoulders and
head visible, a compact faction emblem disk or shield behind the bust, crisp
painted edges, and no ground shadow. The image must be suitable for chroma-key
background removal and later alpha PNG or WebP output. Use the requested flat
pure chroma background only. Do not include text, names, UI elements, logos,
watermarks, health bars, full-body pose, scenery, or multiple characters.
```

| Asset           | Chroma key        | Faction prompt addition                                                                                                                                                                    |
| --------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Orc standee     | `#ff00ff` magenta | Orc warchief bust, heavy jaw, short tusks, scorched iron shoulder armor, crimson forge glow, brutal axe-emblem disk behind the head, broad readable silhouette.                            |
| Human standee   | `#00ff00` green   | Human paladin or commander bust, blue-gold plate armor, lion-crown shield emblem behind the head, upright heroic posture, bright but controlled rim light.                                 |
| Elf standee     | `#ff00ff` magenta | Elf moon sentinel bust, antlered or crescent headpiece, green-gold leaf armor, longbow or crescent motif behind the shoulders, elegant narrow silhouette with readable ears.               |
| Undead standee  | `#00ff00` green   | Undead lich or necromancer bust, bone crown, pale skull face, violet crypt glow, closed-book skull emblem behind the head, angular sinister silhouette.                                    |
| Lobster standee | `#00ff00` green   | Lobster tidecaller bust, expressive shell crown, two forward claws framing the torso, orange coral armor, quill-and-claw emblem disk behind the head, bold playful but premium silhouette. |

### Battlefield Asset Rules

* Generate one asset per prompt; do not request a sprite sheet for this set.
* Keep the background center darker and less noisy than the edges so DOM labels, state rings, and hero buttons remain readable.
* Use emblem-backed bust standees rather than full-body figures so silhouettes read at 44-64 px.
* Do not bake names, state labels, UI text, logos, watermarks, health bars, buttons, cursors, or click affordances into images.
* Use magenta chroma backgrounds for green-heavy subjects such as orc and elf. Use green chroma backgrounds for human, undead, and lobster.
* Reject standee candidates with gradients, scenery, cast shadows, texture, glow spill, or subject details that use the chosen chroma color near the silhouette edge.
* After background removal, validate transparent corners, inspect the alpha edge at 100 percent and at cockpit scale, and verify no obvious color fringe. The approved set used a local `sharp` pipeline with soft matte thresholds and despill logic after the bundled Pillow helper was unavailable.
* Store accepted references under `assets/battlefield-2d/reference/`, optimize runtime copies, then update both `apps/web/public/battlefield/` and `public-demo/assets/battlefield/`.
* When public demo runtime assets change, update `public-demo/sw.js`, run `npm run battlefield:check`, bump `CACHE_VERSION` when the precache list changes or a forced shell-cache refresh is needed, and verify offline reload after one online visit.

## EXAMPLES Audio Findings

Inspection on 2026-05-29 found legacy audio evidence in `EXAMPLES/`, but not a dedicated background music system. The legacy package mainly used short voice-line and notification MP3s.

### Source Evidence

| Source                                                           | Finding                                                                                                    |
| ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `EXAMPLES/package-0.4.1/frontend/dist/assets/speech/`            | Contains 19 legacy MP3 files, about 900 KB total.                                                          |
| `EXAMPLES/findings/asset-inventory.md`                           | Lists the same 19 files as quarantined historical asset inventory.                                         |
| `EXAMPLES/findings/architecture.md`                              | Describes `assets/speech/` as WC3-style voice barks triggered by repeated hero clicks.                     |
| `EXAMPLES/package-0.4.1/frontend/dist/assets/index-CuYaJ5lV.js`  | Minified historical bundle uses direct browser `new Audio(...)` calls and small audio pools.               |
| `EXAMPLES/package-0.4.1/plugin/skills/agentcraft-guide/SKILL.md` | User-facing guide says hero clicks play voice lines and repeated clicks trigger speech-bubble easter eggs. |

### Legacy Voice-Line Inventory

```
celebration.mp3, command.mp3, done.mp3, done_song.mp3, error.mp3,
had_something.mp3, hmm.mp3, hmm_long.mp3, huh.mp3, idle.mp3,
leave_me.mp3, prompt.mp3, prompt2.mp3, prompt_sing.mp3,
slop_complete.mp3, stop_prompting.mp3, warning.mp3, what.mp3, yes.mp3
```

### Inferred Legacy Behavior

* The old bundle used plain `new Audio(...)`; no Howler, WebAudio mixer, or dedicated music runtime was found.
* Audio was grouped by interaction: peon spawn, hero spawn, hero task prompt, awaiting input, mission done, hero selection, rare repeated-click selection, annoyed repeated-click response, alert sounds, and achievement celebration.
* Selection barks included `yes`, `what`, `hmm`, `hmm_long`, and `leave_me`; rare or escalating responses included `had_something` and `stop_prompting`.
* Speech-bubble text and durations were mapped separately from playback, so audio events could also show short RTS-style captions.
* `done_song.mp3` and `prompt_sing.mp3` are song-like barks in the speech directory, not evidence of a looped background music or playlist system.
* The bundle references `/assets/speech/ready.mp3`, but that file was not found in the scanned legacy speech directory. Treat it as an unresolved historical mismatch unless a future spec revalidates it.

### Current Product Direction

* Treat EXAMPLES audio as reference-only standards and gap evidence. Do not copy or transform those files into tracked runtime paths.
* Model voice lines, UI SFX, alerts, celebrations, and future music as separate catalog categories. A future music system should have its own briefs, rights record, loop/edit decisions, size budgets, lazy-loading behavior, and playback controls.
* Use generated, recorded, or rights-cleared replacements with explicit provenance, normalization, browser-format validation, metadata cleanup, and smoke tests.
* The current public demo uses separately supplied orc, human, elf, and undead voice-line clips under `public-demo/assets/speech/`; they are not promoted from `EXAMPLES/`.

## Quarantine Policy

`EXAMPLES/` is reference-only intake material. Do not import from it directly in runtime code, copy files from it into tracked paths, transform its files into product assets, use its files as direct generation inputs, or ship it as release content.

Reference inventory records may cite `EXAMPLES/` source paths for standards and gap analysis only. Each record should capture:

* Source path.
* File type, size, and dimensions or duration when applicable.
* Hash.
* Reference value or implementation gap.
* Provenance or ownership status.
* License and attribution requirement.
* Final disposition.

New product media should be owned or generated from written briefs derived from standards and current implementation gaps, not from direct `EXAMPLES/` files.

## Intake Scope

The retained media-intake plan covers source groups, not individual assets. Future media work should inventory these groups without copying files into tracked runtime paths:

| Source group                                                                  | Handling                                                                                                                      |
| ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `EXAMPLES/` legacy package media and build output                             | Keep ignored, quarantined, and reference-only. Inventory standards and gaps only; do not promote files directly.              |
| Legacy `characterModels.*` registries                                         | Treat as taxonomy or faction/model evidence only; registry entries do not prove asset provenance.                             |
| Historical frontend/PWA asset references and bundle manifests                 | Use as pointers for review, not as source assets. Bundled chunks are not product media.                                       |
| Tracked docs/showcase/public-demo images                                      | Review separately from quarantined legacy media because they are already committed assets.                                    |
| Future 2D, HUD, portrait, achievement, audio, music, and optional video media | Generate or create as owned assets, then promote through manifests or typed catalogs with smoke tests and bundle-size review. |

## Media Tooling Baseline

The repository pins the default open-source media tooling in npm where practical. Verify the local environment with:

```bash
npm run media:check
```

Use these defaults unless a later spec records a better project-specific choice:

* `sharp` for raster resize, crop, composition, alpha, WebP, AVIF encoding, and PNG work.
* FFmpeg and `ffprobe` for audio, music, video, loudness, trims, loops, probes, poster extraction, and browser-compatible transcodes.
* `svgo` for repo-native SVG optimization.
* `oxipng` for retained PNG reference optimization.
* ExifTool plus encoder-level stripping for metadata inspection and cleanup.
* ImageMagick (`magick` or ImageMagick 6 `convert`) plus `imagemagick-cli` for contact sheets, visual inspection, odd-format conversion, and diagnostics.
* Host `cwebp`/`dwebp` for WebP encoder fallback; avoid vulnerable WebP npm binary wrappers while host tools are available.
* `maxrects-packer` plus `sharp` for sprite atlas layout/composition if many small generated sprites make standalone files inefficient.
* `howler.js` for opt-in browser voice, SFX, or music playback when scoped.

## Promotion Decisions

Use these statuses in promotion records:

* `approved`
* `conditionally_promoted`
* `needs_attribution`
* `needs_replacement`
* `prototype_only`
* `rejected`
* `unknown`
* `planned`
* `deferred`

Unknown provenance, missing attribution, oversized raw assets, unclear license terms, or unsupported browser formats are release blockers until resolved or explicitly approved through a reviewed spec.

## Runtime Requirements

* Promoted media should be referenced through manifests or typed catalog modules.
* Browser-loadable image, audio, music, and optional video assets need smoke tests that verify paths exist and formats are supported.
* Heavy audio, music, video, and large image assets should be lazy-loaded and have fallbacks.
* Raw legacy media, old bundled chunks, unoptimized generated assets, oversized images, and unoptimized audio should not ship without a documented exception.

## Release Blockers

Do not release newly promoted media while any of these remain unknown:

* Ownership or source provenance.
* License terms and attribution text.
* Optimization status, dimensions or duration, browser support, and fallback.
* Runtime path, lazy-loading behavior, and size-budget impact.
* Whether the file is product media, prototype-only evidence, generated build output, or historical reference material.

## Current Known State

The current tracked media is limited and intentional. It includes approved showcase media, the generated 2D battlefield references and runtime copies listed above, and the separately supplied public-demo orc, human, elf, and undead click voice lines in `public-demo/assets/speech/`. The larger legacy inventory remains quarantined and is covered by this policy and the media requirements in `docs/PRD.md`.


---

# 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/docs/media/media-assets.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.
