# RC118 · Pass settings menu modernization QA

## Scope

RC118 builds directly on RC117 after real-device/menu feedback.

The user asked to verify whether TV and Live modes still actually work and to rebuild the pass settings menu into a modern theme-aligned menu with clear on/off controls.

No video/timer/wake-lock/player lifecycle, source priority, image/cutout model, or pass-list progress model was refactored.

## Findings before change

- `toggleTvMode()` existed and persisted `state.tvMode`.
- `renderControls()` toggled `body.tv-mode` and hid the playlist through `effectivePlaylistVisible = playlistVisible && !tvMode`.
- `toggleLiveMode()` existed and persisted `state.liveMode`.
- `renderControls()` toggled `body.live-mode`.
- In the currently loaded centralized stylesheet (`assets/css/next-system.css`) there were no meaningful TV/Live visual rules. Old TV/Live comments and styling existed in legacy CSS, but that is not the active styling owner.

Conclusion:

- TV mode was partly functional because JS hid the pass list, but the mode had weak/no modern visual styling in the active CSS layer.
- Live mode was mostly a state/body-class hook with no meaningful active visual effect in the current CSS.

## Changes

### Modern grouped settings menu

The static menu markup in `preview.html` was rebuilt around the existing IDs and handlers:

- `tvModeBtn` → `toggleTvMode()`
- `liveModeBtn` → `toggleLiveMode()`
- `playlistToggleBtn` → `togglePlaylist()`
- `restToggleBtn` → `toggleRest()`
- `autoNextToggleBtn` → `toggleAutoNext()`
- `autoplayToggleBtn` → `toggleAutoplay()`
- `projectorNoYoutubeBtn` → `toggleProjectorNoYoutube()`
- `soundToggleBtn` → `toggleSound()`
- `fullscreenToggleBtn` → `toggleFullscreen()`
- `exitWorkout()` remains on the destructive session action.

Groups:

- Visning
- Passflöde
- Film & ljud
- Pass

### Toggle renderer

`renderControls()` now writes consistent toggle markup for settings buttons:

- `.next-settings-toggle-copy`
- `.next-settings-toggle-title`
- `.next-toggle-pill`
- `.next-toggle-segment`
- `data-state="on|off"`
- `aria-checked="true|false"`

The state is no longer concatenated into labels such as `TVAv` or `ListaPå`. Labels stay stable and the Av/På state is shown inside the segmented control.

### TV mode visual effect restored in centralized CSS

New `next-system.css` rules make TV mode visibly meaningful:

- `body.exercise-active.tv-mode .next-pass-playlist-card` is hidden.
- Desktop layout becomes more media-heavy:
  `grid-template-columns:minmax(0,1.42fr) minmax(320px,.58fr)`
- Info card is visually softened/secondary.

### Live mode visual effect restored in centralized CSS

New `next-system.css` rules make Live mode visibly meaningful:

- Topbar padding is reduced.
- Topbar chrome becomes more transparent.
- Progress/card shadows are reduced.
- Desktop pass-list max-height is tightened.

## Reused code paths / classes

RC118 continues to reuse:

- `preview.html` pass player structure.
- Existing button IDs and click handlers.
- `assets/js/app.js` state and `renderControls()` ownership.
- `assets/js/renderers/pass-player-renderer.js` pass-list and pass-player helpers.
- `assets/css/next-system.css` as visual owner.
- RC117 JS-driven pass-list progress fill.
- Existing player lifecycle: `startWorkout`, `renderStep`, `renderVideo`, `renderRest`, timers, preload and wake lock.

## Real-DOM QA

Real-DOM QA was run with actual `preview.html`, actual CSS and actual JS via Playwright `page.set_content()`. External network/iframe requests were blocked/mocked as in RC108–RC117 QA.

Generated screenshots:

- `qa_screenshots/rc118_settings_menu_mobile_390x844.png`
- `qa_screenshots/rc118_settings_menu_desktop_1440x1024.png`
- `qa_screenshots/rc118_tv_mode_desktop_1440x1024.png`
- `qa_screenshots/rc118_live_mode_desktop_1440x1024.png`

Metrics file:

- `qa_screenshots/rc118_pass_settings_menu_dom_metrics.json`

Verified:

- Menu opens visibly on mobile and desktop.
- Menu has grouped sections: `view`, `flow`, `media`, `session`.
- Toggle buttons have modern toggle pills.
- Legacy concatenated labels are absent.
- TV mode sets `state.tvMode`, `body.tv-mode`, hides playlist and prioritizes the media column.
- Live mode sets `state.liveMode`, `body.live-mode` and applies compact topbar CSS.
- No broken local images.

## Commands run

```bash
node tests/rc118_pass_settings_menu_smoke.js
python3 tests/rc118_pass_settings_menu_real_dom_qa.py
node tests/rc117_iphone_safe_pass_list_progress_smoke.js
node tests/rc116_pass_list_progress_smoke.js
node tests/rc115_pass_player_scale_smoke.js
find assets/js -name '*.js' -print0 | xargs -0 -n1 node --check
php -l ota_youtube_proxy.php
php -l video_backup_api.php
unzip -t next_v96_rc118_pass_settings_menu_modernization.zip
```

## Caveat

The actual deployed host and real iPhone Safari runtime were not testable from this sandbox. The changes are verified through the same real-DOM QA path used in RC108–RC117 and should be confirmed on the real deployed host/device.
