Koder Design — Density modes
Three canonical page-level density modes (compact / default / comfortable) with token deltas, accessibility floor, persistence pattern, and multi-tenant override rules. Density scales Verge spacing + typography tokens uniformly through CSS custom property cascade, so consumers opt in through a single attribute on the document root.
Koder Design — Density modes
Density is the global rhythm a Koder surface ships with. Three canonical modes are supported: *ompact* *efault* *omfortable* The mode sets data-density on <html>; Verge tokens cascade through CSS custom properties so every component picks up the new rhythm without per-call overrides. Power-user tools default to *ompact* touch tablets opt in to *omfortable* public landings stay on *efault*
This is parity work with Fluent 2 (Microsoft Design), Material 3 ("Density" in the Spacing track), and Carbon ("Spacing scale + tokens"). The ratio −20% / 0% / +20% matches Fluent 2's spacing track to make a crossdesignsystem port mechanical.
R1 — When to use which mode
- *ompact*(default for Koder admin/data
dense surfaces): Outlookclassinboxes, Excel-class grids, log viewers, dev tools, file managers, Flow's repo browser. Power users on desktop with a mouse.
- *efault*(default everywhere else): landing pages, marketing, docs
(KDS site), product home, settings, dialogs, onboarding. Reading comfort + density balance.
- *omfortable* touch tablets, kiosks, TV (10-foot UI), accessibility
user preference. Larger hit targets, more breathing room.
The page *icks one mode*as default; user override goes into the Settings drawer (see R4). Per-component override is *ut of scope*of this spec — see § Não-escopo.
R2 — Token deltas
Density multiplies Verge tokens through a single multiplier custom property --kds-density-scale. Compact = 0.8, default = 1, comfortable = 1.2. Tokens that read through the scale automatically respect the mode:
| Token family | Compact | Default | Comfortable |
|---|---|---|---|
--kds-space-* |
× 0.8 | × 1 | × 1.2 |
--kds-line-height-tight |
× 0.95 | × 1 | × 1.05 |
| Form control min-height | 32 px | 40 px | 48 px |
| Button padding (Y) | 6 px | 8 px | 10 px |
| List row padding | 4 px | 8 px | 12 px |
Typography sizes from specs/fonts/typography.kmd stay constant — only spacing and component minimum dimensions scale. Rationale: changing type sizes per density mode breaks visual hierarchy and AAA contrast spot-checks done at the canonical scale.
R3 — Accessibility floor
The *omfortable*mode is the WCAG 2.2 baseline for touch targets: formcontrol minimumheight never drops below 44 px (per specs/koder-app/behaviors.kmd § Tap targets). Compact is desktop-only and intentionally violates the touch target floor; surfaces that ship compact MUST also ship a "tap target ≥ 44 px" branch behind @media (pointer: coarse) so a touch device viewing a compact surface gets the comfortable rhythm anyway.
@media (pointer: coarse) {
[data-density="compact"] { --kds-density-scale: 1.2; }
}This is mandatory; failure to ship it fails T3 below.
R4 — Persistence
User override persists in localStorage["koder.density"] with values compact | default | comfortable. The anti-flash script in the page shell reads the key and writes data-density on <html> before first paint — same pattern as koder.theme from specs/themes/light-dark.kmd § Persistence.
Settings drawer surfaces a 3-segment control (Compact / Default / Comfortable) below the Theme group, sharing the same visual treatment (button[role="radio"] set, aria-pressed). The drawer writes the new value to localStorage and data-density on <html> immediately.
A page MAY ship a per-page initial density via the density query parameter (?density=compact) — useful for marketing previews that demonstrate the surface at a specific rhythm. Query overrides persist *nly for the session*(sessionStorage); the persisted localStorage choice is not mutated.
R5 — Multi-tenant override
Tenants on the Koder platform MAY pin density per workspace via the workspace.density_default setting. When set, the platform shell injects the override before the anti-flash script so the user's localStorage choice still wins (R4 takes precedence). Tenants MUST NOT lock the override; a tenant that genuinely needs a fixed density (public kiosk) ships its own surface, not a tenant-platform setting.
Tests
| ID | Test |
|---|---|
| T1 | Setting data-density="compact" on <html> reduces resolved --kds-space-md by 20% from default. |
| T2 | Setting data-density="comfortable" increases it by 20%. |
| T3 | @media (pointer: coarse) block forces comfortable rhythm regardless of data-density attribute. |
| T4 | localStorage koder.density set to compact survives reload (anti-flash applies before paint). |
| T5 | Settings drawer 3 |
| T6 | Per inside .koder-*` components is 0. |
Não-escopo
- Per-component density override (compact button inside default form).
Density is page
level by spec; tools that need a denser subregion ship a custom token scope. - Touch
detect autodensity. Spec defaults todefault; touch devicesopt in to comfortable via Settings or via the
@media (pointer: coarse)branch (R3). Automatic OS detection would conflict with the three-way persisted user choice.
References
specs/themes/light-dark.kmd§ Persistence — anti-flash patternspecs/themes/verge.kmd§ R4 — token map this scalesspecs/fonts/typography.kmd— type scale stays constantspecs/koder-app/behaviors.kmd§ Tap targets — touch floor- Fluent 2 density tracks · Material 3 spacing scale · Carbon spacing