# God-Tier Cinematic Systems (Phase 0–4)

Built for Unspooled Android TV — June 2026. These systems form the "cinematic engine" layer above the base focus architecture.

## Phase 0: Cinematic Engine

### Spatial UI Audio (SoundPoolManager)
- **File:** `ui/audio/SoundPoolManager.kt` (440 lines)
- **Pattern:** Hilt `@Singleton` with procedural tone synthesis via `AudioTrack` PCM-16
- **No .ogg assets needed** — all sounds generated on first play
- **10 sound events:** FOCUS_ENTER (1kHz click), FOCUS_CHANGE (2kHz directional tick), SELECTION_CONFIRM (C5→E5), SIDEBAR_OPEN (rising whoosh), SIDEBAR_CLOSE (falling whoosh), ERROR (80Hz bump), SUCCESS (ascending chime), DIALOG_OPEN, DIALOG_CLOSE, TRAILER_MUTE_TOGGLE
- **Spatial toggle:** `setSpatialAudioEnabled()` applies stereo panning (±1.0) for directional focus
- **Volume:** 25% system volume, `USAGE_ASSISTANCE_SONIFICATION`
- **Lifecycle:** `release()` in `Activity.onStop()`, `reinitialize()` in `onStart()`
- **Hook:** Wire to `InteractionSource.collectIsFocusedAsState()` — never click events

### Multi-Layer Parallax (Apple TV+ Pattern)
- **File:** `ui/components/ParallaxSystem.kt` (117 lines)
- **ParallaxState:** `@Stable data class` with `layerTranslationY(speedFactor)` = `scrollOffset * speedFactor`
- **Tracking:** `snapshotFlow` on `LazyListState.layoutInfo.viewportStartOffset` for frame-accurate updates
- **Modifier.parallaxLayer(speedFactor):** `graphicsLayer { translationY = state.layerTranslationY(speedFactor) }`
- **Layer speeds:** Hero backdrop 0.5x (depth), Cards 1.0x (normal), Sidebar 0.0x (fixed)
- **Usage in Home:** `PremiumHeroSection(modifier = Modifier.parallaxLayer(parallaxState, 0.5f))` inside LazyColumn item

### Adaptive Halo (GPU-Optimized Focus Glow)
- **File:** `ui/cards/AdaptiveHalo.kt` 
- **Pattern:** `Modifier.drawWithCache` + `drawRoundRect(blendMode = BlendMode.Screen)` — NOT border/shadow
- **Shader:** `RadialGradientShader(center = Offset(size.width/2, size.height/2))` with cached `ShaderBrush`
- **Stops:** transparent center → soft peak (55%) → bright ring (80%) → transparent (100%)
- **Glow radius:** 40dp focused, 0dp unfocused — animated via `animateFloatAsState` (200ms tween)
- **Color:** Palette API dominant color from poster → `glowColor` parameter
- **Cost:** ~10× cheaper GPU than `Modifier.shadow()` on cheap TV boxes
- **Early bail:** skip draw when `alpha <= 0.01f` or `radiusDp <= 0.5f`

## Phase 2: Living Card System

### Directional Expansion (Zero Layout Shift)
- **File:** `ui/cards/DirectionalExpansion.kt` (379 lines)
- **Core trick:** `Modifier.layout` measures content at expanded size (260×148) but reports RESTING size (126×189) to parent — neighbors never move
- **Edge-aware:** Left edge → peeks right, right edge → peeks left, middle → centered, bottom → peeks up
- **Animation:** `Animatable<Float>` with `SpringSpec(dampingRatio=0.55, stiffness=400)` via `graphicsLayer` — no relayout passes
- **TransformOrigin:** Matched to card edge — left cards anchor (0, 0.5), right cards (1, 0.5), middle (0.5, 0.5)
- **Clip:** Disabled during expansion (`clip = false` when expanded or animating)

### Settled Focus Detector (Velocity-Aware)
- **File:** `ui/focus/SettledFocusDetector.kt`
- **Pattern:** `rememberSettledFocusState(velocityTracker)` returns `State<Boolean>`
- **Gate:** Returns `true` only after 1200ms of zero D-pad velocity
- **Mechanism:** `snapshotFlow { velocityTracker.dpadEventVersion }.collectLatest { ... delay(1200ms); settled = true }` — `collectLatest` cancels delay on any new event
- **FocusVelocityTracker updated:** Exposes `dpadEventVersion: State<Long>` — monotonically increasing

## Phase 3: Videophile Settings Hub

- **Files:** `ui/settings/PremiumSettingsHub.kt` (788 lines) + `PremiumSettingsCategory.kt` (435 lines)
- **Layout:** Asymmetric split-pane — left 30% (categories), right 70% (settings)
- **8 categories:** Account, Profiles, Playback, Subtitles & Audio, Parental Controls, Accessibility, Appearance, About
- **5 setting types:** Toggle (ON/OFF pill), Selector (option chips), Slider (L/R dpad), Action (button), Info (readonly)
- **Live Preview Panel:** Appearance shows simulated poster card; Playback shows seek bar with timecodes
- **Focus:** LEFT/RIGHT between panes via `focusProperties`, BACK exits via `BackHandler`
- **Persistence:** All settings emit via `onSettingChanged(categoryKey, settingKey, newValue)` → wire to DataStore

## Phase 4: MVI + Aggressive Prefetching

### MVI (Model-View-Intent)
- **HomeIntent:** 8 intent types — LoadHome, HeroIndexChanged, SetSourceFilter, SeeAll, RetryRow, RemoveFromContinueWatching, ScrollPositionChanged, FocusSettled
- **HomeEffect:** 5 effect types — NavigateToDetail, NavigateToPlayer, NavigateToScreen, ShowError
- **ViewModel:** `onIntent(intent)` dispatcher + `effect: Flow<HomeEffect>` via `Channel`
- **Screen:** `LaunchedEffect` collects effects, replaces direct ViewModel calls with `onIntent()`

### Aggressive Prefetching
- **Trigger:** `HomeIntent.FocusSettled(rowIndex, cardIndex)` — fires when D-pad stops on a row
- **Action:** Preloads poster + background for first 10 items of Row N+1 and N+2 via `ImageLoader.enqueue()`
- **Hero:** Preloads next hero item while current is displayed
- **Dedup:** `ConcurrentHashMap` avoids re-preloading same URLs

## God-Tier Validation Checklist

- [ ] **Mash Test:** Rapid D-pad mashing never escapes intended container
- [ ] **Silence Test:** UI audio perfectly synced with focus, zero latency
- [ ] **Parallax Test:** Vertical scroll creates 3D depth between layers
- [ ] **Zero-Shift Test:** Card expansion doesn't move neighboring cards
- [ ] **Videophile Test:** HDMI-CEC + Frame-Rate matching APIs wired
- [ ] **Memory Test:** 5000 posters scrolled without OOM
- [ ] **Return Test:** 5 screens deep, BACK 5 times → exact pixel scroll + focused card restored
