# 11 — Class Colors (Detection Class Theme)

## 1. High-Level Overview

**Purpose**: The single source of fallback color, fallback name, and `PhotoMode` suffix for any detection class number — used whenever the live `DetectionClass[]` from the admin API is unavailable, partial, or being rendered next to UI chrome that cannot wait for it (initial paint, gradient stops, label tints, sidebar swatches).

**Architectural Pattern**: Pure-function shared kernel. Stateless, no React, no HTTP, no DOM.

**Layer**: shared / Layer 1 (above Foundation, below every UI component that names a detection class).

**Upstream dependencies**: none (no internal imports; no external libraries).

**Downstream consumers**:
- `03_shared-ui/DetectionClasses` (fallback name + color when admin classes haven't loaded)
- `06_annotations/CanvasEditor` (bbox label color + crosshair tint)
- `06_annotations/AnnotationsPage` (active-class indicator)
- `06_annotations/AnnotationsSidebar` (annotation-row gradient stops)
- `07_dataset/DatasetPage` (class-filter chip color, class-distribution chart) — when those features are wired up

## 2. Internal Interfaces

```ts
export const FALLBACK_CLASS_NAMES: string[];                       // 12 generic English labels
export function getClassColor(classNum: number): string;           // hex string, no '#'-alpha
export function getPhotoModeSuffix(classNum: number): string;      // '' | ' (winter)' | ' (night)'
export function getClassNameFallback(classNum: number): string;    // FALLBACK_CLASS_NAMES[base] or '#<n>'
```

A 12-color palette `CLASS_COLORS` is module-private and exposed only via `getClassColor`.

### PhotoMode contract (from legacy WPF)

`yoloId = classId + photoModeOffset`. Three offsets:

| `mode = floor(classNum / 20)` | Suffix | Meaning |
|------------------------------|--------|---------|
| 0 | (empty) | Regular |
| 1 | `' (winter)'` | Winter |
| 2 | `' (night)'` | Night |

`base = classNum % 20` is the index into both `CLASS_COLORS` and `FALLBACK_CLASS_NAMES`.

## 5. Implementation Details

```
base = classNum % 20
mode = floor(classNum / 20)
color = CLASS_COLORS[base % CLASS_COLORS.length]
name  = FALLBACK_CLASS_NAMES[base % FALLBACK_CLASS_NAMES.length] ?? `#${classNum}`
suffix = mode === 1 ? ' (winter)' : mode === 2 ? ' (night)' : ''
```

**Open question** (carried forward from `src__features__annotations__classColors.md`): the `??` guard is dead because `base % length` already brings the index back into range. Either the array is wrong (the legacy palette had >12 entries?) or the guard is dead code. Step 4 verification.

**Redundancy with `DetectionClass.photoMode`** (also in module doc): the live admin DTO carries an explicit `photoMode` field on `DetectionClass`. Computing the suffix from `classNum / 20` here risks disagreeing with the admin-defined value. Step 4 testability candidate: keep `getPhotoModeSuffix` only as a fallback when the admin DTO is missing.

**State Management**: stateless module. Calls are pure.

**Key Dependencies**: none.

## 6. Extensions and Helpers

This *is* the helper. There are no further extensions inside this component.

## 7. Caveats & Edge Cases

- **Physical location**: `src/class-colors/` (own component directory, with `src/class-colors/index.ts` barrel). Lifted from `src/features/annotations/classColors.ts` by AZ-511 (closes Finding F3 / Vision P3 sibling); historical placement note retained for git-archaeology readers.
- **Fallback names are generic English** ("Car", "Person", "Truck", …) and bear no relation to the actual military class taxonomy in `_docs/ui_design/README.md` §"Detection Classes Table". Acceptable only because they appear strictly when admin-loaded classes failed to load. Document in Step 5 (Solution Extraction).
- **No localization**. Suffix strings (`' (winter)'`, `' (night)'`) and fallback names are hardcoded English. Step 4 i18n.
- **Color palette size (12)** vs `base = 0..19` — the wrap-around silently reuses colors for indices 12..19. Visually distinct fallbacks above 12 are not guaranteed.

## 8. Dependency Graph

**Must be implemented after**: nothing (no internal deps).

**Can be implemented in parallel with**: `00_foundation`, `01_api-transport`.

**Blocks**: `03_shared-ui` (DetectionClasses), `06_annotations`, `07_dataset` (when class-distribution chart is added).

## Module Inventory

| Path | Module Doc |
|------|------------|
| `src/class-colors/classColors.ts` | `_docs/02_document/modules/src__class-colors__classColors.md` |
| `src/class-colors/index.ts` | barrel — re-exports `getClassColor`, `getClassNameFallback`, `getPhotoModeSuffix`, `FALLBACK_CLASS_NAMES` |
