Docs + verify report for mobile responsive parity (Slice 10)
Add Mobile Responsive Design section to docs/REQUIREMENTS.md documenting the breakpoint policy (single md:768px), hybrid table strategy (cards below md), SheetForm edit flows, 44px touch targets, dashboard single-column + anchors, unchanged polling, and HoverEditButton behavior. Add openspec verify-report.md with per-AC evidence (AC1-AC8), residual risks (R4.5 dirty-state confirm, default-button touch targets, polling on battery, iOS Safari manual verification, pagination duplication), and non-goals confirmation. All 9 routes fully operable at 375px. 116 frontend tests pass; lint/build green. Desktop layout unchanged. No backend changes. Refs openspec/changes/mobile-responsive-parity/ (tasks slice 10).
This commit is contained in:
@@ -468,3 +468,57 @@ The system receives backup execution reports from an external backup tool via HT
|
||||
|
||||
- Backup tool uses auto-generated Bearer API key
|
||||
- Frontend uses existing OIDC/JWT auth
|
||||
|
||||
## Mobile Responsive Design
|
||||
|
||||
The frontend is fully operable in phone portrait (≥360px) at a single `md:`
|
||||
(768px) breakpoint. Tablets and wider viewports use the desktop layout
|
||||
unchanged.
|
||||
|
||||
### Breakpoint policy
|
||||
|
||||
- Single responsive cut: `md:` (768px). Below is "mobile"; at-or-above is
|
||||
"desktop" (existing layout, unchanged).
|
||||
- `useIsMobile()` hook (`frontend/src/hooks/useIsMobile.ts`) is the single
|
||||
source of truth; it wraps `matchMedia("(max-width: 768px)")` and is SSR-safe.
|
||||
- No `sm:` intermediate cut. No PWA, manifest, or service worker.
|
||||
|
||||
### Data tables (hybrid)
|
||||
|
||||
- The four wide tables (Media, FileBrowser, Users, Backups) render stacked
|
||||
**cards per row** below `md` via `MobileCardRow`, each showing a primary
|
||||
title plus 3–5 key fields. Narrow tables (SessionActivity) keep horizontal
|
||||
scroll. The TanStack column-visibility toggle is hidden below `md`.
|
||||
- At `md:` and above, all tables render as the existing `<DataTable>` unchanged.
|
||||
|
||||
### Edit forms (Sheet)
|
||||
|
||||
- Below `md`, ServicePage, Settings (machine editor), message compose, and
|
||||
WidgetConfigDialog open inside a full-height `SheetForm` (side=bottom,
|
||||
`h-[100dvh]`) with sticky header + sticky save bar instead of a centered
|
||||
Dialog.
|
||||
- At `md:` and above, the existing Dialog-based forms are unchanged.
|
||||
|
||||
### Touch targets
|
||||
|
||||
- All interactive elements below `md` have a minimum 44×44px hit area via the
|
||||
`.mobile-touch-target` CSS utility (applied only below 768px). This covers
|
||||
icon buttons, checkboxes, switches, and small text buttons. The class is a
|
||||
no-op at `md:` and above.
|
||||
|
||||
### Dashboard
|
||||
|
||||
- Below `md`, the widget grid collapses to a single column with a section
|
||||
anchor bar (Observability / Media / Backups / Custom) for quick navigation.
|
||||
- At `md:` and above, the existing multi-widget grid is unchanged.
|
||||
|
||||
### Polling
|
||||
|
||||
- Widget refresh intervals and the message-queue poll interval are identical
|
||||
on mobile and desktop. A follow-up to pause refetch when the tab is hidden
|
||||
(`document.visibilityState`) is tracked as a future battery optimization.
|
||||
|
||||
### `HoverEditButton`
|
||||
|
||||
- Below `md`, edit affordances are always visible (not hover-gated). At `md:`
|
||||
and above, the desktop hover-reveal aesthetic is preserved.
|
||||
|
||||
Reference in New Issue
Block a user