Customization
foundations specs/foundations/customization.kmd
How users + developers personalize Koder UI without leaving the design system. Material parity (`/foundations/customization`). Covers the axes available (style × scheme × density × motion × i18n × layout density × accessibility prefs), where each persists, who the audience is, and what's NOT customizable per surface.
When this spec applies
Primary triggers
- Configure customization surface in any Koder app
All triggers
- Add a new user-facing customization toggle
- Decide whether something belongs in Settings or hard-coded
- Implement per-surface theme/preference persistence
Specification body
Spec — Customization
Facet Visual do Koder Design. Material parity: https://m3.material.io/foundations/customization.
Customization axes (canonical 8)
Every Koder app exposes the same 8 axes in Settings (where applicable), with the same default values and the same persistence pattern. Spec per axis lives in linked references; this doc catalogs them.
| Axis | Default | Spec |
|---|---|---|
| UI style (forma/densidade) | material3 | themes/ui-style.kmd |
| Color scheme (paleta) | default | themes/color-schemes.kmd |
| Theme mode (claro/escuro) | system | themes/light-dark.kmd |
| Language (i18n) | device locale | i18n/contract.kmd |
| Voice / wake-word | OFF (except barge-in) | voice/wake-word.kmd |
| Error reporting | OFF (opt-in) | errors/reporting.kmd |
| Auto-update | ON | koder-app/behaviors.kmd §4 |
| Density | comfortable | themes/ui-style.kmd |
R1 — One Settings page, consistent shape
Every Koder app's Settings page has the SAME section order:
- Appearance (UI style, color scheme, theme mode, density)
- Language (locale picker, ICU regional prefs)
- Notifications (per-app)
- Voice (wake-word, barge-in, hot phrases)
- Privacy (error reporting, telemetry opt-out, data export)
- Account (sign-in, sign-out, tenant switch)
- About (version, licenses, what's new)
Order is rigid; sections can be omitted (no Voice → skip), never reordered.
R2 — Persistence
| Axis | Where it persists |
|---|---|
| Appearance + Language | Per-surface (localStorage / Flutter SharedPreferences) — sticky per device |
| Voice | Per-app (same storage) |
| Privacy | Per-app + propagated to backend audit log on opt-in |
| Account | Server-side (Koder ID) |
R3 — System hints
When the user has not made a choice, surfaces follow system hints:
- Theme mode:
ThemeMode.system/prefers-color-scheme - Language:
Platform.localeName/navigator.language - High contrast / reduced motion: OS accessibility prefs (Android
View.SystemUiHints, iOSUIAccessibility, WindowsSystemSettings, GNOMEorg.gnome.desktop.a11y, etc.)
R4 — Per-tenant vs per-user vs per-surface
| Scope | Examples |
|---|---|
| Per-tenant (workspace-wide) | Custom brand color, organization name, allowed login methods |
| Per-user (synced) | Display name, notification prefs, language |
| Per-surface (device-local) | UI style, density, theme mode, voice settings |
Per-tenant customization always takes precedence over per-user; per-user always takes precedence over per-surface defaults.
R5 — What's NOT customizable
The following are deliberately fixed to preserve product identity:
- Product logo / icon
- Element family taxonomy (
foundations/elements.kmd) - Canonical layouts (
canonical-layouts.kmd) - Error message format (
errors/user-facing-messages.kmd) - Touch target minimums (
safe-area.kmd) - Keyboard shortcuts that conflict with OS conventions
- Brand-color accent (varies by tenant, but the role "accent" stays)
User requests for these go through product feedback, not Settings.
R6 — Customization pickers in UI
Each axis has a canonical widget (in koder_kit):
| Axis | Widget | Spec ref |
|---|---|---|
| UI style | KoderUIStylePicker | themes/ui-style.kmd |
| Color scheme | KoderColorSchemePicker (planned) | themes/color-schemes.kmd |
| Theme mode | KoderThemeToggle | themes/light-dark.kmd |
| Language | KoderL10nSwitcher | i18n/contract.kmd §R3 |
| Voice | KodeVoiceSettingsTile | voice/wake-word.kmd |
| Error reporting | KoderReportButton toggle | errors/reporting.kmd |
R7 — Reset to defaults
Every Settings page exposes a "Reset to defaults" button in the About section. Behavior:
- Clears all per-surface preferences (returns to system hints)
- Per-user prefs preserved (the user owns those)
- Per-tenant prefs unaffected (admin owns those)
- Confirmation dialog: "Reset appearance and preferences to defaults?"
Cross-link
- All axis specs above
koder-app/behaviors.kmd— broader app behaviorspolicies/reuse-first.kmd— pickers come fromkoder_kit, not per-app
References
specs/themes/ui-style.kmdspecs/themes/color-schemes.kmdspecs/themes/light-dark.kmdspecs/i18n/contract.kmdspecs/voice/wake-word.kmdspecs/errors/reporting.kmd