diff --git a/.planning/phases/02-mobile-shell-more-drawer/02-CONTEXT.md b/.planning/phases/02-mobile-shell-more-drawer/02-CONTEXT.md new file mode 100644 index 0000000..2debf89 --- /dev/null +++ b/.planning/phases/02-mobile-shell-more-drawer/02-CONTEXT.md @@ -0,0 +1,142 @@ +# Phase 02: Mobile Shell + More Drawer — Context + +**Gathered:** 2026-05-03 +**Status:** Ready for planning +**Source:** PRD Express Path (`docs/superpowers/specs/2026-05-03-mobile-shell-design.md`) + + +## Phase Boundary + +This phase delivers the new `/mobile/*` shell — the chrome that wraps every mobile page going forward. Specifically: + +1. A new `app/mobile/layout.tsx` with: sticky header (Wulf mark + Bell + avatar), scrollable content area, fixed bottom nav. +2. A 5-cell bottom nav: 4 primary tabs (Dashboard / Tickets / Finance / Analyzer) + a 5th "More" cell. +3. A shadcn `Sheet` drawer that fully replaces the standalone `/mobile/nav` page — opened from the More cell AND from the header avatar — with three sections (Mobile sections, Full site, Account). +4. Deletion of `app/mobile/nav/page.tsx` in the same change. + +The four primary tabs route to existing pages (Dashboard, Tickets, Finance) plus `/mobile/analyzer` which does NOT yet exist as a route — Phase 2 only adds the **nav entry**; Phase 6 builds the page itself. Until Phase 6, tapping Analyzer should land on a placeholder route or 404 — the planner should pick one and keep it consistent (recommend a minimal placeholder `app/mobile/analyzer/page.tsx` returning "Coming soon" so the bottom nav doesn't 404). + +**Out of this phase:** content of any mobile page (Dashboard restyle, Tickets restyle, etc.) — those are Phases 3–7. + + + + +## Implementation Decisions + +### Routes & files (locked) +- **Replace in place** — no `/mobile-v2`, no parallel routes. Edit `app/mobile/layout.tsx` directly. +- **Delete `app/mobile/nav/page.tsx`** as part of the drawer ship — same commit/PR as the new layout. +- **Add a placeholder `app/mobile/analyzer/page.tsx`** so the new bottom-nav Analyzer tab doesn't 404 before Phase 6 lands. Minimal "coming soon" component is sufficient. Mark this as deferred-cleanup in the plan so Phase 6 knows it owns the real page. +- All existing `/mobile/*` paths preserved (`/mobile/dashboard`, `/mobile/tickets`, `/mobile/tickets/[id]`, `/mobile/finance`, `/mobile/engagement` if it exists). + +### Header (`SHELL-02..04`) +- Sticky top, `bg-background/95 backdrop-blur`, bottom border. +- **Left slot:** Wulf mark logo (use the actual brand mark asset, NOT a text-only fallback) + "Pulse" wordmark. Linked to `/mobile/dashboard`. +- **Right slot order:** `Bell` icon button → compact `Avatar` (h-7 w-7). + - Bell: placeholder only — `aria-label="Notifications"`, empty `onClick`, keyboard-focusable. NO menu, NO badge logic, NO popover. Phase out-of-scope says "Real notification list behind the Bell icon — placeholder only this iteration". + - Avatar: tapping opens the More drawer (acts as second entry point; the bottom-bar More button is the first). +- **No page title in the header** — pages render their own H1. +- Honor `pt-safe` (or `pt-[env(safe-area-inset-top)]`) — Phase 1's `pt-safe` utility is available in `app/styles/brand.css`. + +### Content area (`SHELL-05`) +- `
` between header and bottom nav, scrollable. +- Bottom padding = bottom-nav height + safe-area inset, so content doesn't hide under the bar. Use `pb-safe` (Phase 1 utility) plus a fixed offset for the nav (e.g., `pb-[calc(theme(spacing.16)+env(safe-area-inset-bottom))]` or similar — pick a concrete value during planning). + +### Bottom nav (`SHELL-06`, `NAV-01..03`) +- Fixed, full-width, `border-t bg-background`, wrapped in `max-w-lg mx-auto` to share the gutter with content. +- 5 cells: 4 tabs + More. +- **Tabs** (in order, left to right): + + | Tab | Icon (lucide) | Route | + |------------|-------------------|---------------------| + | Dashboard | `LayoutDashboard` | `/mobile/dashboard` | + | Tickets | `Ticket` | `/mobile/tickets` | + | Finance | `DollarSign` | `/mobile/finance` | + | Analyzer | `Sparkles` | `/mobile/analyzer` | + +- Active state: `text-primary`. Inactive: `text-muted-foreground`. Active detection via `pathname.startsWith(href)`. +- **More cell** (5th): `Menu` icon labeled "More". Opens the Sheet drawer. + +### More drawer (`DRAWER-01..06`) +- shadcn `Sheet` component. **Pick `right` OR `bottom` and stay consistent** — recommend `right` for one-handed reachability with right-thumb users; planner can override. Document the choice in the plan. +- **Three sections, top-to-bottom:** + 1. **Mobile sections** — Engagement (`/mobile/engagement`). (No `ExternalLink` icon — it's an in-shell route.) + 2. **Full site** — link list to desktop-only pages, each with `ExternalLink` icon hint: + - Quotes + - Configuration Items + - Backup Status + - Ticket Digest + - Admin / Sync + 3. **Account** — current user (avatar + email, read-only display) and a Sign out action. + - Sign out: `signOut()` then `router.push('/auth/sign-in')`. Use the existing Better Auth `signOut` from `lib/auth-client.ts` (or wherever the client SDK exports it — planner verifies during build). +- **Replaces `/mobile/nav` page** — delete `app/mobile/nav/page.tsx`. Anyone navigating to `/mobile/nav` directly should not see the old standalone page; either redirect to `/mobile/dashboard` or rely on Next.js 404. Recommend NO redirect (just delete) — the URL was never bookmarked-worthy. + +### Existing infrastructure to consume +- **Auth/session:** `useSession()` from Better Auth client (existing). `lib/auth-client.ts`. +- **Theme tokens / Wulf brand:** `app/styles/brand.css` provides `--wulf-blue`, `pt-safe`, `pb-safe` (from Phase 1). +- **Brand assets:** `/public/branding/wulf-mark.png` (mark) and `/public/branding/wulf-wordmark.png` (wordmark) — used in header. +- **shadcn primitives:** `Sheet`, `Avatar`, `Button` are already in `components/ui/`. Verify before planning; if any are missing, planner adds via `npx shadcn add`. + +### Claude's Discretion +- Exact bottom-nav height (recommend `h-16` = 64px to match touch-target guidelines). +- Bottom nav micro-typography (label size, icon size) — keep consistent with existing mobile look. +- Animation/transition specifics for the Sheet (use shadcn defaults). +- Whether the avatar in the header is a real user image or initials fallback — use `Avatar` with `AvatarImage` + `AvatarFallback` (initials). Planner picks the source. +- File organization for the new shell components (e.g., `components/mobile/HeaderBar.tsx`, `components/mobile/BottomNav.tsx`, `components/mobile/MoreDrawer.tsx`) — encouraged for testability and Phase 3+ reuse, but not required by the spec. + + + + +## Canonical References + +**Downstream agents MUST read these before planning or implementing.** + +### Spec & roadmap (load-bearing — every decision derives from these) +- `docs/superpowers/specs/2026-05-03-mobile-shell-design.md` — full spec; §3 (Navigation) and §5 (Shell) are the primary scope of this phase. §3.2 (More drawer) is the secondary scope. §1, §2, §7 set goal/audience/non-goals. +- `.planning/ROADMAP.md` — Phase 2 entry with 6 success criteria. +- `.planning/REQUIREMENTS.md` — IDs SHELL-01..06, NAV-01..03, DRAWER-01..06 (15 total). + +### Project conventions +- `CLAUDE.md` — repo guide. Tailwind 4, shadcn/ui, no new state libs, no SWR/react-query, no Zod in API routes. +- `DESIGN.md` — design tokens, navigation IA, current cleanup backlog (read before touching shared UI). +- `ARCHITECTURE.md` — read if questions about data flow / runtime topology arise (not strictly needed for shell work). + +### Existing code to read or pattern-match against +- `app/mobile/layout.tsx` — current layout, replaced by this phase. Read to understand what's there before deleting. +- `app/mobile/nav/page.tsx` — current standalone nav page, replaced by drawer + deleted. +- `app/layout.tsx` — root layout, NOT modified by this phase. Already exports manifest + viewport from Phase 1. +- `app/styles/brand.css` — `pt-safe`, `pb-safe`, `--wulf-blue` available; new utilities can be added here if needed. +- `components/ui/sheet.tsx`, `components/ui/avatar.tsx`, `components/ui/button.tsx` — shadcn primitives. Planner reads these for prop signatures. +- `lib/auth-client.ts` — Better Auth client SDK. `signOut()` lives here. +- `components/navigation/app-navigation.tsx` — DESKTOP nav component. Reference only — DO NOT modify; this phase only touches `/mobile/*`. + + + + +## Specific Ideas + +- **Wulf mark + wordmark:** use `` + the wordmark image side-by-side; or rebuild as inline SVG if existing brand component is available. Planner verifies during build. +- **Sign-out flow:** `await signOut(); router.push('/auth/sign-in');` — single `onClick` handler on the Sign out button. Wrap in try/catch and toast on failure (sonner is the project's toast library). +- **Active tab detection:** `pathname.startsWith(href)` — handles nested routes (e.g., `/mobile/tickets/123` highlights Tickets). Edge case: `/mobile/dashboard` matches `/mobile/dashboard/anything` correctly; the four routes are non-overlapping prefixes so no special-case needed. +- **Drawer entry from header avatar:** lift the Sheet's `open` state to a layout-level state hook (or use a small Zustand-free pattern with React state + ref) so both the bottom-bar More button AND the avatar can trigger it. +- **Sheet side choice:** spec says "right or bottom — pick one and stay consistent". Recommend `right` (more natural for a settings-style menu). If `bottom`, ensure it doesn't conflict with the bottom nav bar visually. + + + + +## Deferred Ideas + +- **Real notification list behind the Bell** — explicitly out of scope (§7). Bell stays a placeholder. +- **Tablet breakpoint** (`md:max-w-2xl`) — explicitly deferred (§4, §7). Keep `max-w-lg`. +- **Service worker / offline** — explicitly out of scope across all phases (§4, §7). +- **Dashboard / Tickets / Finance / Analyzer / Engagement page restyles** — Phases 3–8. +- **`/mobile/analyzer` real page** — Phase 6. This phase only adds the nav entry + a placeholder page (or accepts the route 404s until Phase 6 — planner picks). +- **Theme toggle in drawer** — not in spec. Don't add. +- **Sign-out confirmation dialog** — not in spec. Single tap signs out. + + + +--- + +*Phase: 02-mobile-shell-more-drawer* +*Context gathered: 2026-05-03 via PRD Express Path (`docs/superpowers/specs/2026-05-03-mobile-shell-design.md`)*