ADR-018 — Mobile-first design, bottom sheet panel pattern
Status · Accepted Date · 2026-04-28 TA anchor · §stack · §components
Context
At the scale of millions of users, roughly half will be on mobile devices. The current prototypes are desktop-only. Mobile must be designed in from the start, not retrofitted.
Decision
Mobile-first design throughout. The base CSS targets small screens; larger screens progressively enhance. The detail panel pattern is a bottom sheet (slides up from the bottom edge) on small screens and a right-side drawer on large screens. Minimum touch target size: 44×44px (iOS HIG / Material Design). Three.js screens support single-finger orbit and two-finger pinch-zoom.
Breakpoints:
mobile: < 768px (base — design here first)
tablet: 768–1024px
desktop: > 1024pxRationale
A bottom sheet is the correct mobile pattern for contextual detail content — it is native to both iOS and Android, leaves the canvas visible behind it, and dismisses with a swipe-down gesture. The right-side drawer is correct on desktop where 314px of panel width is available without obscuring the canvas. SvelteKit components render the appropriate pattern via a CSS media query and a shared panel component that adapts its position.
Alternatives considered
- Full-screen modal on mobile — hides the canvas entirely; worse for context; rejected.
- Desktop-only for v1 — wrong assumption at production scale; rejected.
- Responsive right panel — scales the right panel narrower on mobile; 200px panels are illegible; rejected.
Consequences
Positive: genuinely usable on mobile from day one; bottom sheet is a native-feeling pattern; no UX debt to pay later. Negative: every component must be designed at mobile size first; the porkchop plot (PRD-002) requires a separate mobile interaction design; Three.js touch handling must be explicit.
Implementation notes
CSS custom properties for breakpoints. Svelte components accept a variant: 'sheet' | 'drawer' prop determined by a matchMedia store. Three.js touch: touchstart/touchmove listeners for orbit; gesturechange or two-touch distance delta for zoom. Panel component is shared; layout variant is determined at runtime.