feat(fase-5.12): detail-view chrome — hide MobileTopBar, sticky contextual headers

On /lists/[id], /tasks/[id], /notes/[id], /lists/[id]/session the global
MobileTopBar (hamburger + collective + avatar) is hidden on mobile. The
route's own contextual header (back + title + actions) becomes the only
top chrome and is now sticky with glassmorphism, matching the look of
the MobileTopBar it replaces. BottomTabBar stays visible so the user can
still hop between sections.

Detection: a regex over the path — /^\/(lists\/[uuid](\/session)?|
tasks\/[uuid]|notes\/[uuid])\/?$/ — in (app)/+layout.svelte.

Headers touched:
  - apps/web/src/routes/(app)/lists/[id]/+page.svelte (px-4 on mobile,
    px-8 on md+, transparent/no-border on md+ since the masthead
    provides its own spacing)
  - apps/web/src/routes/(app)/tasks/[id]/+page.svelte
  - apps/web/src/routes/(app)/notes/[id]/+page.svelte

Tests
  tests/e2e/mobile-shell.test.ts gains M-08: on /lists/bbbb..., the
  mobile-hamburger element has count 0 (MobileTopBar removed) while the
  detail's back link + BottomTabBar remain visible. All 5 shell tests
  green.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-13 19:02:06 +02:00
parent d6cea5146f
commit 4cc5f694d3
5 changed files with 29 additions and 5 deletions

View File

@@ -54,4 +54,15 @@ test.describe('Mobile shell — layout switches at md breakpoint', () => {
await expect(page.getByTestId('desktop-sidebar')).toBeVisible({ timeout: 10_000 });
await expect(page.getByTestId('bottom-tab-bar')).toBeHidden();
});
test('M-08: on a detail route the MobileTopBar is hidden but BottomTabBar stays', async ({ page }) => {
await page.setViewportSize(MOBILE);
await loginAs(page, USERS.borja);
await page.goto('/lists/bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb');
// The global hamburger lives inside MobileTopBar — absence == hidden.
await expect(page.getByTestId('mobile-hamburger')).toHaveCount(0, { timeout: 5_000 });
// The detail view still shows a back link + bottom tab bar.
await expect(page.getByRole('link', { name: /^back$/i }).first()).toBeVisible();
await expect(page.getByTestId('bottom-tab-bar')).toBeVisible();
});
});