FAB lifted above BottomTabBar, phone content padding added, D-01 regression guard committed to layout.spec.ts; 3-profile e2e sweep green.
6.5 KiB
phase, plan, subsystem, tags, dependency_graph, tech_stack, key_files, decisions, metrics, status
| phase | plan | subsystem | tags | dependency_graph | tech_stack | key_files | decisions | metrics | status | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 17 | 03 | pwa/layout |
|
|
|
|
|
|
complete |
Phase 17 Plan 03: Phone Layout Overlap Fix — Summary
Fixed the long-standing phone (≤767px) fixed-chrome overlap where the position: fixed BottomTabBar was covering the New Event FAB and occluding the bottom color-legend chips, using the --bottom-chrome-h token from plan 17-01. Added a permanent D-01 overlap regression assertion to layout.spec.ts. Full 3-profile Playwright suite is green.
What Was Built
One-liner: FAB lifted above BottomTabBar via calc(var(--bottom-chrome-h) + var(--space-6)), phone content reserves --bottom-chrome-h padding, permanent overlap regression guard added to CI.
Task 1: FAB lift + phone content padding (CalendarShell.tsx, App.tsx)
CalendarShell.tsx (phone-only FAB, lines 463–491):
- Changed
bottom: 'var(--space-6)'→bottom: 'calc(var(--bottom-chrome-h) + var(--space-6))' - FAB now sits 24px (var(--space-6)) above the BottomTabBar top edge regardless of safe-area-inset
- All other FAB style properties unchanged (right, width, height, zIndex, etc.)
App.tsx (contentStyle, lines 155–164):
- Added phone-only spread:
...(phone ? { paddingBottom: 'var(--bottom-chrome-h)' } : {}) - Phone content area now reserves space equal to the BottomTabBar height
- Desktop branch has no paddingBottom — geometry unchanged
- Build:
pnpm --filter @familysync/pwa buildexits 0
Task 2: FAB↔BottomTabBar overlap regression assertion (layout.spec.ts)
Added new test.describe block "D-01 regression guard — FAB does not overlap BottomTabBar":
- Test name: "New Event FAB does not overlap BottomTabBar (A — phone only)"
- Skips on desktop (
testInfo.project.name === 'desktop') - Locates FAB via
page.getByRole('button', { name: 'New Event' })and bar viapage.getByRole('navigation', { name: 'Main navigation' }) - Asserts
fabBox.y + fabBox.height <= navBox.y(FAB bottom ≤ BottomTabBar top) - Passes GREEN on iphone (390×844 WebKit) and pixel (412×915 Chromium)
Task 3: Small-viewport sweep across all three profiles
pnpm --filter @familysync/pwa test:e2e(all 3 profiles): 115 passed, 23 skipped, 0 failed- iphone profile: all layout.spec.ts assertions pass including new D-01 guard
- pixel profile: all layout.spec.ts assertions pass including new D-01 guard
- desktop profile: all layout.spec.ts assertions pass; D-01 guard correctly skipped
- No violations flagged by Rules 1–4 assertions
- Admin tab tap target still meets ≥44px after layout changes
- Color-legend chips confirmed fully visible via playwright-cli screenshot at 390×844
Visual Confirmation (playwright-cli @390×844)
Screenshot taken via playwright-cli (Chromium, viewport 390×844, reloaded to pick up phone layout):
- New Event FAB (+): clearly positioned above the BottomTabBar with visible gap
- Color-legend chips ("Dev User" blue, "Family" pink): fully visible between calendar content and BottomTabBar — not clipped or occluded
- BottomTabBar (Calendar, Lists, Admin): fully visible at the bottom edge
Verification Results
| Check | Result |
|---|---|
grep 'calc(var(--bottom-chrome-h) + var(--space-6))' in CalendarShell.tsx |
PASS |
grep "paddingBottom: 'var(--bottom-chrome-h)'" in App.tsx |
PASS |
grep 'New Event FAB does not overlap BottomTabBar' in layout.spec.ts |
PASS |
pnpm --filter @familysync/pwa build |
PASS |
| Playwright iphone + pixel layout.spec.ts (overlap assertion) | PASS — 32 passed, 2 skipped |
Full 3-profile pnpm --filter @familysync/pwa test:e2e |
PASS — 115 passed, 23 skipped, 0 failed |
| playwright-cli visual confirmation @390×844 | PASS — FAB above bar, legend chips visible |
| Desktop geometry unchanged | PASS — no desktop layout changes |
Deviations from Plan
None. Plan executed exactly as written. The three-task sequence (CSS fix, regression guard, sweep) was completed without any deviations. The FAB bottom value, phone contentStyle spread pattern, and overlap assertion all match the plan specification exactly.
Known Stubs
None. All changes are wired and fully functional.
Threat Flags
None. CSS-only layout offsets plus a Playwright geometry test — no new network endpoints, auth paths, or data flows introduced.
Self-Check: PASSED
| Item | Result |
|---|---|
| CalendarShell.tsx exists | FOUND |
| App.tsx exists | FOUND |
| layout.spec.ts exists | FOUND |
| SUMMARY.md exists | FOUND |
Commit 5e1c714 (Task 1) |
FOUND |
Commit 85a803f (Task 2) |
FOUND |
| CalendarShell FAB bottom grep | PASS |
| App.tsx paddingBottom grep | PASS |
| layout.spec.ts overlap assertion grep | PASS |