UI Style preset families
themes specs/themes/presets-families.kmd
Taxonomy organizing the Koder Design UI Style presets into 5 families: **Era**, **Brand**, **Mood/Aesthetic**, **Cultural**, and **Domain**. Defines the canonical preset slug grammar, the family-tagged grouping shown in the preset picker, and the expansion roadmap from 19 (today) → ~35-45 (target). Companion spec for ticket #030.
When this spec applies
Primary triggers
- Add preset family classification
All triggers
- Add a new UI Style preset
- Categorize the preset picker
- Plan a preset expansion wave
Specification body
Spec — UI Style preset families
Facet Styles of Koder Design. Cross-link:
policies/reuse-first.kmd.
Source ticket: meta/docs/stack#030. This spec defines the taxonomy;
each family expansion is tracked in its own sub-ticket (#050-#054).
Why families
19 presets in flat list is hard to browse, and the picker page becomes unscannable past ~25 entries. Material 3 itself groups its design examples by "type of brand" tacitly; Koder makes the grouping explicit:
| Without families (today) | With families (target) |
|---|---|
| 19 flat tiles in alphabetical order | 5 family sections, each with 5-10 tiles |
| Hard to find "is there a CRT-style preset?" | Browse Era → 80s/90s → CRT terminal |
| Hard to plan additions ("we need more brands") | "Brand family is 3/8; need 5 more" |
Taxonomy — 5 families
| Family | What it captures | Examples (existing + planned) |
|---|---|---|
| Era | Time-period aesthetics — defined era | windows_95, aqua_classic, frutiger_aero, synthwave (existing); crt_terminal, web_1.0, vista_aero, 2010s_flat, early_2020s_neumorphism (planned) |
| Brand | Platform / vendor design languages | material3, material2, material_expressive, ios_cupertino, macos_sonoma, windows_11, fluent_design, gnome, kde_breeze, yaru, plasma6, shadcn, carbon_ibm (existing); tailwind_default, chakra, mantine (planned) |
| Mood / Aesthetic | Subjective visual treatment, no era / brand anchor | brutalist, minimalist_mono, glassmorphism, neumorphism, cyberpunk_neon, high_contrast, compact_power_user, dieter_rams, swiss, bauhaus, pantheon, newspaper (existing); kawaii_pastel, dark_academia, cottagecore, solarpunk (planned) |
| Cultural / Regional | Cultural visual idioms | japanese_mu, mediterranean (existing); scandi_clean, latin_warm, arabic_arabesque, indian_jaipur, african_kente, chinese_imperial (planned) |
| Domain | Surface / context-specific UI conventions | terminal_classic, memphis_pop, notion, discord (existing); medical_pro, enterprise_dashboard, gaming_hud, kiosk_signage, automotive_hud (planned) |
R1 — Preset slug grammar
| Form | Pattern | Example |
|---|---|---|
| Existing flat (backwards-compat) | <slug> | material3, synthwave |
| New family-tagged | <slug> (slug carries the family hint via prefix when ambiguous) | era_crt_terminal, brand_tailwind_default, cultural_arabic_arabesque |
Backwards compatibility: existing presets keep their flat slugs; no rename. New presets in ambiguous categories prefix the family explicitly. Future migration to all-tagged slugs requires owner ratification.
R2 — Family membership declaration
Each preset's CSS file (assets/css/presets/<slug>.css) carries a
frontmatter comment block:
/*!
* preset: ios_cupertino
* family: brand
* era: 2020s (current) # optional sub-tag
* description: Apple's modern iOS / macOS visual style
* ratified: 2026-02-15
*/
design-gen reads the comment header to populate the picker page groups.
R3 — Preset picker layout
/style/ page (root of styles):
┌─────────────────────────────────────────────┐
│ Pick a UI Style │
│ ─────────────────────────────────────────── │
│ │
│ Filter: [All] [Era] [Brand] [Mood] [Cult.] │
│ [Domain] [Light] [Dark] │
│ │
│ Era (5 / planned 10) │
│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │win95│ │aqua │ │frut │ │synth│ │cyber│ │
│ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │
│ │
│ Brand (9 / planned 13) │
│ ┌─────┐ ┌─────┐ ┌─────┐ ... │
│ │mat3 │ │mat2 │ │ios │ │
│ └─────┘ └─────┘ └─────┘ │
│ │
│ Mood / Aesthetic (8 / planned 14) │
│ ... │
└─────────────────────────────────────────────┘
- Filter chips (per
components/chips.kmdfilter variant) at top - Section per family with count badge (current / planned)
- Tiles arranged in 4-5 column grid (responsive)
- Hover / focus shows preset name + ratification date
R4 — Expansion roadmap
Target ~35-45 total presets across families. Owner-directed allocation (approximate, not rigid):
| Family | Current | Target | Sub-ticket | Status |
|---|---|---|---|---|
| Era | 5 | 10 | meta/docs/stack#050 | planned |
| Brand | 9 | 13 | meta/docs/stack#051 | planned |
| Mood / Aesthetic | 8 | 14 | meta/docs/stack#052 | planned |
| Cultural | 2 | 8 | meta/docs/stack#053 | planned |
| Domain | 4 | 8 | meta/docs/stack#054 | planned |
| Total | 28 (✱ closer to 19 distinct after dedup) | ~45 | — | — |
Wave order recommended:
- Era + Brand first (lower design risk, high recognition factor)
- Mood / Aesthetic next (creative; needs designer sweeps)
- Cultural and Domain last (require research / consultation)
R5 — Quality gates per preset
Each new preset MUST satisfy before merging:
- All 18 color roles (
color-roles.kmd) defined for Light + Dark - Contrast pairs pass WCAG 2.2 AA per
tools/contrast-checker.kmd § R6 - Typography stack defined (4 roles per
themes/typography.kmd) - Shape scale defined (6 levels per
themes/shape.kmd) - Elevation tokens (6 levels per
themes/elevation.kmd) - Motion tokens (duration + easing per
themes/motion.kmd) - Renders correctly for ALL canonical components in
tools/theme-builder.kmd § R3preview gallery - Mobile-responsive per
develop/docs-mobile-responsiveness.kmd
R6 — Naming + brand-score
Preset slug follows specs/naming/forms.kmd — [a-z][a-z0-9_]*,
unique across all families. Brand-score (per
specs/naming/brand-score.kmd) applies only to presets named after
real brands (Material 3, iOS, etc.); fictional / generic preset
names need not score.
R7 — Per-locale display name
Display names localized:
# tools/design-gen/i18n/en-US.json
"style.ios_cupertino.display": "iOS Cupertino"
# tools/design-gen/i18n/pt-BR.json
"style.ios_cupertino.display": "iOS Cupertino" # often kept English
Localization optional — many preset names work as-is in en-US (e.g., brand names).
R8 — Color-blindness packs
Per themes/color-customization.kmd § color-blindness packs, every
preset must support the 4 simulation modes (Protanopia, Deuteranopia,
Tritanopia, Achromatopsia). Validation runs as part of preset PR
review.
R9 — Forbidden patterns
- ❌ Preset that fails WCAG 2.2 AA on any role pair
- ❌ Preset with > 30 character display name (picker tile truncates)
- ❌ Preset that exists only in Light or only in Dark
- ❌ Preset that doesn't render for canonical wave-1 components
- ❌ Preset registered without family classification
- ❌ Preset slug clashing with an existing one (case-insensitive)
- ❌ Preset that references images / illustrations not in
assets/illustrations/(atomic CSS, no orphan dependencies)
Cross-link
themes/color-roles.kmd— required role coveragethemes/color-dynamic.kmd— palette generationtools/theme-builder.kmd— preview gallery testtools/contrast-checker.kmd— WCAG gatetools/design-kit-export.kmd— preset packs exportdevelop/docs-mobile-responsiveness.kmd— mobile render checkfoundations/customization.kmd— preset is a key customization axis
Implementation tracking
Programme tickets (already opened):
meta/docs/stack#050— Era family expansionmeta/docs/stack#051— Brand family expansionmeta/docs/stack#052— Mood / Aesthetic expansionmeta/docs/stack#053— Cultural family expansionmeta/docs/stack#054— Domain family expansionmeta/docs/stack#030— umbrella (remains pending until all 5 sub-tickets close)
References
specs/themes/color-roles.kmdspecs/themes/color-dynamic.kmdspecs/themes/shape.kmdspecs/themes/typography.kmdspecs/themes/elevation.kmdspecs/themes/motion.kmdspecs/foundations/customization.kmd