diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index dfd2b79..042a5a5 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -24,10 +24,10 @@ Requirements for this milestone. Each maps to roadmap phases. ### Navigation & Layout -- [ ] **NAV-01**: Sidebar has a pastel background color distinct from the main content area -- [ ] **NAV-02**: Sidebar app name has a branded typographic treatment (not plain h2) -- [ ] **NAV-03**: Active navigation item has a clearly visible color indicator using sidebar-primary token -- [ ] **NAV-04**: Sidebar is collapsible via a toggle button for smaller screens +- [x] **NAV-01**: Sidebar has a pastel background color distinct from the main content area +- [x] **NAV-02**: Sidebar app name has a branded typographic treatment (not plain h2) +- [x] **NAV-03**: Active navigation item has a clearly visible color indicator using sidebar-primary token +- [x] **NAV-04**: Sidebar is collapsible via a toggle button for smaller screens ### Interaction Quality @@ -99,10 +99,10 @@ Which phases cover which requirements. Updated during roadmap creation. | AUTH-02 | Phase 2 | Complete | | AUTH-03 | Phase 2 | Complete | | AUTH-04 | Phase 2 | Complete | -| NAV-01 | Phase 2 | Pending | -| NAV-02 | Phase 2 | Pending | -| NAV-03 | Phase 2 | Pending | -| NAV-04 | Phase 2 | Pending | +| NAV-01 | Phase 2 | Complete | +| NAV-02 | Phase 2 | Complete | +| NAV-03 | Phase 2 | Complete | +| NAV-04 | Phase 2 | Complete | | IXTN-01 | Phase 3 | Pending | | IXTN-02 | Phase 3 | Pending | | IXTN-03 | Phase 3 | Pending | diff --git a/.planning/STATE.md b/.planning/STATE.md index b6a4d6d..70a6f7e 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -3,14 +3,14 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone status: planning -stopped_at: Completed 02-layout-and-brand-identity-02-01-PLAN.md -last_updated: "2026-03-11T20:50:06.093Z" +stopped_at: Completed 02-layout-and-brand-identity-02-02-PLAN.md +last_updated: "2026-03-11T20:50:28.392Z" last_activity: 2026-03-11 — Roadmap created from requirements and research progress: total_phases: 4 - completed_phases: 1 + completed_phases: 2 total_plans: 4 - completed_plans: 3 + completed_plans: 4 percent: 0 --- @@ -53,6 +53,7 @@ Progress: [░░░░░░░░░░] 0% | Phase 01-design-token-foundation P01 | 4 | 3 tasks | 6 files | | Phase 01-design-token-foundation P02 | 60 | 3 tasks | 8 files | | Phase 02-layout-and-brand-identity P01 | 8 | 2 tasks | 5 files | +| Phase 02-layout-and-brand-identity P02 | 2 | 2 tasks | 2 files | ## Accumulated Context @@ -72,6 +73,7 @@ Recent decisions affecting current work: - [Phase 01-design-token-foundation]: Chart Cell fills use palette[type].base keyed by categoryType — charts and card headers share the same color token - [Phase 02-layout-and-brand-identity]: Gradient background uses palette.saving/bill/investment light shades at 135deg for subtle tinted-paper feel on auth screens - [Phase 02-layout-and-brand-identity]: Alert destructive replaces plain error

— semantic role=alert improves a11y and enables test assertions +- [Phase 02-layout-and-brand-identity]: Gradient wordmark uses inline oklch style, active state overrides sidebar-primary, SidebarTrigger in SidebarInset header ### Pending Todos @@ -84,6 +86,6 @@ None yet. ## Session Continuity -Last session: 2026-03-11T20:50:06.091Z -Stopped at: Completed 02-layout-and-brand-identity-02-01-PLAN.md +Last session: 2026-03-11T20:50:28.391Z +Stopped at: Completed 02-layout-and-brand-identity-02-02-PLAN.md Resume file: None diff --git a/.planning/phases/02-layout-and-brand-identity/02-layout-and-brand-identity-02-02-SUMMARY.md b/.planning/phases/02-layout-and-brand-identity/02-layout-and-brand-identity-02-02-SUMMARY.md new file mode 100644 index 0000000..b531256 --- /dev/null +++ b/.planning/phases/02-layout-and-brand-identity/02-layout-and-brand-identity-02-02-SUMMARY.md @@ -0,0 +1,119 @@ +--- +phase: 02-layout-and-brand-identity +plan: 02 +subsystem: ui +tags: [react, sidebar, shadcn, tailwind, oklch, branding] + +# Dependency graph +requires: + - phase: 01-design-token-foundation + provides: oklch pastel CSS tokens including --sidebar, --sidebar-primary, --sidebar-primary-foreground, --primary +provides: + - Branded AppLayout sidebar with gradient wordmark (oklch 260-300 purple sweep) + - Visible active nav indicator using sidebar-primary (oklch 0.50 vs 0.97 contrast) + - SidebarTrigger collapse button in SidebarInset header bar + - Unit tests for all four NAV requirements +affects: [03-data-display, 04-settings-and-polish] + +# Tech tracking +tech-stack: + added: [] + patterns: + - "Gradient text via WebkitBackgroundClip+WebkitTextFillColor with oklch inline style" + - "SidebarMenuButton className override for active state — no edits to ui/sidebar.tsx" + - "SidebarTrigger placed inside SidebarInset (not Sidebar) for safe useSidebar() hook access" + - "matchMedia mock required in tests that render SidebarProvider" + +key-files: + created: + - frontend/src/components/AppLayout.test.tsx + modified: + - frontend/src/components/AppLayout.tsx + +key-decisions: + - "Gradient wordmark uses inline style (not Tailwind) because oklch values are not Tailwind classes" + - "Active indicator uses sidebar-primary token directly via className override — avoids invisible sidebar-accent default (only 4 lightness points difference)" + - "SidebarTrigger lives in SidebarInset header, not in Sidebar, so useSidebar() context is always available" + +patterns-established: + - "Pattern 1: Sidebar customization via className props only — never edit src/components/ui/sidebar.tsx" + - "Pattern 2: Test files for SidebarProvider-dependent components must mock both ResizeObserver and window.matchMedia" + +requirements-completed: [NAV-01, NAV-02, NAV-03, NAV-04] + +# Metrics +duration: 2min +completed: 2026-03-11 +--- + +# Phase 02 Plan 02: Layout and Brand Identity — Sidebar Polish Summary + +**Gradient wordmark, sidebar-primary active indicator, and SidebarTrigger collapse button added to AppLayout via className overrides and inline oklch styles** + +## Performance + +- **Duration:** 2 min +- **Started:** 2026-03-11T20:47:21Z +- **Completed:** 2026-03-11T20:49:30Z +- **Tasks:** 2 +- **Files modified:** 2 + +## Accomplishments + +- Created AppLayout.test.tsx with 4 passing tests covering NAV-01 through NAV-04 +- Replaced plain h2 app name with gradient span wordmark using oklch(260) to oklch(300) purple-to-pink sweep +- Overrode SidebarMenuButton active className to use sidebar-primary token for high-contrast active indicator +- Added SidebarTrigger collapse button in a header bar within SidebarInset +- All 35 tests pass, production build succeeds + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Create AppLayout test scaffold** - `9b57a1a` (test) +2. **Task 2: Brand sidebar with wordmark, active indicator, and collapse trigger** - `79a0f9b` (feat) + +## Files Created/Modified + +- `frontend/src/components/AppLayout.test.tsx` - Unit tests for NAV-01 through NAV-04 (sidebar renders, wordmark, active state, trigger button) +- `frontend/src/components/AppLayout.tsx` - SidebarTrigger import, gradient wordmark span, active className override, header bar with trigger + +## Decisions Made + +- Gradient wordmark uses inline style with WebkitBackgroundClip rather than a Tailwind class because the oklch values aren't available as utility classes +- Active state uses `data-[active=true]:bg-sidebar-primary` override to replace the nearly-invisible default `bg-sidebar-accent` (only 4 lightness points from sidebar background) +- SidebarTrigger is placed inside SidebarInset header (not inside the Sidebar component) so the `useSidebar()` hook always has access to SidebarProvider context + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 3 - Blocking] Added window.matchMedia mock to test file** +- **Found during:** Task 1 (AppLayout test scaffold) +- **Issue:** SidebarProvider's `use-mobile` hook calls `window.matchMedia()` which is not defined in jsdom test environment, causing all 4 tests to error +- **Fix:** Added `Object.defineProperty(window, 'matchMedia', ...)` mock using `vi.fn()` at the top of the test file +- **Files modified:** frontend/src/components/AppLayout.test.tsx +- **Verification:** Tests run successfully after adding mock +- **Committed in:** 9b57a1a (Task 1 commit) + +--- + +**Total deviations:** 1 auto-fixed (1 blocking) +**Impact on plan:** Necessary for test environment compatibility. No scope creep. + +## Issues Encountered + +The linter reverted early Edit tool changes to AppLayout.tsx before they could be saved atomically — resolved by reading the file again and writing the complete file content in a single Write operation. + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness + +- AppLayout sidebar is fully branded and functional — every authenticated page now has the gradient wordmark, visible active indicator, and collapse toggle +- Ready for Phase 3 data display work which renders inside the `

` container added in this plan + +--- +*Phase: 02-layout-and-brand-identity* +*Completed: 2026-03-11*