Adaptive design
foundations specs/foundations/adaptive-design.kmd
Koder UI is adaptive by default — single codebase serves phones, tablets, foldables, desktops, TVs, and web. Defines the principles, the 4 window-size classes, and the rules each layout uses to reflow. Material parity (`/foundations/adaptive-design`); complement to `app-layout/safe-area.kmd` (which covers insets) and `window-size-classes.kmd` (which covers the canonical breakpoints).
Quando esta spec se aplica
Triggers primários
- Design any cross-surface Koder screen
Todos os triggers
- Build a screen that runs on more than one form factor
- Decide breakpoint behavior (collapse, transform, switch)
- Add a new surface that needs to be responsive
Corpo da especificação
Spec — Adaptive design
Facet Visual do Koder Design. Material parity: https://m3.material.io/foundations/adaptive-design.
Principle
One codebase. Every surface. No "responsive afterthought". A Koder UI must work on the smallest expected surface from day 1; any larger surface is an enhancement, never a special-case rewrite.
This applies equally to:
- Flutter apps (mobile + desktop + web + TV)
- Web apps (browser desktop + mobile breakpoint)
- Landing pages (covered by
web-apps/responsiveness.kmd) - CLIs (TTY width adaptation — yes, even CLIs adapt)
R1 — 4 window-size classes (canonical)
Aligned with Material 3 window-size classes. Full spec in
app-layout/window-size-classes.kmd; summary here:
| Class | Width | Typical surface |
|---|---|---|
| Compact | 0–599 dp | Phone portrait |
| Medium | 600–839 dp | Phone landscape, small tablet, foldable inner |
| Expanded | 840–1199 dp | Large tablet, small desktop, foldable outer |
| Large | ≥ 1200 dp | Desktop, TV |
Breakpoints are density-independent pixels (dp) so Flutter, Web, and Android share the mental model.
R2 — 3 adaptive strategies per element
Every UI element pick ONE of three strategies at each breakpoint:
| Strategy | Behavior | Examples |
|---|---|---|
| Resize | Same element, different dimensions | Card width, font size step |
| Reflow | Same element, different position/order | Sidebar moves to bottom on Compact |
| Transform | Different element entirely | Navigation bar → drawer; full picker → dropdown |
Anti-pattern: mixing all three within one component without documentation — leads to unpredictable behavior.
R3 — Canonical layouts
Material defines 4 canonical layouts (full spec in
canonical-layouts.kmd):
- Feed — vertical scrollable list, full-width on Compact, multi-column on Expanded
- List-detail — split pane on Expanded; stack on Compact
- Supporting pane — primary content + auxiliary pane (collapsible)
- Custom — when the above don't fit
Pick one per screen and stick with it across breakpoints.
R4 — Touch + pointer parity
The same surface must work with touch (Compact/Medium) and pointer (Expanded/Large). Implications:
- All controls satisfy 48×48 dp touch target (
safe-area.kmd) - Hover states are enhancements, never required for primary flow
- Right-click is enhancement; long-press is the touch equivalent
- Drag-and-drop must have a non-drag alternative (button, menu)
R5 — Input modality detection
// Flutter
final canHover = MediaQuery.of(context).platformBrightness != null
&& Theme.of(context).platform.supportsMouse;
// Web (CSS)
@media (hover: hover) { /* hover-capable styles */ }
@media (pointer: coarse) { /* touch-first sizing */ }
Don't gate primary functionality on hover. Use it for refinement.
R6 — Foldable support
Foldable devices switch class mid-session. Koder UIs:
- Listen to size changes via
MediaQuery/ResizeObserver - Re-pick canonical layout on class change
- Preserve scroll position + form state through the transition
R7 — TV (10-foot UI)
Class Large at high DPI (TV) requires:
- Focus indication 2× normal stroke (TV viewing distance)
- Touch target 64×64 dp minimum (D-pad navigation imprecision)
- Color contrast AAA (not AA) — viewing angle variance
See koder-app/behaviors.kmd for full TV adaptation rules.
Cross-link
window-size-classes.kmd— full breakpoint speccanonical-layouts.kmd— 4 layout templatessafe-area.kmd— touch targets + insetsweb-apps/responsiveness.kmd— landing page subsetnavigation/back-behavior.kmd— adapts per class (drawer vs bar)
Referências
rfcs/design-RFC-001-koder-design-system.kmdspecs/app-layout/safe-area.kmdspecs/app-layout/window-size-classes.kmdspecs/app-layout/canonical-layouts.kmdspecs/navigation/back-behavior.kmd