# Settings Master-Detail Pattern — 2026-05-28

## Source
Adapted from NuvioTV 0.6.21 at `/home/rurouni/NuvioTV-0.6.21-beta/`.

## Pattern: Single composable, left rail + right content

NuvioTV's `SettingsScreen` uses a **master-detail pattern**:
- Left: `LazyColumn` of `SettingsRailButton` items (280dp wide)
- Right: `Box(weight(1f))` content area — switches via `when(selectedCategory)`

**All settings render INLINE in the right panel.** No separate navigation pushes.
Only external auth flows (Trakt OAuth, Account) use `navController.navigate()`.

## UNSPOOLED Implementation

### SettingsCategory Enum
17 categories: DASHBOARD, THEME, DEBRID, TRAKT, PLAYBACK, SOURCE_PREFS, ADDONS,
SUBTITLES, PROFILES, CATALOG_ORDER, TMDB, NETWORK, APPEARANCE, SKIP_INTRO,
DEBUG, LICENSES, ABOUT.

### Rail Navigation
```kotlin
railItems.forEachIndexed { index, item ->
    Row(
        modifier = Modifier
            .clip(RoundedCornerShape(10.dp))
            .background(if (isSelected) accent.copy(alpha = 0.18f) else ...)
            .border(if (isSelected || focused) 2.dp else 0.dp, ...)
            .onPreviewKeyEvent { ... }  // D-pad Center → select
            .focusable()
    ) { Text(item.icon); Text(item.label) }
}
```

### Inline Content Panels
Each panel is a `@Composable private fun` that renders directly:
- `SettingsThemePanel()` — theme color picker with focus-aware rows
- `SettingsDebridPanel()` — provider cards with status indicators
- `SettingsTraktPanel()` — connect/disconnect/retry state machine
- `SettingsPlaybackPanel()` — toggle rows
- `SettingsSourcePrefsPanel()` — toggle rows
- `SettingToggleRow(label, initialValue)` — reusable ON/OFF toggle with D-pad support

### Focus Management
- Rail items use `onFocusChanged` + `focusable()`
- Content panels use same pattern per element
- D-pad Right from rail → content; D-pad Left from content → rail
- No separate `FocusRequester` maps (simpler than NuvioTV's approach)

### Key Pitfall
The old NexStream SettingsScreen had 19 separate `composable()` routes in `NexStreamNavHost`.
Each opened as a full-screen push, losing the settings rail context.
The rewrite collapses all of them into ONE composable.
