# 2026-06-16 UI/Focus/Stability/Perf Audit

## Session scope
Full audit of Unspooled Android TV Compose front-end across 21 modified files.

## Batch 1 — Focus/Navigation (completed, compiled)
- **SeeAllScreen.kt**: Grid-aware FocusLinks with `gridColumns=5`, stable keyed requesters via `mutableMapOf<String, FocusRequester>`
- **AddonsScreen.kt**: Top action row (Add URL ↔ Configure Phone), addon list rows with up/down/left/right, dialog focus restore
- **CatalogManagerScreen.kt**: Header buttons, tab strip, catalog rows, reset dialog with Cancel↔Reset focus trap
- **DetailsScreen.kt**: "More Like This" row — replaced empty `FocusLinks()` with stable card requesters and horizontal links
- **LibraryHubScreen.kt**: 6 hub cards with stable requesters, left/right focus links between cards
- **PersonDetailScreen.kt**: `PersonCreditCard` converted from bare `focusable()` to `Surface` with focus links; hash-based nav fixed to use actual TMDB ID
- **WatchedScreen.kt**: Grid focus links, raw string nav → `Screen.Details.createRoute()`
- **HistoryScreen.kt**: Raw string nav → `Screen.Details.createRoute()`
- **WatchlistScreen.kt**: Raw string nav → `Screen.Details.createRoute()`

## Batch 2 — UI Consistency (completed, compiled)
- **LibraryHubScreen.kt**: Disabled cards labeled "Coming soon" instead of "scaffold"
- **PersonDetailScreen.kt**: `PersonCreditCard` uses `Surface` with focus border instead of bare `focusable()`
- **WatchedScreen.kt**: "✕ Remove" in focus overlay converted to clickable `Surface` button
- **SettingsDesignSystem.kt** (ui/components): `SettingsGroupCard` replaced `Card(onClick={})` with non-clickable `Column` + manual border/clip
- **SettingsDesignSystem.kt** (ui/screens): `SettingsContentActionRow` gained `enabled` parameter for disabled rows
- **SettingsScreen.kt**: About screen rows (Version, Package, Memory, OS, Device) marked `enabled = false`
- **DebridServicesScreen.kt**: Non-connected `DebridProviderCard` made `focusable()` so focus can enter card area

## Batch 3 — Stability (partially completed, compilation blocker)
- **CatalogGridHost.kt**: `checkNotNull` replaced with null-check + early return (prevents crash if row ID missing)
- **AddonUrlInput.kt**: 3 empty `onClick = {}` on `Surface` → `enabled = false`
- **DashboardEditor.kt**: Empty `onClick = {}` → `enabled = false`
- **SettingsDesignSystem.kt** (ui/components): Empty `onClick = {}` → replaced `Card` with `Column`
- **TmdbKnownFor**: Added `id: Int = 0` field + wired from `TmdbKnownForItem.id`
- **PersonDetailScreen.kt**: Added `BorderStroke` import from `androidx.compose.foundation`
- **WatchedScreen.kt**: `TextButton` → `Surface` (avoided `androidx.tv.material3.TextButton` shadowed by local function)
- **BLOCKER**: `SettingsDesignSystem.kt` (ui/components) `border()` extension unresolved — needs `androidx.compose.foundation.border` import. Patch applied but not yet compiled.

## Batch 4 — Performance (not started)
- Not yet audited for recomposition, image loading, overdraw, animations

## Lint (not started)
- Pre-existing: 76 errors, 2488 warnings, 7 hints
- First error: `MissingTvBanner` in `AndroidManifest.xml:11`
- Second: `enterPictureInPictureMode` API 26 on minSdk 24

## Key patterns discovered
- `androidx.tv.material3.Card` has NO `enabled` parameter — use `Column`/`Box` replacement for non-clickable containers
- `androidx.tv.material3.Surface` DOES have `enabled` parameter
- `BorderStroke` is in `androidx.compose.foundation`, NOT `androidx.tv.material3`
- `TextButton`/`TextButtonDefaults` may be shadowed by local functions — use `Surface` as fallback
- `SettingsSecondaryCardRadius` is defined in `ui/screens/settings/SettingsDesignSystem.kt`, NOT in `ui/components/SettingsDesignSystem.kt`
