# Android TV Compose UI Audit Methodology

## Four-Area Audit Framework

When auditing an Android TV Compose app, evaluate every screen/component across four orthogonal dimensions. Each area has distinct signals, tools, and fix patterns.

### 1. DPAD / Focus Navigation
- Initial focus on every screen
- All four directions wired via `focusProperties` (not just left/right)
- No nullable FocusRequester escapes (use `FocusRequester.Cancel`)
- No focus traps (Cancel at real edges only)
- Focus restoration when returning from sub-screens
- `focusGroup()` + `focusRestorer()` on every LazyRow/LazyColumn
- `onKeyEvent` returns `true` when overlay/controls are visible
- No `FocusRequester.Default` — always Cancel at boundaries
- Sidebar → content entry: `entryFocusRequesterMap` per route, not hardcoded

### 2. UI/UX Consistency
- Colors match token system (no hardcoded hex outside tokens)
- Spacing uses token values (no 80.dp, 24.dp hardcoded)
- Sidebar accent bar drawn behind icon (not on top)
- BackButton padding uses safe area + tokens
- Every section has loading/error/empty states
- No TODO stubs or dead buttons
- Text uses theme typography, not raw `fontSize`

### 3. Stability
- `rememberSaveable` for position/selection state (not `remember`)
- Saver.restore uses safe casts (`as?` with defaults, not raw `as`)
- No `requestFocus()` in LaunchedEffect without `requestFocusAfterFrames()`
- `BackHandler` dismisses dialogs/panels before navigating away
- `DisposableEffect` for cleanup (player release, observer removal)

### 4. Performance
- `RecompositionTracker` at screen level only (not card/row level)
- Card focus animations: `tween(200ms)` not `spring()` (avoids relayout)
- Isolate overlay state from content state (avoid Crossfade on full state)
- `remember()` keys match actual dependencies (don't widen scope unnecessarily)
- Avoid `MutableMap` casts to `Map` — use concrete `MutableMap` type
