> For the complete documentation index, see [llms.txt](https://docs.kouch.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kouch.dev/docs/adr/0003-oled-single-accent-design.md).

# ADR 0003: OLED-first, single-accent design system

## Status

Accepted (2026-09-17 — see `docs/ARCHITECTURE.md` "Decisions locked in with the user" and `docs/DESIGN.md` §1–2).

## Context

Kouch's UI has to read clearly on two very different displays at once: a 7" handheld screen held close, and a TV viewed from roughly 3 meters — while also fitting a "10-foot" controller-first navigation model (paged tile grid, one focused element per player, glyph-and-label prompts) rather than a mouse-first desktop app. It also needs to support Workshop-authored themes later without themes being able to silently break contrast, accessibility, or the controller-first navigation model. A conventional UI approach of many accent colors, drop shadows, and gradients would be expensive to keep consistent across two vastly different theme instances, would sit poorly on OLED handheld panels, and would be hard for a solo developer plus friends (not a design team) to keep visually coherent as new screens are added.

## Decision

The design system (`docs/DESIGN.md`) commits to: a true `#000000` background (real black, best on OLED — no glow/low-alpha gradients that would just look like dark grey), near-black surfaces distinguished only by stepped white opacity plus hairline borders, white text at a small fixed set of opacity steps, and **exactly one** accent color (`--k-accent`) used for focus/selection/emphasis, plus one exception color (`--k-danger`) for destructive actions only. All colors are tokens in `app/ui/src/theme/tokens.css`; nothing else may declare a raw color (enforced by `design-lint.mjs`). The accent itself is not hardcoded: Rust resolves it from a priority chain (user override → active theme → OS accent color → a default pastel purple), validated by a contrast/ saturation gate before injection, so it is always readable on black no matter its source. Themes (`docs/DESIGN.md` §10) may only set an allowlisted subset of tokens (`docs/theme-token-allowlist.json`) plus images and sounds — never arbitrary CSS, selectors, or scripts. Motion is transform/opacity only, everything is navigable by d-pad alone, and the 18-item checklist in `docs/DESIGN.md` §12 is the required self-review for every UI change (there is no PR gate, since commits go straight to `main`, so this checklist plus CI lint is the enforcement mechanism).

## Consequences

* Any new color, shadow, gradient, or non-transform/opacity animation is a lint failure (`npm run design-lint`), not just a style guide violation — the rule is mechanically enforced, matching CLAUDE.md ground rule 5 ("design system is enforced, not advisory").
* A Workshop theme can never break accessibility or introduce arbitrary styling, because it can only touch allowlisted tokens, images, and sounds — the allowlist file is the actual security/consistency boundary, not just documentation.
* Because there is one accent and a fixed player-color palette (separate from the accent, per `docs/DESIGN.md` §2), status must always be conveyed by more than color alone (glyph, text, slot number) — this is a direct accessibility consequence (§9) of committing to so few colors.
* Every screen must work at three reference resolutions (1280×800, 1920×1080, 3840×2160) and 150% text scale; this is checked manually (screenshots) since there is no automated visual-regression tooling yet.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.kouch.dev/docs/adr/0003-oled-single-accent-design.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
