Page header with tabs
The top of a record page: breadcrumb, title with a favourite star and summary chips, two actions, and an underline tab bar with counts that scrolls on its own when narrow.
It is live: hover, focus and its own controls respond. Actions that would change data (approve, send, delete) are for your app to wire. The width is a real 390 px, 768 px or 1280 px box, shrunk to fit your screen.
<style>
/* The rail uses the recessed surface, not --ds-color-surface-nav: some systems paint that one in the brand colour, and these items are written for dark text on a light surface. */
.odl-sidebar-nav { box-sizing: border-box; inline-size: 100%; max-inline-size: 17.5rem; margin-inline: auto; display: flex; flex-direction: column; gap: var(--ds-space-stack-md); padding: var(--ds-space-inset-sm);
background: var(--ds-color-surface-sunken); color: var(--ds-color-text-primary); border-inline-end: var(--ds-border-width-default) solid var(--ds-color-border-subtle);
font: var(--ds-text-body-md); text-wrap: pretty; container-type: inline-size; }
.odl-sidebar-nav *, .odl-sidebar-nav *::before { box-sizing: border-box; }
.odl-sidebar-nav svg { flex: none; inline-size: var(--ds-size-icon-sm); block-size: var(--ds-size-icon-sm); }
.odl-sidebar-nav button, .odl-sidebar-nav a, .odl-sidebar-nav summary { color: inherit; font: inherit; text-decoration: none; cursor: pointer;
transition: background-color var(--ds-motion-duration-short) var(--ds-motion-easing-standard); }
.odl-sidebar-nav button:focus-visible, .odl-sidebar-nav a:focus-visible, .odl-sidebar-nav summary:focus-visible {
outline: var(--ds-focus-ring-width) solid var(--ds-color-border-focus); outline-offset: var(--ds-focus-ring-offset); }
.odl-sidebar-nav .odl-switcher { display: flex; align-items: center; gap: var(--ds-space-inline-sm); inline-size: 100%; min-block-size: var(--ds-size-target-min);
padding: 0 var(--ds-space-inset-xs); border: 0; border-radius: var(--ds-radius-control); background: transparent; text-align: start; }
.odl-sidebar-nav .odl-switcher:hover { background: var(--ds-color-bg-neutral-subtle-hover); }
.odl-sidebar-nav .odl-mark { flex: none; display: grid; place-items: center; inline-size: var(--ds-size-control-sm); block-size: var(--ds-size-control-sm);
border-radius: var(--ds-radius-control-sm); background: var(--ds-color-bg-inverse); color: var(--ds-color-text-inverse); font: var(--ds-text-label-md); font-weight: var(--ds-font-weight-heading); }
.odl-sidebar-nav .odl-ws { flex: 1; min-inline-size: 0; display: grid; }
.odl-sidebar-nav .odl-ws strong { font: var(--ds-text-label-lg); font-weight: var(--ds-font-weight-heading); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.odl-sidebar-nav .odl-ws small { color: var(--ds-color-text-tertiary); font: var(--ds-text-body-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.odl-sidebar-nav .odl-switcher > svg { color: var(--ds-color-icon-subtle); }
.odl-sidebar-nav .odl-search { display: flex; align-items: center; gap: var(--ds-space-inline-sm); inline-size: 100%; min-block-size: var(--ds-size-target-min);
padding: 0 var(--ds-space-inset-xs) 0 var(--ds-space-inset-sm); border: var(--ds-border-width-default) solid var(--ds-color-border-subtle); border-radius: var(--ds-radius-control);
background: var(--ds-color-surface-raised); color: var(--ds-color-text-tertiary); text-align: start; }
.odl-sidebar-nav .odl-search:hover { border-color: var(--ds-color-border-default); }
.odl-sidebar-nav .odl-search span { flex: 1; }
.odl-sidebar-nav kbd { display: inline-grid; place-items: center; min-inline-size: var(--ds-space-20); padding: 0 var(--ds-space-4); border: var(--ds-border-width-default) solid var(--ds-color-border-subtle);
border-radius: var(--ds-radius-detail); background: var(--ds-color-surface-base); color: var(--ds-color-text-secondary); font: var(--ds-text-code-sm); }
.odl-sidebar-nav nav { display: grid; gap: var(--ds-space-stack-md); }
.odl-sidebar-nav ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--ds-space-2); }
.odl-sidebar-nav .odl-heading { margin: 0; padding: 0 var(--ds-space-inset-sm) var(--ds-space-4); color: var(--ds-color-text-tertiary); font: var(--ds-text-label-md); letter-spacing: var(--ds-text-label-md-tracking); }
.odl-sidebar-nav .odl-item { display: flex; align-items: center; gap: var(--ds-space-inline-sm); min-block-size: var(--ds-size-target-min); padding: 0 var(--ds-space-inset-sm);
border-radius: var(--ds-radius-control); color: var(--ds-color-text-secondary); }
.odl-sidebar-nav .odl-item svg { color: var(--ds-color-icon-subtle); }
.odl-sidebar-nav .odl-item .odl-label { flex: 1; min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.odl-sidebar-nav .odl-item:hover { background: var(--ds-color-bg-neutral-subtle-hover); color: var(--ds-color-text-primary); }
.odl-sidebar-nav .odl-item[aria-current="page"] { background: var(--ds-color-surface-raised); color: var(--ds-color-text-primary); font-weight: var(--ds-font-weight-label);
box-shadow: inset 0 0 0 var(--ds-border-width-default) var(--ds-color-border-subtle); }
.odl-sidebar-nav .odl-item[aria-current="page"] svg { color: var(--ds-color-icon-accent); }
.odl-sidebar-nav .odl-count { flex: none; color: var(--ds-color-text-tertiary); font: var(--ds-text-label-md); font-variant-numeric: tabular-nums; }
.odl-sidebar-nav .odl-count.is-new { min-inline-size: var(--ds-space-20); padding: 0 var(--ds-space-6); border-radius: var(--ds-radius-full); text-align: center;
background: var(--ds-color-bg-accent-subtle); color: var(--ds-color-text-accent); }
.odl-sidebar-nav details > summary { list-style: none; display: flex; align-items: center; justify-content: space-between; gap: var(--ds-space-inline-xs);
min-block-size: var(--ds-size-target-min); padding: 0 var(--ds-space-inset-sm); border-radius: var(--ds-radius-control); color: var(--ds-color-text-tertiary);
font: var(--ds-text-label-md); letter-spacing: var(--ds-text-label-md-tracking); }
.odl-sidebar-nav details > summary::-webkit-details-marker { display: none; }
.odl-sidebar-nav details > summary:hover { background: var(--ds-color-bg-neutral-subtle-hover); color: var(--ds-color-text-secondary); }
.odl-sidebar-nav details > summary svg { transition: transform var(--ds-motion-duration-short) var(--ds-motion-easing-standard); }
.odl-sidebar-nav details[open] > summary svg { transform: rotate(90deg); }
.odl-sidebar-nav .odl-person { display: flex; align-items: center; gap: var(--ds-space-inline-sm); margin-block-start: var(--ds-space-stack-sm); padding: var(--ds-space-inset-xs);
min-block-size: var(--ds-size-target-min); border: 0; border-block-start: var(--ds-border-width-default) solid var(--ds-color-border-subtle); border-radius: 0; background: transparent; inline-size: 100%; text-align: start; }
.odl-sidebar-nav .odl-person:hover { background: var(--ds-color-bg-neutral-subtle-hover); }
.odl-sidebar-nav .odl-avatar { flex: none; position: relative; display: grid; place-items: center; inline-size: var(--ds-size-control-sm); block-size: var(--ds-size-control-sm);
border-radius: var(--ds-radius-person); background: var(--ds-color-bg-accent-subtle); color: var(--ds-color-text-accent); font: var(--ds-text-label-sm); font-weight: var(--ds-font-weight-heading); }
.odl-sidebar-nav .odl-avatar::after { content: ""; position: absolute; inset-block-end: calc(-1 * var(--ds-space-2)); inset-inline-end: calc(-1 * var(--ds-space-2));
inline-size: var(--ds-space-8); block-size: var(--ds-space-8); border-radius: var(--ds-radius-full); background: var(--ds-color-bg-success-bold);
box-shadow: 0 0 0 var(--ds-border-width-emphasis) var(--ds-color-surface-sunken); }
.odl-sidebar-nav .odl-person > svg { color: var(--ds-color-icon-subtle); }
@media (prefers-reduced-motion: reduce) { .odl-sidebar-nav, .odl-sidebar-nav *, .odl-sidebar-nav *::before { transition: none !important; animation: none !important; } }
</style>
<aside class="odl-sidebar-nav" aria-label="Sidebar">
<button type="button" class="odl-switcher" aria-haspopup="menu" aria-label="Switch workspace, current: Thistlecombe Foods">
<span class="odl-mark" aria-hidden="true">B</span>
<span class="odl-ws"><strong>Thistlecombe Foods</strong><small>Business · 38 members</small></span>
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="m5 6 3-3 3 3M5 10l3 3 3-3"/></svg>
</button>
<button type="button" class="odl-search" aria-keyshortcuts="Meta+K">
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><circle cx="7" cy="7" r="4.5"/><path d="m10.5 10.5 3 3"/></svg>
<span>Search</span><kbd>⌘</kbd><kbd>K</kbd>
</button>
<nav aria-label="Main">
<ul>
<li><a class="odl-item" href="#home"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M2.5 7 8 2.5 13.5 7v6.5h-4V10h-3v3.5h-4z"/></svg><span class="odl-label">Home</span></a></li>
<li><a class="odl-item" href="#inbox"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M2.5 9.5 4 3.5h8l1.5 6v3h-11z"/><path d="M2.5 9.5h3.25l.75 1.5h3l.75-1.5h3.25"/></svg><span class="odl-label">Inbox</span><span class="odl-count is-new" aria-label="3 unread">3</span></a></li>
</ul>
<div>
<p class="odl-heading" id="odl-sn-payables">Payables</p>
<ul aria-labelledby="odl-sn-payables">
<li><a class="odl-item" href="#bills" aria-current="page"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M4 1.5h5.5L12 4v10.5H4z"/><path d="M6 7h4M6 9.5h4M6 12h2"/></svg><span class="odl-label">Bills</span><span class="odl-count" aria-label="14 to approve">14</span></a></li>
<li><a class="odl-item" href="#payments"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M2.5 8h10M9 4.5 12.5 8 9 11.5"/></svg><span class="odl-label">Payments</span><span class="odl-count" aria-label="22 scheduled">22</span></a></li>
<li><a class="odl-item" href="#vendors"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M2.5 6.5 3.5 3h9l1 3.5M3 6.5v7h10v-7"/><path d="M2.5 6.5c0 1 .8 1.5 1.8 1.5S6 7.5 6 6.5c0 1 .9 1.5 2 1.5s2-.5 2-1.5c0 1 .7 1.5 1.7 1.5s1.8-.5 1.8-1.5"/></svg><span class="odl-label">Vendors</span></a></li>
<li><a class="odl-item" href="#reimbursements"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M4 1.5h8v13l-2-1.25-2 1.25-2-1.25-2 1.25z"/><path d="M6.5 5.5h3M6.5 8h3"/></svg><span class="odl-label">Reimbursements</span><span class="odl-count" aria-label="5 waiting">5</span></a></li>
</ul>
</div>
<div>
<p class="odl-heading" id="odl-sn-spend">Spend</p>
<ul aria-labelledby="odl-sn-spend">
<li><a class="odl-item" href="#cards"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><rect x="1.5" y="3.5" width="13" height="9" rx="1.5"/><path d="M1.5 6.5h13M4 10h3"/></svg><span class="odl-label">Cards</span><span class="odl-count" aria-label="11 cards">11</span></a></li>
<li><a class="odl-item" href="#budgets"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><circle cx="8" cy="8" r="6"/><path d="M8 2v6h6"/></svg><span class="odl-label">Budgets</span></a></li>
</ul>
</div>
<details open>
<summary><span>Books</span><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="m6 4 4 4-4 4"/></svg></summary>
<ul>
<li><a class="odl-item" href="#accounting"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M3 2.5h8.5a1 1 0 0 1 1 1v10H4a1 1 0 0 1-1-1z"/><path d="M3 11.5h9.5"/></svg><span class="odl-label">Accounting</span></a></li>
<li><a class="odl-item" href="#policies"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><path d="M8 2v12M4.5 14h7M2.5 5h11"/><path d="m2.5 5-1.5 4a1.5 1.5 0 0 0 3 0zM13.5 5 12 9a1.5 1.5 0 0 0 3 0z"/></svg><span class="odl-label">Approval policies</span></a></li>
</ul>
</details>
</nav>
<button type="button" class="odl-person" aria-haspopup="menu">
<span class="odl-avatar" aria-hidden="true">KA</span>
<span class="odl-ws"><strong>Kwabena Asante</strong><small>Controller · online</small></span>
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true"><circle cx="3.5" cy="8" r=".75"/><circle cx="8" cy="8" r=".75"/><circle cx="12.5" cy="8" r=".75"/></svg>
</button>
</aside>
The top of a record page: breadcrumb, title with a favourite star and summary chips, two actions, and an underline tab bar with counts that scrolls on its own when narrow.
The footer under a long table: how many rows are showing, rows per page, and previous, next and page numbers that collapse to "Page 3 of 49" when narrow.
A search-first menu for every action and page, grouped, with keyboard shortcuts, live filtering and an empty result that says what to try.