--- phase: 02-layout-and-brand-identity plan: 02 type: execute wave: 1 depends_on: [] files_modified: - frontend/src/components/AppLayout.tsx - frontend/src/components/AppLayout.test.tsx autonomous: true requirements: [NAV-01, NAV-02, NAV-03, NAV-04] must_haves: truths: - "Sidebar has a visually distinct pastel background from the main content area" - "Sidebar app name displays as a branded gradient text wordmark" - "Clicking a nav item produces a clearly visible active state indicator" - "A toggle button exists to collapse/expand the sidebar" artifacts: - path: "frontend/src/components/AppLayout.tsx" provides: "Branded sidebar with wordmark, active indicator, collapse trigger" contains: "SidebarTrigger" - path: "frontend/src/components/AppLayout.test.tsx" provides: "Unit tests for NAV-01 through NAV-04" key_links: - from: "frontend/src/components/AppLayout.tsx" to: "frontend/src/components/ui/sidebar.tsx" via: "SidebarTrigger import for collapse toggle" pattern: "SidebarTrigger" - from: "frontend/src/components/AppLayout.tsx" to: "SidebarMenuButton isActive" via: "data-active styling override for visible indicator" pattern: "data-\\[active=true\\]" --- Polish the sidebar shell -- branded wordmark, visible active nav indicator, and collapse toggle -- so every authenticated page load feels intentionally designed. Purpose: The sidebar is visible on every page after login. Its polish directly determines the perceived quality of the entire app. Output: Updated AppLayout.tsx with branded sidebar and passing unit tests. @/home/jean-luc-makiola/.claude/get-shit-done/workflows/execute-plan.md @/home/jean-luc-makiola/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/02-layout-and-brand-identity/02-RESEARCH.md @.planning/phases/02-layout-and-brand-identity/02-VALIDATION.md @frontend/src/components/AppLayout.tsx From frontend/src/components/AppLayout.tsx: ```typescript interface Props { auth: AuthContext children: React.ReactNode } // Uses: useTranslation, useLocation from react-router-dom // Imports from ui/sidebar: Sidebar, SidebarContent, SidebarFooter, SidebarGroup, // SidebarGroupContent, SidebarHeader, SidebarMenu, SidebarMenuButton, // SidebarMenuItem, SidebarProvider, SidebarInset // NOTE: SidebarTrigger is NOT currently imported // Current app name:

{t('app.title')}

// Current active state: isActive={location.pathname === item.path} (no className override) // Current SidebarInset:
{children}
(no header bar) ``` From frontend/src/index.css (sidebar token values): ```css --sidebar: oklch(0.97 0.012 280); /* light lavender background */ --sidebar-primary: oklch(0.50 0.12 260); /* strong accent for active state */ --sidebar-primary-foreground: oklch(0.99 0.005 290); --sidebar-accent: oklch(0.93 0.020 280); /* 4-point lightness diff from sidebar - may be too subtle */ --primary: oklch(0.50 0.12 260); /* for wordmark gradient start */ ``` From frontend/src/components/ui/sidebar.tsx (already exported): ```typescript export { SidebarTrigger } // renders PanelLeftIcon button, calls toggleSidebar() ```
Task 1: Create AppLayout test scaffold frontend/src/components/AppLayout.test.tsx Create `frontend/src/components/AppLayout.test.tsx` with test cases for all four NAV requirements. Test setup: - Mock `react-i18next`: `vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (key: string) => key }) }))` - Mock `react-router-dom`: `vi.mock('react-router-dom', () => ({ Link: ({ children, to, ...props }: any) => {children}, useLocation: () => ({ pathname: '/' }) }))` - Create mock auth: `{ user: { display_name: 'Test' }, loading: false, login: vi.fn(), register: vi.fn(), logout: vi.fn(), token: 'test' } as unknown as AuthContext` - Render with: `render(
content
)` Note: SidebarProvider uses ResizeObserver internally. Add to test file top: ```typescript // Mock ResizeObserver for sidebar tests globalThis.ResizeObserver = class { observe() {} unobserve() {} disconnect() {} } as any ``` Test cases: - NAV-01: The sidebar element renders (verify `