# RC119 · Legacy cleanup / v97 handoff QA

## Purpose

RC119 is a closeout cleanup for the v96 branch before moving to a v97 base. The goal is not new product behavior; it is to remove active version-spaghetti from runtime paths and make the standardized app shell easier to carry forward.

## Source base

- Base package: `next_v96_rc118_pass_settings_menu_modernization.zip`
- RC118 behavior retained:
  - modern grouped pass settings menu
  - verified TV mode and Live mode state hooks
  - pass player lifecycle remains owned by `assets/js/app.js`
  - pass list auto-scroll and JS-driven progress fill remain intact
  - S2P1 premium exercise images remain direct-composites

## Changes made

### Active runtime cleanup

- Removed versioned active cache-busters from `preview.html`.
- Replaced old runtime query strings such as `?v=96rc118` with `?cache=standard`.
- Updated the active page title to `NEXT Athlete OS · Standardiserad appbas`.
- Removed the reference-only legacy CSS archive from the deploy payload:
  - removed `assets/css/app-legacy-rc74-full.css`
- Removed active old class tokens from runtime/CSS, including:
  - `rc18-*` dashboard classes
  - `v9540-*` onboarding classes
  - `start-stage-v9528`
  - `rest-stage-v9510`
  - old versioned CSS/comment markers in the active system CSS

### Standardized names

- Dashboard active classes now use `next-dashboard-*` naming.
- Start/rest stage renderer output now uses `next-pass-start-stage` and `next-pass-rest-stage` without versioned compatibility classnames.
- Active CSS selectors were updated to match the standardized class names.

### Settings renderer extraction

- Added `assets/js/renderers/settings-renderer.js`.
- `renderControls()` in `app.js` now calls:
  - `window.NEXTRenderers.settings.syncMenu(...)`
- `app.js` still owns state, actions and player lifecycle.
- The settings renderer owns the grouped menu/toggle presentation.

### Guard test

Added:

- `tests/rc119_legacy_cleanup_smoke.js`

This test fails if active runtime files reintroduce old active tokens such as:

- `?v=96rc...`
- `rc18`
- `v9540`
- `start-stage-v...`
- `rest-stage-v...`
- `ov47` / `ov51`

The test intentionally scans active runtime files only. Historical QA documents, release notes and test names are allowed to preserve project history.

## Intentionally retained compatibility

Some persisted browser/local database keys remain compatible with prior installs. Where needed they are handled as internal compatibility strings, not active UI/class/path contracts.

Examples:

- profile settings storage
- old exercise illustration theme storage
- local/server video backup storage

These should not be renamed blindly because it can orphan user data or local video backups.

## QA performed

### Static/smoke

```bash
find assets/js -name '*.js' -print0 | xargs -0 -n1 node --check
for t in tests/*.js; do node "$t"; done
for t in tests/*.sh; do bash "$t"; done
php -l ota_youtube_proxy.php
php -l video_backup_api.php
node tests/rc119_legacy_cleanup_smoke.js
```

### Real-DOM QA

```bash
python3 tests/rc119_legacy_cleanup_real_dom_qa.py
```

Method:

- renders actual `preview.html`
- inlines real CSS and JS
- uses Playwright `page.set_content()`
- mocks OTA/video backup network calls
- verifies grouped settings menu
- verifies TV mode has visible layout effect
- verifies Live mode has visible chrome effect
- verifies no broken local images in the tested views

## Screenshots

- `qa_screenshots/rc119_settings_menu_mobile_390x844.png`
- `qa_screenshots/rc119_settings_menu_ipad_820x1180.png`
- `qa_screenshots/rc119_settings_menu_desktop_1440x1024.png`
- `qa_screenshots/rc119_tv_mode_desktop_1440x1024.png`
- `qa_screenshots/rc119_live_mode_desktop_1440x1024.png`

## Real-DOM metrics

- `qa_screenshots/rc119_legacy_cleanup_dom_metrics.json`

## Result

Passed.

RC119 is suitable as a v96 closeout / v97 handoff candidate, pending real deploy/device testing.

## Caveat

The actual deployed host was not tested from this sandbox. Real-DOM QA used the same working local method as RC108–RC118: actual `preview.html`, actual CSS and actual JS via `page.set_content()`.
