# Active vs Focused — Two Simultaneous Visual States

## Problem

A D-pad-focusable element can also be in a "selected" or "active" state. These are two independent axes and can occur simultaneously on the same element. The user must be able to answer two questions at a glance: "Which category's content am I viewing?" AND "Where is my D-pad cursor?"

Settings rail, filter chips, tabs, and profile type toggles all have this dual-state requirement.

## Visual Specification

| State | Left border | Outline | Background | Text color |
|-------|-------------|---------|------------|------------|
| Default (neither) | — | — | Transparent | `TextSecondary` |
| Active (selected) | 4dp `Accent` | — | `Accent @ 16%` | `TextPrimary` (white) |
| Focused (D-pad) | — | 3dp `FocusRing` | `FocusBackground` | `TextPrimary` |
| Active + Focused | 4dp `Accent` | 3dp `FocusRing` | `FocusBackground` | `TextPrimary` |

## Implementation Pattern

### Container: tv.material3.Surface + ClickableSurfaceDefaults

```kotlin
Surface(
    onClick = onClick,
    colors = ClickableSurfaceDefaults.colors(
        containerColor = if (isSelected) NuvioTheme.colors.Accent.copy(alpha = 0.16f) else Color.Transparent,
        focusedContainerColor = NuvioTheme.colors.FocusBackground,
        pressedContainerColor = NuvioTheme.colors.FocusBackground.copy(alpha = 0.4f),
    ),
    scale = ClickableSurfaceDefaults.scale(focusedScale = 1.03f),
    border = ClickableSurfaceDefaults.border(
        focusedBorder = Border(
            border = BorderStroke(3.dp, NuvioTheme.colors.FocusRing),
            shape = RoundedCornerShape(cornerRadius),
        ),
    ),
)
```

### Left accent stripe (active indicator)

Rendered INSIDE the Surface content as a 4dp-wide Box with accent background. When the element is also focused, the FocusRing outline from ClickableSurfaceDefaults renders around the entire Surface — the left stripe sits inside it.

```kotlin
Box(modifier = Modifier.fillMaxWidth()) {
    if (isSelected) {
        Box(
            modifier = Modifier
                .width(4.dp)
                .fillMaxHeight()
                .background(
                    NuvioTheme.colors.Accent,
                    RoundedCornerShape(topStart = 18.dp, bottomStart = 18.dp),
                ),
        )
    }
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(start = if (isSelected) 20.dp else 16.dp, ...)
    ) {
        // icon + text + chevron
    }
}
```

### Key gotchas

1. `ClickableSurfaceDefaults.focusedContainerColor` REPLACES `containerColor` when focused — the selected accent tint is lost on focus. Intentional: focus ring and FocusBackground dominate when actively navigating.

2. Surface scale animates smoothly via `ClickableSurfaceDefaults.scale`. Inner content (including stripe) scales with it.

3. Do NOT use `Modifier.clickable` or `Modifier.focusable` — Surface handles both.

4. Active state must survive focus loss — `isSelected` is a separate boolean, not tied to D-pad focus. `containerColor` retains accent tint when item loses focus but remains selected.

## Reference implementation

`GlassSettingsRailItem.kt` (127 lines, ~/Unspooled/app/src/main/java/com/unspooled/app/ui/components/glass/)
Applied 2026-06-03 for SET-07 focus audit fix.
