8 CSS Navbar Designs04 / 08

CSS + JSMIT licensed

Vertical CSS Sidebar Navigation

A GitHub-dark-inspired collapsible sidebar navbar UI for a SaaS dashboard — proving that the canonical 240px ↔ 64px sidebar collapse pattern can carry a complete information density. Sidebar with gradient hex logo, a circular collapse-toggle button that rotates 180° on click, a workspace selector card (Acme Corp / Pro Plan), three nav sections (Overview / Workspace / System) with mono-uppercase labels and colour-coded badges (Live green, "12" blue, "2" orange, "3" red), and a bottom user row with gradient avatar. On collapse the entire 240px width animates to 64px — every label, badge, and the workspace info smoothly fade out — and tooltips appear on hover via a `data-label` attribute. The main pane carries a sticky topbar (breadcrumb / ⌘K search / notifications dot / command icon) and the actual dashboard content: 4-up stat cards (Revenue $84.2k +12.4%, Active Users 4,291, Deployments 138 −3.2%, Uptime 99.97%) plus a 14-bar Request Volume chart + Recent Activity feed. IBM Plex Sans + IBM Plex Mono. Best for SaaS admin panels, developer tools, internal dashboards, analytics platforms, B2B product chrome.

Published Updated

Live Demo
Try it

This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.

The code

<section class="nb-sdb" aria-label="hexlane collapsible sidebar demo">
  <aside data-nb-sdb-sidebar aria-label="Primary">
    <div class="sidebar-logo">
      <div class="logo-icon" aria-hidden="true">⬡</div>
      <span class="logo-text">hexlane<span class="logo-dot">.</span>io</span>
    </div>

    <div class="workspace">
      <div class="ws-avatar">A</div>
      <div class="ws-info">
        <div class="ws-name">Acme Corp</div>
        <div class="ws-plan">Pro Plan</div>
      </div>
      <span class="ws-chevron" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="6 9 12 15 18 9"/></svg></span>
    </div>

    <nav class="sidebar-nav" aria-label="Sections">
      <div class="nav-section">
        <div class="nav-section-label">Overview</div>
        <a href="#" class="nav-item active" data-label="Dashboard">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg></span>
          <span class="nav-label">Dashboard</span>
        </a>
        <a href="#" class="nav-item" data-label="Analytics">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg></span>
          <span class="nav-label">Analytics</span>
          <span class="nav-badge badge-green">Live</span>
        </a>
        <a href="#" class="nav-item" data-label="Reports">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14,2 14,8 20,8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg></span>
          <span class="nav-label">Reports</span>
        </a>
      </div>

      <div class="nav-section">
        <div class="nav-section-label">Workspace</div>
        <a href="#" class="nav-item" data-label="Projects">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><polygon points="12,2 2,7 12,12 22,7"/><polyline points="2,17 12,22 22,17"/><polyline points="2,12 12,17 22,12"/></svg></span>
          <span class="nav-label">Projects</span>
          <span class="nav-badge badge-blue">12</span>
        </a>
        <a href="#" class="nav-item" data-label="Team">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg></span>
          <span class="nav-label">Team</span>
        </a>
        <a href="#" class="nav-item" data-label="Deployments">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><polyline points="22,12 18,12 15,21 9,3 6,12 2,12"/></svg></span>
          <span class="nav-label">Deployments</span>
          <span class="nav-badge badge-orange">2</span>
        </a>
        <a href="#" class="nav-item" data-label="Logs">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg></span>
          <span class="nav-label">Logs</span>
        </a>
      </div>

      <div class="nav-section">
        <div class="nav-section-label">System</div>
        <a href="#" class="nav-item" data-label="Alerts">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg></span>
          <span class="nav-label">Alerts</span>
          <span class="nav-badge badge-red">3</span>
        </a>
        <a href="#" class="nav-item" data-label="Settings">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg></span>
          <span class="nav-label">Settings</span>
        </a>
        <a href="#" class="nav-item" data-label="Docs">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg></span>
          <span class="nav-label">Docs</span>
        </a>
      </div>
    </nav>

    <div class="sidebar-foot">
      <div class="user-row">
        <div class="user-avatar">JL</div>
        <div class="user-info">
          <div class="user-name">Jordan Lee</div>
          <div class="user-handle">admin · Acme Corp</div>
        </div>
        <span class="user-menu-btn" aria-hidden="true"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="5" r="1"/><circle cx="12" cy="12" r="1"/><circle cx="12" cy="19" r="1"/></svg></span>
      </div>
    </div>
  </aside>

  <button class="collapse-btn" type="button" data-nb-sdb-toggle aria-label="Toggle sidebar" aria-expanded="true">
    <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><polyline points="15 18 9 12 15 6"/></svg>
  </button>

  <div class="main">
    <div class="topbar">
      <div class="breadcrumb">
        <span>hexlane</span>
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>
        <span>Acme Corp</span>
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>
        <strong>Dashboard</strong>
      </div>
      <div class="topbar-spacer"></div>
      <div class="topbar-search">
        <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
        Search...
        <span class="search-shortcut">⌘K</span>
      </div>
      <div class="topbar-actions">
        <button class="topbar-icon" type="button" aria-label="Notifications">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
          <span class="notif-dot" aria-hidden="true"></span>
        </button>
        <button class="topbar-icon" type="button" aria-label="Command palette">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></svg>
        </button>
      </div>
    </div>

    <div class="content">
      <h1 class="page-title">Overview</h1>
      <p class="page-desc">Your workspace at a glance — updated just now</p>

      <div class="stats-row">
        <div class="stat-card">
          <div class="stat-label">Monthly Revenue</div>
          <div class="stat-value">$84.2k</div>
          <div class="stat-change up"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><polyline points="18 15 12 9 6 15"/></svg> +12.4%</div>
        </div>
        <div class="stat-card">
          <div class="stat-label">Active Users</div>
          <div class="stat-value">4,291</div>
          <div class="stat-change up"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><polyline points="18 15 12 9 6 15"/></svg> +8.1%</div>
        </div>
        <div class="stat-card">
          <div class="stat-label">Deployments</div>
          <div class="stat-value">138</div>
          <div class="stat-change down"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg> −3.2%</div>
        </div>
        <div class="stat-card">
          <div class="stat-label">Uptime SLA</div>
          <div class="stat-value">99.97%</div>
          <div class="stat-change up"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><polyline points="18 15 12 9 6 15"/></svg> Stable</div>
        </div>
      </div>

      <div class="chart-area">
        <div class="chart-card">
          <div class="chart-title">Request Volume</div>
          <div class="chart-sub">Last 14 days — hover over bars</div>
          <div class="chart-bars" aria-hidden="true">
            <div class="bar bh-45"></div><div class="bar bh-60"></div><div class="bar bh-40"></div><div class="bar bh-70"></div><div class="bar bh-55"></div><div class="bar bh-80"></div><div class="bar active bh-90"></div><div class="bar bh-65"></div><div class="bar bh-75"></div><div class="bar bh-50"></div><div class="bar bh-85"></div><div class="bar bh-70"></div><div class="bar bh-95"></div><div class="bar bh-78"></div>
          </div>
        </div>
        <div class="chart-card">
          <div class="chart-title">Recent Activity</div>
          <div class="chart-sub">Live feed</div>
          <div class="activity-list">
            <div class="activity-item">
              <div class="activity-dot dot-green" aria-hidden="true"></div>
              <div class="activity-text"><strong>Deploy succeeded</strong> — production v2.4.1</div>
              <div class="activity-time">2m ago</div>
            </div>
            <div class="activity-item">
              <div class="activity-dot dot-blue" aria-hidden="true"></div>
              <div class="activity-text"><strong>Jordan Lee</strong> updated API keys</div>
              <div class="activity-time">14m</div>
            </div>
            <div class="activity-item">
              <div class="activity-dot dot-orange" aria-hidden="true"></div>
              <div class="activity-text"><strong>Alert triggered</strong> — latency spike</div>
              <div class="activity-time">1h</div>
            </div>
            <div class="activity-item">
              <div class="activity-dot dot-red" aria-hidden="true"></div>
              <div class="activity-text"><strong>Build failed</strong> — staging branch</div>
              <div class="activity-time">2h</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>
/* ─── 04 hexlane — collapsible sidebar dashboard navbar UI ─────── */

@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap');

.nb-sdb {
  --nb-sdb-sidebar-w: 240px;
  --nb-sdb-sidebar-collapsed: 64px;
  --nb-sdb-bg: #0d1117;
  --nb-sdb-surface: #161b22;
  --nb-sdb-surface-2: #21262d;
  --nb-sdb-border: #30363d;
  --nb-sdb-text: #e6edf3;
  --nb-sdb-text-muted: #7d8590;
  --nb-sdb-text-dim: #484f58;
  --nb-sdb-accent: #58a6ff;
  --nb-sdb-accent-green: #3fb950;
  --nb-sdb-accent-orange: #d29922;
  --nb-sdb-accent-red: #f85149;
  --nb-sdb-accent-purple: #bc8cff;
  --nb-sdb-transition: 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  width: 100%;
  min-height: 720px;
  background: var(--nb-sdb-bg);
  color: var(--nb-sdb-text);
  font-family: 'IBM Plex Sans', sans-serif;
  display: flex;
  overflow: hidden;
  box-sizing: border-box;
}

.nb-sdb *,
.nb-sdb *::before,
.nb-sdb *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.nb-sdb aside {
  width: var(--nb-sdb-sidebar-w);
  background: var(--nb-sdb-surface);
  border-right: 1px solid var(--nb-sdb-border);
  display: flex;
  flex-direction: column;
  transition: width var(--nb-sdb-transition);
  position: relative;
  z-index: 50;
  overflow: hidden;
  flex-shrink: 0;
}

.nb-sdb aside.collapsed {
  width: var(--nb-sdb-sidebar-collapsed);
}

.nb-sdb .sidebar-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 16px;
  height: 56px;
  border-bottom: 1px solid var(--nb-sdb-border);
  flex-shrink: 0;
  overflow: hidden;
  white-space: nowrap;
}

.nb-sdb .logo-icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: linear-gradient(135deg, var(--nb-sdb-accent), var(--nb-sdb-accent-purple));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  flex-shrink: 0;
  box-shadow: 0 2px 12px rgba(88,166,255,0.3);
  color: #fff;
}

.nb-sdb .logo-text {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--nb-sdb-text);
  transition: opacity var(--nb-sdb-transition), width var(--nb-sdb-transition);
  overflow: hidden;
}

.nb-sdb .logo-dot {
  color: var(--nb-sdb-accent);
}

.nb-sdb aside.collapsed .logo-text {
  opacity: 0;
  width: 0;
}
/* Collapse toggle sits at the sidebar's outer edge. Lifted out of
   <aside> so aside's overflow:hidden (which clips the fading labels)
   doesn't also clip this button. Positioned absolute against the
   wrapper; its left coord tracks the sidebar width via :has(). */

.nb-sdb .collapse-btn {
  position: absolute;
  top: 68px;
  left: calc(var(--nb-sdb-sidebar-w) - 12px);
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--nb-sdb-surface-2);
  border: 1px solid var(--nb-sdb-border);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--nb-sdb-text-muted);
  transition: background 0.15s, color 0.15s, left var(--nb-sdb-transition);
  z-index: 60;
}

.nb-sdb:has(aside.collapsed) .collapse-btn {
  left: calc(var(--nb-sdb-sidebar-collapsed) - 12px);
}

.nb-sdb .collapse-btn:hover {
  background: var(--nb-sdb-accent);
  color: #fff;
  border-color: var(--nb-sdb-accent);
}

.nb-sdb .collapse-btn svg {
  transition: transform var(--nb-sdb-transition);
}

.nb-sdb:has(aside.collapsed) .collapse-btn svg {
  transform: rotate(180deg);
}

.nb-sdb .workspace {
  margin: 12px 10px;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid var(--nb-sdb-border);
  background: var(--nb-sdb-surface-2);
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
  overflow: hidden;
  white-space: nowrap;
  flex-shrink: 0;
}

.nb-sdb .workspace:hover {
  border-color: var(--nb-sdb-accent);
  background: rgba(88,166,255,0.05);
}

.nb-sdb .ws-avatar {
  width: 24px;
  height: 24px;
  border-radius: 6px;
  background: linear-gradient(135deg, #3fb950, #1f6feb);
  flex-shrink: 0;
  font-size: 0.6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 600;
}

.nb-sdb .ws-info {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  transition: opacity var(--nb-sdb-transition), width var(--nb-sdb-transition);
}

.nb-sdb aside.collapsed .ws-info {
  opacity: 0;
  width: 0;
}

.nb-sdb .ws-name {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--nb-sdb-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.nb-sdb .ws-plan {
  font-size: 0.6rem;
  color: var(--nb-sdb-text-muted);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.nb-sdb .ws-chevron {
  color: var(--nb-sdb-text-dim);
  flex-shrink: 0;
  transition: opacity var(--nb-sdb-transition);
}

.nb-sdb aside.collapsed .ws-chevron {
  opacity: 0;
}

.nb-sdb .sidebar-nav {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 8px 0;
  scrollbar-width: thin;
  scrollbar-color: var(--nb-sdb-border) transparent;
}

.nb-sdb .sidebar-nav::-webkit-scrollbar {
  width: 4px;
}

.nb-sdb .sidebar-nav::-webkit-scrollbar-thumb {
  background: var(--nb-sdb-border);
  border-radius: 2px;
}

.nb-sdb .nav-section {
  margin-bottom: 4px;
}

.nb-sdb .nav-section-label {
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--nb-sdb-text-dim);
  padding: 8px 20px 4px;
  white-space: nowrap;
  overflow: hidden;
  transition: opacity var(--nb-sdb-transition);
}

.nb-sdb aside.collapsed .nav-section-label {
  opacity: 0;
}

.nb-sdb .nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px 7px 16px;
  margin: 1px 8px;
  border-radius: 8px;
  font-size: 0.82rem;
  font-weight: 400;
  color: var(--nb-sdb-text-muted);
  text-decoration: none;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
  white-space: nowrap;
  overflow: hidden;
  user-select: none;
}

.nb-sdb .nav-item:hover {
  background: var(--nb-sdb-surface-2);
  color: var(--nb-sdb-text);
}

.nb-sdb .nav-item.active {
  background: rgba(88,166,255,0.1);
  color: var(--nb-sdb-accent);
}

.nb-sdb .nav-item.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 20%;
  bottom: 20%;
  width: 3px;
  border-radius: 0 2px 2px 0;
  background: var(--nb-sdb-accent);
}

.nb-sdb .nav-icon {
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  opacity: 0.8;
}

.nb-sdb .nav-item.active .nav-icon,
.nb-sdb .nav-item:hover .nav-icon {
  opacity: 1;
}

.nb-sdb .nav-label {
  transition: opacity var(--nb-sdb-transition), width var(--nb-sdb-transition);
  overflow: hidden;
}

.nb-sdb aside.collapsed .nav-label {
  opacity: 0;
  width: 0;
}

.nb-sdb .nav-badge {
  margin-left: auto;
  flex-shrink: 0;
  font-size: 0.6rem;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 100px;
  transition: opacity var(--nb-sdb-transition);
}

.nb-sdb aside.collapsed .nav-badge {
  opacity: 0;
}

.nb-sdb .badge-blue {
  background: rgba(88,166,255,0.15);
  color: var(--nb-sdb-accent);
}

.nb-sdb .badge-green {
  background: rgba(63,185,80,0.15);
  color: var(--nb-sdb-accent-green);
}

.nb-sdb .badge-orange {
  background: rgba(210,153,34,0.15);
  color: var(--nb-sdb-accent-orange);
}

.nb-sdb .badge-red {
  background: rgba(248,81,73,0.15);
  color: var(--nb-sdb-accent-red);
}

.nb-sdb aside.collapsed .nav-item::after {
  content: attr(data-label);
  position: absolute;
  left: calc(var(--nb-sdb-sidebar-collapsed) - 8px);
  top: 50%;
  transform: translateY(-50%);
  background: var(--nb-sdb-surface-2);
  color: var(--nb-sdb-text);
  font-size: 0.75rem;
  padding: 5px 10px;
  border-radius: 6px;
  border: 1px solid var(--nb-sdb-border);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s;
  z-index: 100;
  box-shadow: 0 4px 16px rgba(0,0,0,0.4);
}

.nb-sdb aside.collapsed .nav-item:hover::after {
  opacity: 1;
}

.nb-sdb .sidebar-foot {
  border-top: 1px solid var(--nb-sdb-border);
  padding: 10px;
  flex-shrink: 0;
  overflow: hidden;
}

.nb-sdb .user-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 6px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.12s;
  white-space: nowrap;
  overflow: hidden;
}

.nb-sdb .user-row:hover {
  background: var(--nb-sdb-surface-2);
}

.nb-sdb .user-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--nb-sdb-accent-purple), var(--nb-sdb-accent));
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  font-weight: 600;
  color: #fff;
}

.nb-sdb .user-info {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  transition: opacity var(--nb-sdb-transition), width var(--nb-sdb-transition);
}

.nb-sdb aside.collapsed .user-info {
  opacity: 0;
  width: 0;
}

.nb-sdb .user-name {
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--nb-sdb-text);
  overflow: hidden;
  text-overflow: ellipsis;
}

.nb-sdb .user-handle {
  font-size: 0.65rem;
  color: var(--nb-sdb-text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
}

.nb-sdb .user-menu-btn {
  color: var(--nb-sdb-text-dim);
  flex-shrink: 0;
  transition: opacity var(--nb-sdb-transition);
}

.nb-sdb aside.collapsed .user-menu-btn {
  opacity: 0;
}

.nb-sdb .main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 720px;
}

.nb-sdb .topbar {
  height: 56px;
  border-bottom: 1px solid var(--nb-sdb-border);
  display: flex;
  align-items: center;
  padding: 0 24px;
  gap: 16px;
  background: var(--nb-sdb-surface);
  flex-shrink: 0;
}

.nb-sdb .breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.72rem;
  color: var(--nb-sdb-text-muted);
}

.nb-sdb .breadcrumb span {
  color: var(--nb-sdb-text-dim);
}

.nb-sdb .breadcrumb strong {
  color: var(--nb-sdb-text);
  font-weight: 500;
}

.nb-sdb .topbar-spacer {
  flex: 1;
}

.nb-sdb .topbar-search {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--nb-sdb-bg);
  border: 1px solid var(--nb-sdb-border);
  border-radius: 8px;
  padding: 6px 12px;
  color: var(--nb-sdb-text-muted);
  font-size: 0.75rem;
  cursor: pointer;
  transition: border-color 0.15s;
}

.nb-sdb .topbar-search:hover {
  border-color: var(--nb-sdb-text-dim);
}

.nb-sdb .search-shortcut {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.6rem;
  background: var(--nb-sdb-surface-2);
  border: 1px solid var(--nb-sdb-border);
  border-radius: 4px;
  padding: 1px 5px;
  color: var(--nb-sdb-text-dim);
  margin-left: 24px;
}

.nb-sdb .topbar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.nb-sdb .topbar-icon {
  width: 32px;
  height: 32px;
  border-radius: 6px;
  border: 1px solid var(--nb-sdb-border);
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--nb-sdb-text-muted);
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
  position: relative;
}

.nb-sdb .topbar-icon:hover {
  background: var(--nb-sdb-surface-2);
  color: var(--nb-sdb-text);
}

.nb-sdb .notif-dot {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--nb-sdb-accent-red);
  border: 1.5px solid var(--nb-sdb-surface);
}

.nb-sdb .content {
  padding: 28px;
  flex: 1;
}

.nb-sdb .page-title {
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--nb-sdb-text);
  margin-bottom: 4px;
}

.nb-sdb .page-desc {
  font-size: 0.82rem;
  color: var(--nb-sdb-text-muted);
  margin-bottom: 24px;
}

.nb-sdb .stats-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}

.nb-sdb .stat-card {
  background: var(--nb-sdb-surface);
  border: 1px solid var(--nb-sdb-border);
  border-radius: 12px;
  padding: 18px 20px;
  transition: border-color 0.15s;
}

.nb-sdb .stat-card:hover {
  border-color: var(--nb-sdb-text-dim);
}

.nb-sdb .stat-label {
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--nb-sdb-text-muted);
  margin-bottom: 10px;
}

.nb-sdb .stat-value {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 1.6rem;
  font-weight: 500;
  color: var(--nb-sdb-text);
  line-height: 1;
  margin-bottom: 8px;
}

.nb-sdb .stat-change {
  font-size: 0.72rem;
  display: flex;
  align-items: center;
  gap: 4px;
}

.nb-sdb .up {
  color: var(--nb-sdb-accent-green);
}

.nb-sdb .down {
  color: var(--nb-sdb-accent-red);
}

.nb-sdb .chart-area {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 16px;
}

.nb-sdb .chart-card {
  background: var(--nb-sdb-surface);
  border: 1px solid var(--nb-sdb-border);
  border-radius: 12px;
  padding: 20px;
}

.nb-sdb .chart-title {
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--nb-sdb-text);
  margin-bottom: 4px;
}

.nb-sdb .chart-sub {
  font-size: 0.72rem;
  color: var(--nb-sdb-text-muted);
  margin-bottom: 16px;
}

.nb-sdb .chart-bars {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 100px;
}

.nb-sdb .bar {
  flex: 1;
  border-radius: 4px 4px 0 0;
  background: rgba(88,166,255,0.15);
  border: 1px solid rgba(88,166,255,0.2);
  transition: background 0.15s;
}

.nb-sdb .bar:hover {
  background: rgba(88,166,255,0.35);
}

.nb-sdb .bar.active {
  background: rgba(88,166,255,0.6);
  border-color: var(--nb-sdb-accent);
}

.nb-sdb .bh-40 {
  height: 40%;
}

.nb-sdb .bh-45 {
  height: 45%;
}

.nb-sdb .bh-50 {
  height: 50%;
}

.nb-sdb .bh-55 {
  height: 55%;
}

.nb-sdb .bh-60 {
  height: 60%;
}

.nb-sdb .bh-65 {
  height: 65%;
}

.nb-sdb .bh-70 {
  height: 70%;
}

.nb-sdb .bh-75 {
  height: 75%;
}

.nb-sdb .bh-78 {
  height: 78%;
}

.nb-sdb .bh-80 {
  height: 80%;
}

.nb-sdb .bh-85 {
  height: 85%;
}

.nb-sdb .bh-90 {
  height: 90%;
}

.nb-sdb .bh-95 {
  height: 95%;
}

.nb-sdb .activity-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.nb-sdb .activity-item {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.nb-sdb .activity-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  margin-top: 4px;
}

.nb-sdb .dot-green {
  background: var(--nb-sdb-accent-green);
}

.nb-sdb .dot-blue {
  background: var(--nb-sdb-accent);
}

.nb-sdb .dot-orange {
  background: var(--nb-sdb-accent-orange);
}

.nb-sdb .dot-red {
  background: var(--nb-sdb-accent-red);
}

.nb-sdb .activity-text {
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--nb-sdb-text-muted);
}

.nb-sdb .activity-text strong {
  color: var(--nb-sdb-text);
}

.nb-sdb .activity-time {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.65rem;
  color: var(--nb-sdb-text-dim);
  margin-left: auto;
  flex-shrink: 0;
}

@media (max-width: 1024px) {
  .nb-sdb .stats-row {
    grid-template-columns: repeat(2, 1fr);
  }

  .nb-sdb .chart-area {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 640px) {
  .nb-sdb .stats-row {
    grid-template-columns: 1fr;
  }

  .nb-sdb .search-shortcut {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .nb-sdb aside,
    .nb-sdb .nav-label,
    .nb-sdb .ws-info,
    .nb-sdb .user-info,
    .nb-sdb .collapse-btn svg {
    transition: none !important;
  }
}
(() => {
  // Scoped collapsible-sidebar wiring. State lives on the wrapper, so
  // two instances of this demo on one page can each collapse
  // independently.
  const root = document.querySelector('.nb-sdb');
  if (!root) return;
  const sidebar = root.querySelector('[data-nb-sdb-sidebar]');
  const toggle = root.querySelector('[data-nb-sdb-toggle]');
  if (!sidebar || !toggle) return;

  toggle.addEventListener('click', () => {
    const collapsed = sidebar.classList.toggle('collapsed');
    toggle.setAttribute('aria-expanded', !collapsed);
  });

  // Click to set the active nav item, scoped to this sidebar.
  sidebar.querySelectorAll('.nav-item').forEach((item) => {
    item.addEventListener('click', (e) => {
      e.preventDefault();
      sidebar.querySelectorAll('.nav-item').forEach((i) => i.classList.remove('active'));
      item.classList.add('active');
    });
  });
})();
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Navbar Design from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Vertical CSS Sidebar Navigation
Source: https://codefronts.com/navigation/css-navbars/vertical-css-sidebar-navigation/

A GitHub-dark-inspired collapsible sidebar navbar UI for a SaaS dashboard — proving that the canonical 240px ↔ 64px sidebar collapse pattern can carry a complete information density. Sidebar with gradient hex logo, a circular collapse-toggle button that rotates 180° on click, a workspace selector card (Acme Corp / Pro Plan), three nav sections (Overview / Workspace / System) with mono-uppercase labels and colour-coded badges (Live green, "12" blue, "2" orange, "3" red), and a bottom user row with gradient avatar. On collapse the entire 240px width animates to 64px — every label, badge, and the workspace info smoothly fade out — and tooltips appear on hover via a `data-label` attribute. The main pane carries a sticky topbar (breadcrumb / ⌘K search / notifications dot / command icon) and the actual dashboard content: 4-up stat cards (Revenue $84.2k +12.4%, Active Users 4,291, Deployments 138 −3.2%, Uptime 99.97%) plus a 14-bar Request Volume chart + Recent Activity feed. IBM Plex Sans + IBM Plex Mono. Best for SaaS admin panels, developer tools, internal dashboards, analytics platforms, B2B product chrome.
## HTML
```html
<section class="nb-sdb" aria-label="hexlane collapsible sidebar demo">
  <aside data-nb-sdb-sidebar aria-label="Primary">
    <div class="sidebar-logo">
      <div class="logo-icon" aria-hidden="true">⬡</div>
      <span class="logo-text">hexlane<span class="logo-dot">.</span>io</span>
    </div>

    <div class="workspace">
      <div class="ws-avatar">A</div>
      <div class="ws-info">
        <div class="ws-name">Acme Corp</div>
        <div class="ws-plan">Pro Plan</div>
      </div>
      <span class="ws-chevron" aria-hidden="true"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="6 9 12 15 18 9"/></svg></span>
    </div>

    <nav class="sidebar-nav" aria-label="Sections">
      <div class="nav-section">
        <div class="nav-section-label">Overview</div>
        <a href="#" class="nav-item active" data-label="Dashboard">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg></span>
          <span class="nav-label">Dashboard</span>
        </a>
        <a href="#" class="nav-item" data-label="Analytics">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><line x1="18" y1="20" x2="18" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="6" y1="20" x2="6" y2="14"/></svg></span>
          <span class="nav-label">Analytics</span>
          <span class="nav-badge badge-green">Live</span>
        </a>
        <a href="#" class="nav-item" data-label="Reports">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14,2 14,8 20,8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/></svg></span>
          <span class="nav-label">Reports</span>
        </a>
      </div>

      <div class="nav-section">
        <div class="nav-section-label">Workspace</div>
        <a href="#" class="nav-item" data-label="Projects">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><polygon points="12,2 2,7 12,12 22,7"/><polyline points="2,17 12,22 22,17"/><polyline points="2,12 12,17 22,12"/></svg></span>
          <span class="nav-label">Projects</span>
          <span class="nav-badge badge-blue">12</span>
        </a>
        <a href="#" class="nav-item" data-label="Team">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg></span>
          <span class="nav-label">Team</span>
        </a>
        <a href="#" class="nav-item" data-label="Deployments">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><polyline points="22,12 18,12 15,21 9,3 6,12 2,12"/></svg></span>
          <span class="nav-label">Deployments</span>
          <span class="nav-badge badge-orange">2</span>
        </a>
        <a href="#" class="nav-item" data-label="Logs">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg></span>
          <span class="nav-label">Logs</span>
        </a>
      </div>

      <div class="nav-section">
        <div class="nav-section-label">System</div>
        <a href="#" class="nav-item" data-label="Alerts">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg></span>
          <span class="nav-label">Alerts</span>
          <span class="nav-badge badge-red">3</span>
        </a>
        <a href="#" class="nav-item" data-label="Settings">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg></span>
          <span class="nav-label">Settings</span>
        </a>
        <a href="#" class="nav-item" data-label="Docs">
          <span class="nav-icon" aria-hidden="true"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg></span>
          <span class="nav-label">Docs</span>
        </a>
      </div>
    </nav>

    <div class="sidebar-foot">
      <div class="user-row">
        <div class="user-avatar">JL</div>
        <div class="user-info">
          <div class="user-name">Jordan Lee</div>
          <div class="user-handle">admin · Acme Corp</div>
        </div>
        <span class="user-menu-btn" aria-hidden="true"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="5" r="1"/><circle cx="12" cy="12" r="1"/><circle cx="12" cy="19" r="1"/></svg></span>
      </div>
    </div>
  </aside>

  <button class="collapse-btn" type="button" data-nb-sdb-toggle aria-label="Toggle sidebar" aria-expanded="true">
    <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><polyline points="15 18 9 12 15 6"/></svg>
  </button>

  <div class="main">
    <div class="topbar">
      <div class="breadcrumb">
        <span>hexlane</span>
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>
        <span>Acme Corp</span>
        <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>
        <strong>Dashboard</strong>
      </div>
      <div class="topbar-spacer"></div>
      <div class="topbar-search">
        <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
        Search...
        <span class="search-shortcut">⌘K</span>
      </div>
      <div class="topbar-actions">
        <button class="topbar-icon" type="button" aria-label="Notifications">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
          <span class="notif-dot" aria-hidden="true"></span>
        </button>
        <button class="topbar-icon" type="button" aria-label="Command palette">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><polyline points="4 17 10 11 4 5"/><line x1="12" y1="19" x2="20" y2="19"/></svg>
        </button>
      </div>
    </div>

    <div class="content">
      <h1 class="page-title">Overview</h1>
      <p class="page-desc">Your workspace at a glance — updated just now</p>

      <div class="stats-row">
        <div class="stat-card">
          <div class="stat-label">Monthly Revenue</div>
          <div class="stat-value">$84.2k</div>
          <div class="stat-change up"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><polyline points="18 15 12 9 6 15"/></svg> +12.4%</div>
        </div>
        <div class="stat-card">
          <div class="stat-label">Active Users</div>
          <div class="stat-value">4,291</div>
          <div class="stat-change up"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><polyline points="18 15 12 9 6 15"/></svg> +8.1%</div>
        </div>
        <div class="stat-card">
          <div class="stat-label">Deployments</div>
          <div class="stat-value">138</div>
          <div class="stat-change down"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><polyline points="6 9 12 15 18 9"/></svg> −3.2%</div>
        </div>
        <div class="stat-card">
          <div class="stat-label">Uptime SLA</div>
          <div class="stat-value">99.97%</div>
          <div class="stat-change up"><svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><polyline points="18 15 12 9 6 15"/></svg> Stable</div>
        </div>
      </div>

      <div class="chart-area">
        <div class="chart-card">
          <div class="chart-title">Request Volume</div>
          <div class="chart-sub">Last 14 days — hover over bars</div>
          <div class="chart-bars" aria-hidden="true">
            <div class="bar bh-45"></div><div class="bar bh-60"></div><div class="bar bh-40"></div><div class="bar bh-70"></div><div class="bar bh-55"></div><div class="bar bh-80"></div><div class="bar active bh-90"></div><div class="bar bh-65"></div><div class="bar bh-75"></div><div class="bar bh-50"></div><div class="bar bh-85"></div><div class="bar bh-70"></div><div class="bar bh-95"></div><div class="bar bh-78"></div>
          </div>
        </div>
        <div class="chart-card">
          <div class="chart-title">Recent Activity</div>
          <div class="chart-sub">Live feed</div>
          <div class="activity-list">
            <div class="activity-item">
              <div class="activity-dot dot-green" aria-hidden="true"></div>
              <div class="activity-text"><strong>Deploy succeeded</strong> — production v2.4.1</div>
              <div class="activity-time">2m ago</div>
            </div>
            <div class="activity-item">
              <div class="activity-dot dot-blue" aria-hidden="true"></div>
              <div class="activity-text"><strong>Jordan Lee</strong> updated API keys</div>
              <div class="activity-time">14m</div>
            </div>
            <div class="activity-item">
              <div class="activity-dot dot-orange" aria-hidden="true"></div>
              <div class="activity-text"><strong>Alert triggered</strong> — latency spike</div>
              <div class="activity-time">1h</div>
            </div>
            <div class="activity-item">
              <div class="activity-dot dot-red" aria-hidden="true"></div>
              <div class="activity-text"><strong>Build failed</strong> — staging branch</div>
              <div class="activity-time">2h</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</section>
```
## CSS
```css
/* ─── 04 hexlane — collapsible sidebar dashboard navbar UI ─────── */

@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@300;400;500;600&family=IBM+Plex+Mono:wght@400;500&display=swap');

.nb-sdb {
  --nb-sdb-sidebar-w: 240px;
  --nb-sdb-sidebar-collapsed: 64px;
  --nb-sdb-bg: #0d1117;
  --nb-sdb-surface: #161b22;
  --nb-sdb-surface-2: #21262d;
  --nb-sdb-border: #30363d;
  --nb-sdb-text: #e6edf3;
  --nb-sdb-text-muted: #7d8590;
  --nb-sdb-text-dim: #484f58;
  --nb-sdb-accent: #58a6ff;
  --nb-sdb-accent-green: #3fb950;
  --nb-sdb-accent-orange: #d29922;
  --nb-sdb-accent-red: #f85149;
  --nb-sdb-accent-purple: #bc8cff;
  --nb-sdb-transition: 0.22s cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
  width: 100%;
  min-height: 720px;
  background: var(--nb-sdb-bg);
  color: var(--nb-sdb-text);
  font-family: 'IBM Plex Sans', sans-serif;
  display: flex;
  overflow: hidden;
  box-sizing: border-box;
}

.nb-sdb *,
.nb-sdb *::before,
.nb-sdb *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.nb-sdb aside {
  width: var(--nb-sdb-sidebar-w);
  background: var(--nb-sdb-surface);
  border-right: 1px solid var(--nb-sdb-border);
  display: flex;
  flex-direction: column;
  transition: width var(--nb-sdb-transition);
  position: relative;
  z-index: 50;
  overflow: hidden;
  flex-shrink: 0;
}

.nb-sdb aside.collapsed {
  width: var(--nb-sdb-sidebar-collapsed);
}

.nb-sdb .sidebar-logo {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 16px;
  height: 56px;
  border-bottom: 1px solid var(--nb-sdb-border);
  flex-shrink: 0;
  overflow: hidden;
  white-space: nowrap;
}

.nb-sdb .logo-icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: linear-gradient(135deg, var(--nb-sdb-accent), var(--nb-sdb-accent-purple));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  flex-shrink: 0;
  box-shadow: 0 2px 12px rgba(88,166,255,0.3);
  color: #fff;
}

.nb-sdb .logo-text {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: -0.02em;
  color: var(--nb-sdb-text);
  transition: opacity var(--nb-sdb-transition), width var(--nb-sdb-transition);
  overflow: hidden;
}

.nb-sdb .logo-dot {
  color: var(--nb-sdb-accent);
}

.nb-sdb aside.collapsed .logo-text {
  opacity: 0;
  width: 0;
}
/* Collapse toggle sits at the sidebar's outer edge. Lifted out of
   <aside> so aside's overflow:hidden (which clips the fading labels)
   doesn't also clip this button. Positioned absolute against the
   wrapper; its left coord tracks the sidebar width via :has(). */

.nb-sdb .collapse-btn {
  position: absolute;
  top: 68px;
  left: calc(var(--nb-sdb-sidebar-w) - 12px);
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--nb-sdb-surface-2);
  border: 1px solid var(--nb-sdb-border);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--nb-sdb-text-muted);
  transition: background 0.15s, color 0.15s, left var(--nb-sdb-transition);
  z-index: 60;
}

.nb-sdb:has(aside.collapsed) .collapse-btn {
  left: calc(var(--nb-sdb-sidebar-collapsed) - 12px);
}

.nb-sdb .collapse-btn:hover {
  background: var(--nb-sdb-accent);
  color: #fff;
  border-color: var(--nb-sdb-accent);
}

.nb-sdb .collapse-btn svg {
  transition: transform var(--nb-sdb-transition);
}

.nb-sdb:has(aside.collapsed) .collapse-btn svg {
  transform: rotate(180deg);
}

.nb-sdb .workspace {
  margin: 12px 10px;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid var(--nb-sdb-border);
  background: var(--nb-sdb-surface-2);
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
  overflow: hidden;
  white-space: nowrap;
  flex-shrink: 0;
}

.nb-sdb .workspace:hover {
  border-color: var(--nb-sdb-accent);
  background: rgba(88,166,255,0.05);
}

.nb-sdb .ws-avatar {
  width: 24px;
  height: 24px;
  border-radius: 6px;
  background: linear-gradient(135deg, #3fb950, #1f6feb);
  flex-shrink: 0;
  font-size: 0.6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 600;
}

.nb-sdb .ws-info {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  transition: opacity var(--nb-sdb-transition), width var(--nb-sdb-transition);
}

.nb-sdb aside.collapsed .ws-info {
  opacity: 0;
  width: 0;
}

.nb-sdb .ws-name {
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--nb-sdb-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.nb-sdb .ws-plan {
  font-size: 0.6rem;
  color: var(--nb-sdb-text-muted);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.nb-sdb .ws-chevron {
  color: var(--nb-sdb-text-dim);
  flex-shrink: 0;
  transition: opacity var(--nb-sdb-transition);
}

.nb-sdb aside.collapsed .ws-chevron {
  opacity: 0;
}

.nb-sdb .sidebar-nav {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 8px 0;
  scrollbar-width: thin;
  scrollbar-color: var(--nb-sdb-border) transparent;
}

.nb-sdb .sidebar-nav::-webkit-scrollbar {
  width: 4px;
}

.nb-sdb .sidebar-nav::-webkit-scrollbar-thumb {
  background: var(--nb-sdb-border);
  border-radius: 2px;
}

.nb-sdb .nav-section {
  margin-bottom: 4px;
}

.nb-sdb .nav-section-label {
  font-size: 0.6rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--nb-sdb-text-dim);
  padding: 8px 20px 4px;
  white-space: nowrap;
  overflow: hidden;
  transition: opacity var(--nb-sdb-transition);
}

.nb-sdb aside.collapsed .nav-section-label {
  opacity: 0;
}

.nb-sdb .nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px 7px 16px;
  margin: 1px 8px;
  border-radius: 8px;
  font-size: 0.82rem;
  font-weight: 400;
  color: var(--nb-sdb-text-muted);
  text-decoration: none;
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
  white-space: nowrap;
  overflow: hidden;
  user-select: none;
}

.nb-sdb .nav-item:hover {
  background: var(--nb-sdb-surface-2);
  color: var(--nb-sdb-text);
}

.nb-sdb .nav-item.active {
  background: rgba(88,166,255,0.1);
  color: var(--nb-sdb-accent);
}

.nb-sdb .nav-item.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 20%;
  bottom: 20%;
  width: 3px;
  border-radius: 0 2px 2px 0;
  background: var(--nb-sdb-accent);
}

.nb-sdb .nav-icon {
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  opacity: 0.8;
}

.nb-sdb .nav-item.active .nav-icon,
.nb-sdb .nav-item:hover .nav-icon {
  opacity: 1;
}

.nb-sdb .nav-label {
  transition: opacity var(--nb-sdb-transition), width var(--nb-sdb-transition);
  overflow: hidden;
}

.nb-sdb aside.collapsed .nav-label {
  opacity: 0;
  width: 0;
}

.nb-sdb .nav-badge {
  margin-left: auto;
  flex-shrink: 0;
  font-size: 0.6rem;
  font-weight: 600;
  padding: 2px 6px;
  border-radius: 100px;
  transition: opacity var(--nb-sdb-transition);
}

.nb-sdb aside.collapsed .nav-badge {
  opacity: 0;
}

.nb-sdb .badge-blue {
  background: rgba(88,166,255,0.15);
  color: var(--nb-sdb-accent);
}

.nb-sdb .badge-green {
  background: rgba(63,185,80,0.15);
  color: var(--nb-sdb-accent-green);
}

.nb-sdb .badge-orange {
  background: rgba(210,153,34,0.15);
  color: var(--nb-sdb-accent-orange);
}

.nb-sdb .badge-red {
  background: rgba(248,81,73,0.15);
  color: var(--nb-sdb-accent-red);
}

.nb-sdb aside.collapsed .nav-item::after {
  content: attr(data-label);
  position: absolute;
  left: calc(var(--nb-sdb-sidebar-collapsed) - 8px);
  top: 50%;
  transform: translateY(-50%);
  background: var(--nb-sdb-surface-2);
  color: var(--nb-sdb-text);
  font-size: 0.75rem;
  padding: 5px 10px;
  border-radius: 6px;
  border: 1px solid var(--nb-sdb-border);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s;
  z-index: 100;
  box-shadow: 0 4px 16px rgba(0,0,0,0.4);
}

.nb-sdb aside.collapsed .nav-item:hover::after {
  opacity: 1;
}

.nb-sdb .sidebar-foot {
  border-top: 1px solid var(--nb-sdb-border);
  padding: 10px;
  flex-shrink: 0;
  overflow: hidden;
}

.nb-sdb .user-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 6px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.12s;
  white-space: nowrap;
  overflow: hidden;
}

.nb-sdb .user-row:hover {
  background: var(--nb-sdb-surface-2);
}

.nb-sdb .user-avatar {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--nb-sdb-accent-purple), var(--nb-sdb-accent));
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  font-weight: 600;
  color: #fff;
}

.nb-sdb .user-info {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  transition: opacity var(--nb-sdb-transition), width var(--nb-sdb-transition);
}

.nb-sdb aside.collapsed .user-info {
  opacity: 0;
  width: 0;
}

.nb-sdb .user-name {
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--nb-sdb-text);
  overflow: hidden;
  text-overflow: ellipsis;
}

.nb-sdb .user-handle {
  font-size: 0.65rem;
  color: var(--nb-sdb-text-dim);
  overflow: hidden;
  text-overflow: ellipsis;
}

.nb-sdb .user-menu-btn {
  color: var(--nb-sdb-text-dim);
  flex-shrink: 0;
  transition: opacity var(--nb-sdb-transition);
}

.nb-sdb aside.collapsed .user-menu-btn {
  opacity: 0;
}

.nb-sdb .main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 720px;
}

.nb-sdb .topbar {
  height: 56px;
  border-bottom: 1px solid var(--nb-sdb-border);
  display: flex;
  align-items: center;
  padding: 0 24px;
  gap: 16px;
  background: var(--nb-sdb-surface);
  flex-shrink: 0;
}

.nb-sdb .breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.72rem;
  color: var(--nb-sdb-text-muted);
}

.nb-sdb .breadcrumb span {
  color: var(--nb-sdb-text-dim);
}

.nb-sdb .breadcrumb strong {
  color: var(--nb-sdb-text);
  font-weight: 500;
}

.nb-sdb .topbar-spacer {
  flex: 1;
}

.nb-sdb .topbar-search {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--nb-sdb-bg);
  border: 1px solid var(--nb-sdb-border);
  border-radius: 8px;
  padding: 6px 12px;
  color: var(--nb-sdb-text-muted);
  font-size: 0.75rem;
  cursor: pointer;
  transition: border-color 0.15s;
}

.nb-sdb .topbar-search:hover {
  border-color: var(--nb-sdb-text-dim);
}

.nb-sdb .search-shortcut {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.6rem;
  background: var(--nb-sdb-surface-2);
  border: 1px solid var(--nb-sdb-border);
  border-radius: 4px;
  padding: 1px 5px;
  color: var(--nb-sdb-text-dim);
  margin-left: 24px;
}

.nb-sdb .topbar-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.nb-sdb .topbar-icon {
  width: 32px;
  height: 32px;
  border-radius: 6px;
  border: 1px solid var(--nb-sdb-border);
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--nb-sdb-text-muted);
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
  position: relative;
}

.nb-sdb .topbar-icon:hover {
  background: var(--nb-sdb-surface-2);
  color: var(--nb-sdb-text);
}

.nb-sdb .notif-dot {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--nb-sdb-accent-red);
  border: 1.5px solid var(--nb-sdb-surface);
}

.nb-sdb .content {
  padding: 28px;
  flex: 1;
}

.nb-sdb .page-title {
  font-size: 1.2rem;
  font-weight: 600;
  color: var(--nb-sdb-text);
  margin-bottom: 4px;
}

.nb-sdb .page-desc {
  font-size: 0.82rem;
  color: var(--nb-sdb-text-muted);
  margin-bottom: 24px;
}

.nb-sdb .stats-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 24px;
}

.nb-sdb .stat-card {
  background: var(--nb-sdb-surface);
  border: 1px solid var(--nb-sdb-border);
  border-radius: 12px;
  padding: 18px 20px;
  transition: border-color 0.15s;
}

.nb-sdb .stat-card:hover {
  border-color: var(--nb-sdb-text-dim);
}

.nb-sdb .stat-label {
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--nb-sdb-text-muted);
  margin-bottom: 10px;
}

.nb-sdb .stat-value {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 1.6rem;
  font-weight: 500;
  color: var(--nb-sdb-text);
  line-height: 1;
  margin-bottom: 8px;
}

.nb-sdb .stat-change {
  font-size: 0.72rem;
  display: flex;
  align-items: center;
  gap: 4px;
}

.nb-sdb .up {
  color: var(--nb-sdb-accent-green);
}

.nb-sdb .down {
  color: var(--nb-sdb-accent-red);
}

.nb-sdb .chart-area {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: 16px;
}

.nb-sdb .chart-card {
  background: var(--nb-sdb-surface);
  border: 1px solid var(--nb-sdb-border);
  border-radius: 12px;
  padding: 20px;
}

.nb-sdb .chart-title {
  font-size: 0.82rem;
  font-weight: 500;
  color: var(--nb-sdb-text);
  margin-bottom: 4px;
}

.nb-sdb .chart-sub {
  font-size: 0.72rem;
  color: var(--nb-sdb-text-muted);
  margin-bottom: 16px;
}

.nb-sdb .chart-bars {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 100px;
}

.nb-sdb .bar {
  flex: 1;
  border-radius: 4px 4px 0 0;
  background: rgba(88,166,255,0.15);
  border: 1px solid rgba(88,166,255,0.2);
  transition: background 0.15s;
}

.nb-sdb .bar:hover {
  background: rgba(88,166,255,0.35);
}

.nb-sdb .bar.active {
  background: rgba(88,166,255,0.6);
  border-color: var(--nb-sdb-accent);
}

.nb-sdb .bh-40 {
  height: 40%;
}

.nb-sdb .bh-45 {
  height: 45%;
}

.nb-sdb .bh-50 {
  height: 50%;
}

.nb-sdb .bh-55 {
  height: 55%;
}

.nb-sdb .bh-60 {
  height: 60%;
}

.nb-sdb .bh-65 {
  height: 65%;
}

.nb-sdb .bh-70 {
  height: 70%;
}

.nb-sdb .bh-75 {
  height: 75%;
}

.nb-sdb .bh-78 {
  height: 78%;
}

.nb-sdb .bh-80 {
  height: 80%;
}

.nb-sdb .bh-85 {
  height: 85%;
}

.nb-sdb .bh-90 {
  height: 90%;
}

.nb-sdb .bh-95 {
  height: 95%;
}

.nb-sdb .activity-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.nb-sdb .activity-item {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

.nb-sdb .activity-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
  margin-top: 4px;
}

.nb-sdb .dot-green {
  background: var(--nb-sdb-accent-green);
}

.nb-sdb .dot-blue {
  background: var(--nb-sdb-accent);
}

.nb-sdb .dot-orange {
  background: var(--nb-sdb-accent-orange);
}

.nb-sdb .dot-red {
  background: var(--nb-sdb-accent-red);
}

.nb-sdb .activity-text {
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--nb-sdb-text-muted);
}

.nb-sdb .activity-text strong {
  color: var(--nb-sdb-text);
}

.nb-sdb .activity-time {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 0.65rem;
  color: var(--nb-sdb-text-dim);
  margin-left: auto;
  flex-shrink: 0;
}

@media (max-width: 1024px) {
  .nb-sdb .stats-row {
    grid-template-columns: repeat(2, 1fr);
  }

  .nb-sdb .chart-area {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 640px) {
  .nb-sdb .stats-row {
    grid-template-columns: 1fr;
  }

  .nb-sdb .search-shortcut {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .nb-sdb aside,
    .nb-sdb .nav-label,
    .nb-sdb .ws-info,
    .nb-sdb .user-info,
    .nb-sdb .collapse-btn svg {
    transition: none !important;
  }
}
```

## JavaScript
```js
(() => {
  // Scoped collapsible-sidebar wiring. State lives on the wrapper, so
  // two instances of this demo on one page can each collapse
  // independently.
  const root = document.querySelector('.nb-sdb');
  if (!root) return;
  const sidebar = root.querySelector('[data-nb-sdb-sidebar]');
  const toggle = root.querySelector('[data-nb-sdb-toggle]');
  if (!sidebar || !toggle) return;

  toggle.addEventListener('click', () => {
    const collapsed = sidebar.classList.toggle('collapsed');
    toggle.setAttribute('aria-expanded', !collapsed);
  });

  // Click to set the active nav item, scoped to this sidebar.
  sidebar.querySelectorAll('.nav-item').forEach((item) => {
    item.addEventListener('click', (e) => {
      e.preventDefault();
      sidebar.querySelectorAll('.nav-item').forEach((i) => i.classList.remove('active'));
      item.classList.add('active');
    });
  });
})();
```

Techniques used in this demo

Search CodeFronts

Loading…