Color roles
Semantic color role taxonomy — the mapping from concrete tokens (bg, surface, accent, error, etc.) to the UI elements that use each. Material parity (`/styles/color/roles`). Companion to `themes/color-schemes.kmd` (which defines the actual colors) and `foundations/elements.kmd` (which says which family uses which role).
Spec — Color roles
Facet *isual*do Koder Design. Material parity: https://m3.material.io/styles/color/roles.
A *ole*is a semantic slot ("primary action accent", "page background"). A *oken*is the concrete value bound to that role in the current theme. Roles stay constant across themes; tokens vary.
R1 — The 18 canonical roles
Organized by the 5 element families from foundations/elements.kmd:
Surface roles
| Role | Token | Use |
|---|---|---|
bg |
--kdr-bg |
Page background |
surface |
--kdr-surface |
Cards, sheets, raised containers |
surface-variant |
--kdr-surface-2 |
Recessed/inset surfaces (search box, code block) |
surface-inverse |
inverse-bg | Snackbars, tooltips (dark on light pages, light on dark) |
Content roles
| Role | Token | Use |
|---|---|---|
text |
--kdr-text |
Primary text on bg / surface |
text-muted |
--kdr-text-muted |
Secondary text, captions, helper text |
text-subtle |
--kdr-text-subtle |
Disabled text, placeholders |
text-on-accent |
--kdr-accent-on |
Text on accent-filled surfaces |
Control roles
| Role | Token | Use |
|---|---|---|
accent |
--kdr-accent |
Primary action button, active link |
accent-strong |
--kdr-accent-strong |
Hover/pressed state of accent |
accent-on |
--kdr-accent-on |
Foreground on accent (text/icon) |
accent-tint |
accent at 12% opacity | Selected row background, focus halo |
Status roles
| Role | Token | Use |
|---|---|---|
error |
--kdr-error |
Error state border/text |
error-bg |
--kdr-error-bg |
Error banner background (subtle tint) |
warning |
--kdr-warning |
Warning state border/text |
success |
--kdr-success |
Confirmation badge, valid input |
info |
--kdr-info |
Informational banner |
Decoration roles
| Role | Token | Use |
|---|---|---|
border |
--kdr-border |
Container borders, dividers |
border-strong |
--kdr-border-strong |
Emphasis borders (focused container) |
focus |
--kdr-focus |
Keyboard focus ring color |
selection |
--kdr-selection |
Text selection bg / row selection bg |
R2 — Role binding contract
Every koder_kit widget MUST bind colors via roles, not raw hex:
// ❌
Container(color: Color(0xFF3B5BFD)) // hardcoded
// ✅
Container(color: KoderTheme.of(context).accent)The theme exposes a typed KoderColorRoles struct (planned) with one getter per role. Widget code never references tokens by string.
R3 — Inversion in dark mode
Roles flip meaning between light and dark themes via the token system, not via per-widget logic. Example:
| Role | Light theme token | Dark theme token |
|---|---|---|
bg |
#FFFFFF |
#0B1220 |
text |
#0B1220 |
#E7ECF5 |
accent |
#3B5BFD |
#7E97FF (lighter for dark bg legibility) |
Widget code stays the same; the theme rebinds the tokens.
R4 — Contrast requirements
Per color-schemes.kmd § AAA contrast, role bindings must satisfy:
| Pair | Min ratio |
|---|---|
text/bg, text/surface |
7.0 (AAA Normal) |
text-muted/bg |
4.5 (AA) |
accent-on/accent |
4.5 (AA) |
error/error-bg |
4.5 |
focus/bg |
3.0 (UI element contrast) |
high_contrast preset tightens all to ≥ 7.0.
R5 — Forbidden bindings
- ❌ Body text on
accentbackground (useaccent-oninstead) - ❌
text-mutedfor primary action labels (usetextoraccent-on) - ❌ Body text in
errorcolor (red text outside error context is alarming) - ❌ Custom hex on user-facing surface without going through a role
R6 — When to add a new role
Adding a role is an architectural decision (impacts every theme). Threshold:
- Needed by ≥ 2 widgets
- Not expressible via existing role + opacity modifier
- Has a stable semantic meaning across themes
Process: propose via PR with the binding added to all 12 color scheme presets simultaneously (per color-schemes.kmd Catalog).
Cross-link
color-schemes.kmd— concrete tokens per presetlight-dark.kmd— light/dark switching behaviorfoundations/elements.kmd— which family uses which rolesinteraction/states.kmd— overlay/state colors derive from roles