feat(02-02): brand sidebar with wordmark, active indicator, and collapse trigger

- Add SidebarTrigger import (NAV-04)
- Replace plain h2 with gradient span wordmark using oklch 260-300 purple sweep (NAV-02)
- Override SidebarMenuButton active state with sidebar-primary for high contrast (NAV-03)
- Add header bar with SidebarTrigger inside SidebarInset (NAV-04)
- Add p-4 padding to main content area
- NAV-01 satisfied by existing bg-sidebar token on sidebar element
This commit is contained in:
2026-03-11 21:49:29 +01:00
parent 381a06008b
commit 79a0f9bc3d

View File

@@ -13,6 +13,7 @@ import {
SidebarMenuItem, SidebarMenuItem,
SidebarProvider, SidebarProvider,
SidebarInset, SidebarInset,
SidebarTrigger,
} from '@/components/ui/sidebar' } from '@/components/ui/sidebar'
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import type { AuthContext } from '@/hooks/useAuth' import type { AuthContext } from '@/hooks/useAuth'
@@ -36,7 +37,18 @@ export function AppLayout({ auth, children }: Props) {
<SidebarProvider> <SidebarProvider>
<Sidebar> <Sidebar>
<SidebarHeader className="border-b px-4 py-3"> <SidebarHeader className="border-b px-4 py-3">
<h2 className="text-lg font-semibold">{t('app.title')}</h2> <span
data-testid="sidebar-wordmark"
className="text-base font-semibold tracking-wide"
style={{
background: `linear-gradient(to right, oklch(0.50 0.12 260), oklch(0.50 0.12 300))`,
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
backgroundClip: 'text',
}}
>
{t('app.title')}
</span>
{auth.user && ( {auth.user && (
<p className="text-sm text-muted-foreground">{auth.user.display_name}</p> <p className="text-sm text-muted-foreground">{auth.user.display_name}</p>
)} )}
@@ -47,7 +59,11 @@ export function AppLayout({ auth, children }: Props) {
<SidebarMenu> <SidebarMenu>
{navItems.map((item) => ( {navItems.map((item) => (
<SidebarMenuItem key={item.path}> <SidebarMenuItem key={item.path}>
<SidebarMenuButton asChild isActive={location.pathname === item.path}> <SidebarMenuButton
asChild
isActive={location.pathname === item.path}
className="data-[active=true]:bg-sidebar-primary data-[active=true]:text-sidebar-primary-foreground"
>
<Link to={item.path}> <Link to={item.path}>
<item.icon /> <item.icon />
<span>{item.label}</span> <span>{item.label}</span>
@@ -67,7 +83,10 @@ export function AppLayout({ auth, children }: Props) {
</SidebarFooter> </SidebarFooter>
</Sidebar> </Sidebar>
<SidebarInset> <SidebarInset>
<main className="flex-1">{children}</main> <header className="flex h-12 shrink-0 items-center gap-2 border-b px-4">
<SidebarTrigger className="-ml-1" />
</header>
<main className="flex-1 p-4">{children}</main>
</SidebarInset> </SidebarInset>
</SidebarProvider> </SidebarProvider>
) )