feat(phase 3i mobile): responsive CSS across all projax pages

- viewport meta on layout.tmpl + login.tmpl (iOS won't render legibly without)
- two breakpoints: tablet (≤768px), phone (≤480px)
- chip strips: horizontal-scroll with sticky labels instead of wrapping
- tables → card lists: classify + bulk render as stacked cards on mobile
- forms: single column on phone; min 44px touch targets on buttons
- dashboard: cards already 1-col, polish for narrow widths; grid jumps to
  2 columns at ≥1280px with stale card spanning both
- /graph: SVG scrolls inside .graph-canvas (max-width 100vw, max-height
  75vh, overflow auto); "fit to screen" toggle flips natural vs viewport
- TestLayoutHasViewportMeta verifies every chrome-bearing route ships the
  meta tag
- CLAUDE.md "Out of scope" drops mobile/Otto-PWA exclusion (head approved
  on m/mAi#1861); replaced with native-PWA-install line for Phase 3j
- design.md adds §"Mobile responsiveness" with breakpoint + principle notes
This commit is contained in:
mAi
2026-05-15 19:27:07 +02:00
parent f2f74d1fef
commit 522b7489d3
7 changed files with 186 additions and 3 deletions

View File

@@ -418,6 +418,35 @@ A read-only top-down DAG render of every projax item at `/graph`, server-rendere
**Out of scope for 3f**: editable layout (drag-to-rearrange), Excalidraw file export, auto-refresh on item changes.
## Mobile responsiveness (Phase 3i)
Pure CSS + minimal template tweaks make every projax page legible and tappable on m's phone (via Tailscale). The original "Otto-PWA covers mobile" plan is dropped — projax's own pages need to render on phone even if Otto-PWA later embeds or links to them.
**Breakpoints** (CSS media queries on `web/static/style.css`):
- ≤ 768px (tablet): chip strips become horizontal-scrollable, tables (`/admin/bulk`, `/admin/classify`) flip to card lists, dashboard cards widen, edit forms drop to single column. Touch targets bump to ≥ 44px on buttons.
- ≤ 480px (phone): base font nudges to 15px so default body text is legible without pinch-zoom. Header nav wraps. The bulk-table primary-path column hides on phone (slug + tags + actions are enough).
- ≥ 1280px (wide laptop): main column widens to 1200px and the dashboard grid splits to 2 columns with the stale card spanning both.
**Layout principles:**
- Viewport meta on every page (`<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">`); enforced by `TestLayoutHasViewportMeta`.
- Touch targets ≥ 44px on phone for buttons + chip toggles. Chip strips use `flex-wrap: nowrap` + `overflow-x: auto` so the row scrolls instead of wrapping into a tall block.
- Tables → cards: `display: block` on tbody/tr/td with `td::before { content: attr(data-label); }` — when m wants per-column labels visible on mobile, add `data-label="…"` to the `<td>`.
- Forms: native `<input type=date>` etc. so iOS pickers fire (already in place).
**SVG `/graph` special case:**
- Wrapped in `.graph-canvas { max-width: 100vw; max-height: 75vh; overflow: auto; }` so the inline SVG scrolls + pinch-zooms inside its container instead of overflowing the page.
- "Fit to screen" toggle (`.graph-canvas.fit .graph-svg { width: 100%; }`) flips between natural-size and viewport-sized renders. Native pinch-zoom remains available via the viewport meta.
**Out of scope:**
- Native PWA install (manifest.json + service worker) — Phase 3j candidate.
- Push notifications (Otto-PWA's domain).
- Dark mode toggle.
- Right-to-left layout.
## 9. Phase-1 deliverable checklist
- [ ] `projax.items` + `projax.item_links` migrations in `db/migrations/`