Designing — Elements
Element-level guidance for every Koder UI. Defines the unit cells of the design system — surfaces, text, controls, containers, and affordances — and the rules that compose them into pages. Material parity (`/foundations/designing/elements`); ratified as part of the Koder Design Visual facet expansion (#049.1).
Spec — Designing: Elements
Facet *isual*do Koder Design. Material parity ref: https://m3.material.io/foundations/designing/elements.
Every Koder UI decomposes into 5 element families. Knowing which family a thing belongs to determines its allowed tokens, motion, elevation, and accessibility contract.
The 5 element families
| Family | Purpose | Examples | Token group |
|---|---|---|---|
| *urface* | The "paper" the UI is painted on | App background, sheet, card, dialog body | bg, surface, surface-variant |
| *ontainer* | Visual grouping with structure | Card frame, section group, list block | surface, border, radius-* |
| *ontrol* | User-actionable affordance | Button, switch, slider, link | accent, accent-strong, accent-on |
| *ontent* | Conveyed information | Text, image, icon, code block | text, text-muted, typography scale |
| *ecoration* | Pure visual rhythm (no semantics) | Divider, badge accent stripe, ornament | border, accent-strong (sparingly) |
Composition: every screen reduces to a tree where surfaces hold containers, containers hold content + controls, decorations punctuate.
R1 — Element identity is mandatory
A new visual block must declare which family it belongs to via class prefix:
.s-*— surface.c-*— container (use the bare slug; existing convention).btn-*,.input-*,.switch-*— control (named by control type)text,code,kbd,img— content (semantic HTML preferred).divider,.dot,.bar— decoration
Mixedfamily blocks are an antipattern; split into nested elements.
R2 — Token discipline per family
| Family | MUST use | MUST NOT use |
|---|---|---|
| Surface | bg/surface/surface-variant |
accent (controls only) |
| Container | surface/border/radius |
bg (surface owns the page bg) |
| Control | accent/accent-strong/accent-on for actions |
text-muted for primary action label |
| Content | typography scale + text/text-muted |
accent as body text color (use links) |
| Decoration | border or muted accent at low opacity |
full-strength accent (steals focus) |
R3 — Affordance hierarchy
Within a single surface, controls follow strict hierarchy:
- *rimary action*— at most ONE per surface.
accentfilled. - *econdary action*— 0..N.
outlinedstyle. - *ertiary*— text
only / icononly. - *estructive*— visually separated (right-aligned or hierarchy
marker), uses
errortoken notaccent.
R4 — Touch target
All controls must satisfy minimum touch target per safe-area.kmd (48×48 dp mobile, 32×32 px desktop with 8px spacing).
R5 — Accessibility per family
| Family | A11y requirement |
|---|---|
| Surface | color-scheme matching theme; sufficient contrast for nested content |
| Container | role="region" + aria-label when not implicit from heading |
| Control | Visible focus ring (outline: 2px solid focus); keyboard reachable; aria-* for state |
| Content | Semantic HTML (<h1>-<h6>, <p>, <img alt>); contrast AA minimum, AAA preferred |
| Decoration | aria-hidden="true" (purely visual) |
Examples
<!-- ✅ Surface > Container > (Content + Control) -->
<main class="s-page">
<section class="c-card">
<h2 class="text-title">User profile</h2>
<p class="text-body">Update your display name.</p>
<input class="input-text" type="text">
<button class="btn-primary">Save</button>
</section>
</main><!-- ❌ Mixed family: surface uses accent (control color) -->
<main class="s-page" style="background: var(--accent);">
...
</main>Cross-link
app-layout/safe-area.kmd— touch targets + window insetsthemes/color-schemes.kmd— token names per familyinteraction/states.kmd— focushoverpressed/disabled per controlthemes/ui-style.kmd— shape/density vary per family