Navigation
The WS Connect navigation system — left sidebar, top bar, icon rail, and global search — working together to orient users across the product.
Left Navigation
The primary wayfinding panel for WS Connect. It sits on the left edge of the viewport, shows the full site hierarchy, and supports expandable sub-groups.
<div class="ws-leftnav">
<div class="ws-leftnav__header">
<div class="ws-leftnav__logo-mark">WS</div>
<div>
<span class="ws-leftnav__brand">Connect</span>
<span class="ws-leftnav__brand-sub">Woodruff Sawyer</span>
</div>
</div>
<div class="ws-leftnav__menu">
<div class="ws-leftnav__group">
<div class="ws-leftnav__group-label">Workspace</div>
<!-- Active leaf item -->
<a href="/dashboard" class="ws-leftnav__item is-active">
<svg>…</svg>
Dashboard
</a>
<!-- Expandable group (aria-expanded toggles chevron + children) -->
<button class="ws-leftnav__item" aria-expanded="true"
data-leftnav-toggle="clients-sub">
<svg>…</svg> Clients
<svg class="ws-leftnav__chevron">…</svg>
</button>
<div class="ws-leftnav__children" id="clients-sub">
<a href="#" class="ws-leftnav__child is-active">Acme Manufacturing</a>
<a href="#" class="ws-leftnav__child">Bright Horizons LLC</a>
</div>
</div>
</div>
<div class="ws-leftnav__footer">
<div class="ws-avatar ws-avatar--sm">JD</div>
<div class="ws-leftnav__footer-text">
<strong>Jane Doe</strong> Account Manager
</div>
</div>
</div>Anatomy
WS mark + "Connect" wordmark + product sub-label. Always links back to home.
Uppercase, muted — groups related items (Workspace, Settings, etc.).
16px icon + label. Active state: green-tinted background with a 2px green right-edge border.
A <button> with a trailing chevron. aria-expanded and data-leftnav-toggle drive the open/close behavior.
Indented children rendered inside .ws-leftnav__children. Add .is-collapsed to hide them.
Avatar + name + role. Pinned to bottom with a subtle top border.
Clicking an expandable toggle sets aria-expanded and removes .is-collapsed from its children container. Only one group can be expanded at a time on mobile viewports.
Top Navigation Bar
A dark navy strip fixed to the top of each product page. Houses the brand logo, page breadcrumb, contextual tab strip, quick-action icons, and the user avatar.
With tab strip
<div class="ws-topnav">
<div class="ws-topnav__logo">
<div class="ws-topnav__logo-mark">WS</div>
<span class="ws-topnav__logo-name">Connect</span>
</div>
<!-- Tab strip (add .is-active to current tab) -->
<div class="ws-topnav__tabs">
<button class="ws-topnav__tab is-active">Overview</button>
<button class="ws-topnav__tab">Coverage</button>
<button class="ws-topnav__tab">Documents</button>
</div>
<div class="ws-topnav__actions">
<button class="ws-topnav__btn" aria-label="Search"><svg>…</svg></button>
<button class="ws-topnav__btn" aria-label="Notifications"><svg>…</svg></button>
<div class="ws-topnav__sep"></div>
<div class="ws-avatar ws-avatar--sm">JD</div>
</div>
</div>With breadcrumb trail
<div class="ws-topnav">
<div class="ws-topnav__logo">…</div>
<!-- Breadcrumb variant (replaces tab strip) -->
<nav class="ws-topnav__breadcrumb" aria-label="Breadcrumb">
<a href="/clients">Clients</a>
<span class="sep">/</span>
<a href="/clients/acme">Acme Manufacturing Co.</a>
<span class="sep">/</span>
<span class="current">Policy WS-2026-004471</span>
</nav>
<div class="ws-topnav__actions">
<button class="ws-topnav__btn" aria-label="Save"><svg>…</svg></button>
<div class="ws-topnav__sep"></div>
<div class="ws-avatar ws-avatar--sm">JD</div>
</div>
</div>Anatomy
WS mark + "Connect" label, separated from the center zone by a faint vertical rule.
Use .ws-topnav__tabs for entity-level pages (policy detail, client profile). Switch to .ws-topnav__breadcrumb for deep-link context pages.
Icon-only 34×34 px targets. Use sparingly — max 4 icons before the avatar separator.
Initials avatar that opens a profile/logout dropdown. Always rightmost.
Left Navigation Rail
A compact 56 px icon-only rail used when the full left nav is collapsed. It gives persistent access to primary sections while preserving maximum workspace width.
<div class="ws-nav-rail">
<div class="ws-nav-rail__logo">WS</div>
<!-- Primary nav items — add is-active to current section -->
<button class="ws-nav-rail__item is-active" title="Dashboard"><svg>…</svg></button>
<button class="ws-nav-rail__item" title="Clients"><svg>…</svg></button>
<button class="ws-nav-rail__item" title="Policies"><svg>…</svg></button>
<div class="ws-nav-rail__divider"></div>
<div class="ws-nav-rail__footer">
<button class="ws-nav-rail__item" title="Settings"><svg>…</svg></button>
<div class="ws-avatar ws-avatar--xs">JD</div>
</div>
</div>Anatomy
36 × 36 px WS mark. Tapping it collapses or expands the full left nav.
40 × 40 px icon buttons. Active state: translucent green fill. The title attribute renders as a browser tooltip on hover — add a custom tooltip component for richer labels.
Faint horizontal rule followed by settings and the user avatar. Always pushed to the bottom via margin-top: auto on .ws-nav-rail__footer.
Behaviors
- Hover state — icon buttons gain a subtle white-tint background and the native
titletooltip appears. - Active state — translucent green fill (
.is-active) indicates the currently selected primary section. - Expand to full nav — clicking the logo or a dedicated expand button slides in the full
.ws-leftnavpanel; the rail hides or collapses behind it. - Sub-menu flyout — on hover, items with children can show a secondary panel flyout to the right of the rail (pattern handled at the app layout level).
Navigation Search
Global search accessible from the top nav bar. Surfaces clients, policies, documents, and contacts with categorized, type-ahead results.
Trigger in top bar
<button class="ws-nav-search__trigger" id="searchTrigger">
<svg>…search icon…</svg>
<span class="ws-nav-search__trigger-text">Search clients, policies, docs…</span>
<kbd class="ws-nav-search__kbd">⌘K</kbd>
</button>Search panel with results
<div class="ws-nav-search">
<div class="ws-nav-search__panel">
<!-- Input row -->
<div class="ws-nav-search__input-row">
<svg>…</svg>
<input type="text" placeholder="Search clients, policies, documents…" />
</div>
<!-- Category filter chips -->
<div class="ws-nav-search__cats">
<button class="ws-nav-search__cat is-active">All</button>
<button class="ws-nav-search__cat">Clients</button>
<button class="ws-nav-search__cat">Policies</button>
<button class="ws-nav-search__cat">Documents</button>
</div>
<!-- Results list -->
<div class="ws-nav-search__results">
<div class="ws-nav-search__section-label">Clients</div>
<div class="ws-nav-search__result">
<div class="ws-nav-search__result-icon ws-nav-search__result-icon--client">AM</div>
<div class="ws-nav-search__result-body">
<div class="ws-nav-search__result-name">Acme Manufacturing Co.</div>
<div class="ws-nav-search__result-meta">Client · 14 active policies</div>
</div>
</div>
<!-- More results… -->
</div>
</div>
</div>Anatomy
Ghost button styled to look like an input. Shows placeholder text and the keyboard shortcut badge (⌘K / Ctrl+K). Clicking opens the search panel as a floating overlay or modal.
Full-width text input with leading search icon. Focus is auto-set when the panel opens.
Pill buttons: All / Clients / Policies / Documents. Active pill is green-tinted. Filtering narrows the results list without a network round-trip where possible.
Grouped by entity type with a muted uppercase section label. Each result row: 30 × 30 px type icon, primary name, secondary metadata line. Keyboard-navigable with arrow keys.
⌘K / Ctrl+K opens the panel. ↑ ↓ navigate results. Enter selects. Esc closes. Tab cycles through category filters.
Breadcrumbs
Inline breadcrumbs appear both inside .ws-topnav__breadcrumb and on content pages to show hierarchy position.
<nav class="ws-breadcrumb" aria-label="Breadcrumb">
<a href="/clients">Clients</a><span class="sep">/</span>
<a href="/clients/acme">Acme Manufacturing Co.</a><span class="sep">/</span>
<span class="current">Policy WS-2026-004471</span>
</nav>Pagination
Used on table and list views to navigate between pages of results.
<div class="ws-pagination">
<button aria-label="Previous page" disabled>‹</button>
<button class="is-active">1</button>
<button>2</button>
<button>3</button>
<span>…</span>
<button>12</button>
<button aria-label="Next page">›</button>
</div>