# RC109 · Stable image asset path cleanup QA

## Purpose

RC109 is a targeted cleanup release on top of RC108. The goal is to remove remaining active references to versioned image folders and keep assets in stable, semantic locations.

No new exercise images were generated. Image generation remains paused. No foreground/background cutout workflow was reactivated.

## Reference implementation carried forward

Read before change:

- `docs/ARCHITECTURE_DECISIONS.md`
- `docs/DO_NOT_TOUCH_WITHOUT_DESIGN.md`
- `docs/RC104_DIRECT_COMPOSITE_CLEANUP_NOTES.md`
- `docs/RC107_EXERCISE_LIBRARY_ASSET_CLEANUP.md`
- `docs/RC108_EXERCISE_LIBRARY_REAL_DOM_QA.md`

Carried forward unchanged:

- Existing static `preview.html` shell and script order.
- Existing exercise library path:
  - `assets/js/services/exercise-library-service.js`
  - `assets/js/actions/library-actions.js`
  - `assets/js/renderers/library-renderer.js`
- Existing illustration path:
  - `assets/js/core/exercise-illustrations.js`
  - `assets/js/services/exercise-illustration-service.js`
- Existing theme path:
  - `assets/js/services/theme-service.js`
- Existing server/local backup services.

No new renderer, fallback SVG system, background model, or player subsystem was introduced.

## Asset path changes

### Removed obsolete active version folders

These image folders were removed from the active package after their files were copied to stable locations:

- `assets/img/v93/`
- `assets/img/v95/`
- `assets/img/v96/`

Old archived version-folder copies were also removed because the active assets now exist in stable folders:

- old archived RC98 exercise backgrounds
- old archived RC99 generated fallback copies

### Stable target structure now used

| Asset type | Stable active path |
|---|---|
| Dashboard/profile/library hero images | `assets/img/hero/` |
| UI icons | `assets/img/icons/` |
| Rest/pause imagery | `assets/img/rest/` |
| Stage/program imagery | `assets/img/program/` |
| Calendar background | `assets/img/calendar/` |
| Exercise theme backgrounds | `assets/img/themes/exercise-backgrounds/` |
| S2P1 premium direct composites | `assets/img/exercises/premium/s2p1/` |
| Generated fallback exercise SVGs | `assets/img/exercises/fallback/svg/` |

## Code paths updated

Runtime references were updated in:

- `preview.html`
- `assets/css/next-system.css`
- `assets/css/app-legacy-rc74-full.css` reference CSS
- `assets/js/app.js`
- `assets/js/core/exercise-illustrations.js` version/comment marker only; direct-composite mapping remains unchanged
- `assets/js/services/theme-service.js` version/comment marker only; stable theme background path remains unchanged
- `assets/js/services/exercise-illustration-service.js` version/comment marker only; renderer logic remains unchanged

## Key implementation confirmation

Premium S2P1 images still use direct composite:

```text
exerciseKey → assets/img/exercises/premium/s2p1/<exerciseKey>.webp
```

The expanded Bear Crawl/Björngång card still reports:

```text
data-quality="premium-approved"
data-background-mode="composite"
data-theme="hockey"
imageOriginalSrc: assets/img/exercises/premium/s2p1/bear-crawl.webp
```

The paused cutout/layered foreground-background model remains inactive for S2P1 premium images.

Theme backgrounds remain in:

```text
assets/img/themes/exercise-backgrounds/
```

## Browser/DOM QA method

As in RC108, direct browser navigation to local `file://` and local `http://127.0.0.1` is unreliable/blocked in this sandbox.

RC109 real-DOM QA uses Chromium + Playwright with `page.set_content()` after inlining the actual `preview.html`, CSS and scripts. This exercises the real `window.NEXTRenderers.library.renderDetail()` output and real CSS cascade.

For screenshots only, local images are converted to data URIs after render so screenshots can show the actual assets. DOM metrics still record the production source paths.

## Screenshots created

- `qa_screenshots/rc109_library_expanded_mobile_390x844.png`
- `qa_screenshots/rc109_library_expanded_ipad_820x1180.png`
- `qa_screenshots/rc109_library_expanded_desktop_1440x1024.png`

DOM metrics:

- `qa_screenshots/rc109_library_expanded_dom_metrics.json`

QA script:

- `tests/rc109_library_real_dom_qa.py`

## Automated checks run

```bash
node tests/rc109_asset_path_cleanup_smoke.js
node tests/rc107_asset_and_library_smoke.js
node tests/rc109_library_compactness_static_smoke.js
node tests/rc104_direct_composite_smoke.js
node tests/rc106_smoke.js assets/js/core/exercise-illustrations.js "$PWD"
for t in tests/*.js; do ...; done
for t in tests/*.sh; do bash "$t"; done
find assets/js -name '*.js' -print0 | xargs -0 -n1 node --check
php -l ota_youtube_proxy.php
php -l video_backup_api.php
python3 tests/rc109_library_real_dom_qa.py
```

Result: checks passed.

## Explicit non-changes

- No new exercise images.
- No image generation.
- No cutout workflow reactivated.
- No new foreground/background model.
- No new SVG fallback system.
- No new renderer.
- No pass player/video lifecycle changes.
- No change to RC108 expanded-card layout ownership.
