Layout primitives
Semantic page structure for consumer apps: shells, sections, stacks, clusters, grids, splits, and main content wrappers.
PageShell + Section
/layout/page-shell/Start pages with a dark shell and a semantic section instead of hand-writing page backgrounds and spacing. The inner content wrapper is always flex flex-col flex-1 — add className='flex flex-col min-h-screen' to the shell and the flex chain works: header stays top, footer sticks bottom. Use contentClassName to add extra classes to the inner wrapper.
PageShellProps| Prop | Type |
|---|---|
as? | 'div' | 'main' |
background? | PageShellBackground |
density? | PageShellDensity |
contentClassName? | string |
Build with components first.
Use Tailwind only for small local glue in consumer apps.
Stack + Cluster
/layout/stack-cluster/Use Stack for vertical rhythm and Cluster for wrapping action rows, chips, toolbars, and nav groups.
StackProps| Prop | Type |
|---|---|
as? | 'div' | 'section' | 'article' | 'header' | 'footer' | 'nav' |
gap? | StackGap |
align? | StackAlign |
Production guardrails
Every action is logged and reversible.
Grid + CardGrid
/layout/grid-cardgrid/Use Grid for generic responsive tracks and CardGrid for card collections with Tollerud spacing defaults.
GridProps| Prop | Type |
|---|---|
as? | 'div' | 'section' |
columns? | GridColumns |
gap? | GridGap |
systemctl status tollerud-agentdocker compose psScrollRail
/layout/scroll-rail/Horizontal scroll rail for card rows, image strips, and overflow content. Use `visibleCount` when N items should fill the row and the rest scroll (achievement rails, product rows). Use `itemWidth` for fixed-pixel cards. Continuous scroll with peek (only when overflowing), edge fades (default on), and optional controls.
ScrollRailProps| Prop | Type |
|---|---|
as? | 'div' | 'section' |
peek? | ScrollRailPeek |
gap? | ScrollRailGap |
controls? | ScrollRailControls |
fadeEdges? | boolean |
ariaLabel? | string |
itemWidth? | number | string |
visibleCount? | number |
trackClassName? | string |
Split + MainContent
/layout/split-maincontent/Use Split for content/aside pages and MainContent for app routes that need consistent width, padding, and density.
SplitProps| Prop | Type |
|---|---|
as? | 'div' | 'section' |
ratio? | SplitRatio |
gap? | SplitGap |
align? | SplitAlign |
reverse? | boolean |
Primary content
A wider column for tables, forms, or detail content.
Aside
A narrower panel for metadata, actions, or status.