ADR-0006: Frontends are mobile-first
- Status: Accepted
- Date: 2026-05-30
- Scope: core (all frontends, every project)
Context
The Expenses apps were built desktop-first and patched for mobile afterward. The admin
console shipped outright unusable on phones (full-width sidebar over the content,
overflowing tables) and needed a retrofit in v0.2.0–v0.2.1. Retrofitting is
painful and error-prone; designing for the small screen up front is cheaper and
produces better layouts. Real users open these on phones.
Decision
New frontend work is authored mobile-first.
- Author the small-viewport layout as the base, then enhance upward with
min-widthmedia queries — not desktop-base +max-widthpatches. - Minimum bar (definition of done) for any frontend surface:
- Works at 375px wide with no horizontal page scroll.
- No business-critical element is hidden on mobile. Reflow/restack it —
neverdisplay: nonean action the user needs. - Dense data tables either reflow/stack (e.g. rows → cards) or use a
contained horizontal scroll (the table scrolls inside its own wrapper via
overflow-x: auto; the page never scrolls sideways) — whichever keeps the
data readable. What’s banned: page-level horizontal scroll, and a clipped /
cut-off column (anoverflow: hiddenwrapper with no scroll container). - The mobile viewport is actually checked before “done” (generalizes the prior
feedback_mobile_check_requiredrule).
Brand-neutral mobile-UX baseline (the useful kernel of systems like Material —
ergonomics, not a visual skin; each app keeps its own design language, so we do
not adopt the Material look, Roboto, FABs, etc.):
- Touch targets ≥ ~44px on the mobile layout — no dense desktop-size hit
areas (padding counts toward the target). - Primary action stays thumb-reachable — prefer a bottom sheet / sticky
bottom action over a top-corner placement for a screen’s main action on phones. - Visible press/active + focus state on interactive elements — never
hover-only (touch has no hover). - Existing code is desktop-first (
max-widthqueries). This ADR governs new
work and surfaces being touched — not a wholesale rewrite. Migrate
opportunistically.
Per-app responsive mechanics (breakpoints, drawer, table-stacking) are recorded
in the app’s project folder in this handbook (e.g.
docs/expenses/frontend-web/0002-responsive-layout-mechanics.md,
docs/expenses/frontend-admin/0001-responsive-layout-mechanics.md).
Consequences
- Mobile is a first-class default, not an afterthought, so we stop shipping
desktop-only screens that need a later rescue. - A clear, checkable bar that the
handbook:ask-mobilereviewer agent can audit. - Mixed paradigms during the transition (old
max-width, newmin-width) —
accepted; consistency improves as surfaces are revisited.
Related
docs/expenses/frontend-web/0002-responsive-layout-mechanics.mddocs/expenses/frontend-admin/0001-responsive-layout-mechanics.md- Enforcement: the
handbook:ask-mobilereviewer agent