App shell
Top app bar, collapsible sidebar navigation, and a scrolling content region — the chrome every prototype app starts from. esa-app-bar sets the brand color context, esa-sidebar-nav carries the navigation as data, and everything below the chrome is just page content.
Live demo
The miniature below is Estuary, an invented site-and-permit monitoring app for an environmental consulting team. It is the real composition, just framed at a fixed height: use the chevrons at the top of the sidebar to collapse it to an icon rail, expand Reports to see accordion children, and scroll the content region — the chrome never moves.
Dashboard
Active permits
Across 14 monitored sites
- Shoreline stabilization — Carquinez Strait Active
- Eelgrass restoration — Tomales Bay Renewal due
- Maintenance dredging — Mare Island In review
Upcoming field visits
Next two weeks
- Jun 16 Sediment sampling — Suisun Marsh
- Jun 19 Avian nesting survey — Hamilton Wetlands
- Jun 24 Water quality — Petaluma River mouth
Composition notes
- Two flex passes make the frame. A column lays the bar over the body; a row lays the nav beside the content. Only
.shell-contentscrolls (flex: 1+min-height: 0+overflow-y: auto) — in a spoke the shell runsheight: 100vh; here it's 440px to frame the miniature. - The bar brands itself from tokens.
tone="brand"sets background and currentColor from--color-primary/--color-text-inverse; the wordmark, icon buttons, and user menu trigger all inherit. A spoke re-brands the whole bar by re-pointing--color-primaryin its theme file — never by touching the component. - The sidebar re-skins through its component tokens.
--sidebar-width,--sidenav-bg,--sidenav-link-text-active, and friends are set on the shell wrapper and inherit through the shadow boundary — that's exactly how this demo narrows the rail to 248px. - Navigation is data, not markup.
esa-sidebar-navtakesitemsas a JS array property (not an attribute): groups, badges, accordion children, and the active flag all live in the array, so a spoke swaps its whole nav by swapping data. - Page content owns everything below the chrome. The scrolling region is plain composition space — here a page head plus
esa-card/esa-badgelegos. The shell makes no assumptions about what goes inside it.