Session 37: Design system Phase F — mobile parity: 5-tab bar, More sheet, PWA polish (1872 tests)

VYNDR 2.0 conversion, Phase F (mobile is the PWA we launch first). Frontend-only;
zero backend changes.

- BottomTabBar rewritten to the §6 5-tab spec: Slate/Terminal/Scan/Ledger/More,
  with Scan as the prominent raised grade-green action. Shown for anon too (only
  mobile nav). Integrated More bottom sheet (sheet-up, backdrop dismiss, 48px mono
  rows). iOS safe-area + 44px touch targets.
- Nav hamburger retired on mobile (tab bar owns nav).
- globals.css mobile section: tab-bar hidden >=768, main bottom padding,
  grade-hero 80px, terminal-grid stacks, game-lines horizontal scroll.
- PWA: manifest shortcuts (Slate/Scan/Terminal) + categories; viewport-fit=cover.

Gotcha: `as const` on the TABS array broke type-check (distinct literal types);
fixed with a shared TabDef interface.

19 new tests. Backend 1853 -> 1872, 145 suites, zero regressions. Web build clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kev
2026-06-16 10:11:52 -04:00
parent 612f5e0b72
commit f88961885c
10 changed files with 433 additions and 141 deletions
+4 -1
View File
@@ -310,13 +310,16 @@ export default function Nav() {
</a>
)}
{/* Session 37 — the mobile bottom tab bar + More sheet now own
mobile navigation, so the hamburger is retired (display:none).
The mobile panel below is consequently dead code but harmless. */}
<button
className="nav-mobile-toggle"
aria-label="Toggle menu"
aria-expanded={mobileOpen}
onClick={() => setMobileOpen((o) => !o)}
style={{
display: 'flex',
display: 'none',
background: 'transparent',
border: '1px solid var(--border)',
borderRadius: 8,