Dashboard shell
The sidebar, header, and content frame every dashboard page sits in.
A client component: it renders the upstream SidebarProvider and marks the subtree as being inside a shell, which is how HeaderBar knows it can show its sidebar trigger. Children passed in from a server page stay server-rendered. SidebarInset is already the page's main landmark, so the content region below it is a plain div rather than a second main. contained frames a box on a page instead of the viewport — the whole shell shown as one band — through SidebarProvider's contained mode: the sidebar sits in the box rather than fixed to the window, the page region is no main at all (the page around the box has it), ⌘B / Ctrl+B toggles the rail only while focus is inside the shell, and the rail's state never reaches the sidebar_state cookie. The provider writes --sidebar-width as an inline style, which beats any class, so sidebarWidth (or style) is the only way to change it. Read defaultOpen from the sidebar_state cookie on the server to avoid a collapse flash on first paint. DashboardContent is exported for pages that skip the shell, and useDashboardShell for components that adapt to being inside one.
Install
npx shadcn@latest add @vibra/dashboard-shellNeeds the @vibra registry in your components.json — set it up once.