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-width media queries — not desktop-base + max-width patches.
  • 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 —
      never display: none an 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
      (an overflow: hidden wrapper with no scroll container).
    • The mobile viewport is actually checked before “done” (generalizes the prior
      feedback_mobile_check_required rule).

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-width queries). 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-mobile reviewer agent can audit.
  • Mixed paradigms during the transition (old max-width, new min-width) —
    accepted; consistency improves as surfaces are revisited.
  • docs/expenses/frontend-web/0002-responsive-layout-mechanics.md
  • docs/expenses/frontend-admin/0001-responsive-layout-mechanics.md
  • Enforcement: the handbook:ask-mobile reviewer agent