4. Navigation System
4.1 Left Sidebar - Hierarchical Project Tree
Full Specification:
┌─────────────────────────────────────────┐
│ DASHBOARD 2.0 │ ← Header (sticky)
├─────────────────────────────────────────┤
│ 🔍 Filter projects... │ ← Search input (instant filter)
├─────────────────────────────────────────┤
│ │
│ VIEWS │ ← Section header (uppercase, gray-500)
│ 📊 Portfolio Overview ← │ ← Active view (blue background)
│ 📋 All Tasks │
│ 📈 Analytics & Reports │
│ 🔍 Search Results (12) │ ← Badge: result count
│ │
│ PROJECTS (8 categories, 46 total) │ ← Section header with count
│ ▼ Core (3 projects) │ ← Category (collapsible, bold)
│ ├─ 🟢 coditect-core 78% ← │ ← Project (status color, % badge)
│ │ 530 tasks • Beta Phase │ ← Metadata (gray-700, 12px)
│ ├─ 🟡 coditect-core-framework 40% │
│ │ 45 tasks • Planning │
│ └─ 🔵 coditect-core-architecture ✓ │ ← Blue = 100% complete
│ 12 tasks • Complete │
│ │
│ ▼ Cloud (4 projects) │
│ ├─ 🟢 coditect-cloud-backend 65% │
│ │ 89 tasks • Beta Phase │
│ ├─ 🟡 coditect-cloud-ide 45% │
│ │ 134 tasks • Development │
│ ├─ 🟢 coditect-cloud-infra 70% │
│ │ 67 tasks • Beta Phase │
│ └─ 🔴 coditect-cloud-monitoring 10% │ ← Red = <40% (needs attention)
│ 23 tasks • Not Started │
│ │
│ ▶ Dev (10 projects) [+] │ ← Collapsed (click to expand)
│ ▶ Frontend (8 projects) [+] │
│ ▶ Security (5 projects) [+] │
│ ▶ Testing (6 projects) [+] │
│ ▶ Docs (4 projects) [+] │
│ ▶ Tools (6 projects) [+] │
│ │
│ MILESTONES & GATES │ ← Section header
│ ◆ Beta Analysis Dec 10, 2025 │ ← Diamond icon for milestones
│ ◆ Pilot Launch Feb 15, 2026 │
│ ◆ Public GTM Mar 11, 2026 │
│ │
└─────────────────────────────────────────┘
Detailed Element Specifications:
4.1.1 Search Input
<div class="sidebar-search">
<input
type="text"
placeholder="Filter projects..."
aria-label="Search projects"
class="search-input"
/>
<svg class="search-icon" aria-hidden="true"><!-- magnifying glass --></svg>
</div>
.sidebar-search {
position: sticky;
top: 0;
background: var(--white);
padding: var(--spacing-md);
border-bottom: 1px solid var(--gray-300);
z-index: 10;
}
.search-input {
width: 100%;
padding: var(--spacing-sm) var(--spacing-md) var(--spacing-sm) 2.5rem;
border: 1px solid var(--gray-300);
border-radius: 4px;
font-size: var(--font-size-sm);
}
.search-input:focus {
outline: 2px solid var(--primary-blue);
outline-offset: 2px;
border-color: var(--primary-blue);
}
.search-icon {
position: absolute;
left: var(--spacing-md);
top: 50%;
transform: translateY(-50%);
width: 16px;
height: 16px;
color: var(--gray-500);
}
Behavior:
- Instant filtering: Filter on keyup (no debounce, instant feedback)
- Fuzzy matching: Match substring anywhere in project name
- Highlight matches: Bold matching text in results
- Empty state: Show "No projects match 'search term'" if no results
- Clear button: Show ✕ icon when text entered (click to clear)
4.1.2 Category Headers
<button
class="category-header"
aria-expanded="true"
aria-controls="category-core"
>
<svg class="chevron" aria-hidden="true"><!-- down chevron --></svg>
<span class="category-name">Core</span>
<span class="category-count">(3 projects)</span>
</button>
.category-header {
width: 100%;
display: flex;
align-items: center;
gap: var(--spacing-sm);
padding: var(--spacing-sm) var(--spacing-md);
background: var(--gray-100);
border: none;
font-weight: var(--font-weight-semibold);
font-size: var(--font-size-sm);
text-align: left;
cursor: pointer;
transition: background 0.2s;
}
.category-header:hover {
background: var(--gray-300);
}
.category-header:focus {
outline: 2px solid var(--primary-blue);
outline-offset: -2px;
}
.chevron {
width: 16px;
height: 16px;
transition: transform 0.2s;
}
.category-header[aria-expanded="false"] .chevron {
transform: rotate(-90deg); /* Point right when collapsed */
}
.category-count {
margin-left: auto;
color: var(--gray-500);
font-weight: var(--font-weight-normal);
}
Behavior:
- Click to toggle: Expand/collapse category
- Keyboard: Space or Enter to toggle
- Animation: 200ms ease transition for chevron rotation and height
- State persistence: Remember expanded/collapsed state in localStorage
4.1.3 Project Items
<a
href="#/project/coditect-core"
class="project-item"
aria-current="page"
>
<span class="status-indicator status-green" aria-label="78% complete"></span>
<div class="project-content">
<div class="project-header">
<span class="project-name">coditect-core</span>
<span class="project-progress">78%</span>
</div>
<div class="project-meta">
530 tasks • Beta Phase
</div>
</div>
</a>
.project-item {
display: flex;
align-items: flex-start;
gap: var(--spacing-sm);
padding: var(--spacing-sm) var(--spacing-md);
text-decoration: none;
color: var(--gray-900);
border-left: 3px solid transparent;
transition: all 0.2s;
}
.project-item:hover {
background: var(--gray-100);
border-left-color: var(--gray-300);
}
.project-item[aria-current="page"] {
background: var(--primary-blue-light);
border-left-color: var(--primary-blue);
font-weight: var(--font-weight-medium);
}
.project-item:focus {
outline: 2px solid var(--primary-blue);
outline-offset: -2px;
}
.status-indicator {
width: 12px;
height: 12px;
border-radius: 50%;
flex-shrink: 0;
margin-top: 0.25rem;
}
.status-green { background: var(--status-green); }
.status-yellow { background: var(--status-yellow); }
.status-red { background: var(--status-red); }
.status-blue { background: var(--status-blue); }
.project-content {
flex: 1;
min-width: 0; /* Allow text truncation */
}
.project-header {
display: flex;
justify-content: space-between;
align-items: center;
gap: var(--spacing-sm);
margin-bottom: 0.25rem;
}
.project-name {
font-size: var(--font-size-sm);
font-weight: var(--font-weight-medium);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.project-progress {
font-size: var(--font-size-xs);
font-weight: var(--font-weight-semibold);
color: var(--gray-700);
flex-shrink: 0;
}
.project-meta {
font-size: var(--font-size-xs);
color: var(--gray-700);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Behavior:
- Click: Navigate to project detail view (updates main content)
- Hover: Show tooltip with full project name (if truncated) + next milestone
- Keyboard: Tab to focus, Enter to navigate
- Right-click: Show context menu (Open in new tab, Copy link, Add to favorites)
Tooltip Example:
┌────────────────────────────────────────┐
│ coditect-core │
│ 530 tasks (415 complete, 115 pending) │
│ Next milestone: Beta Analysis (Dec 10) │
└────────────────────────────────────────┘
4.2 Top Bar - Global Controls
Full Specification:
┌──────────────────────────────────────────────────────────────────────────────┐
│ 🔍 Search... │ 🎛️ Filters (3) │ Home > Projects > Core │
│ [Cmd+K] │ │ 👤 Hal Casteel │ ❓ Help │
└──────────────────────────────────────────────────────────────────────────────┘
↑ ↑ ↑ ↑
Global Search Filter Badge Breadcrumbs User Menu
Detailed Layout:
<header class="top-bar">
<div class="top-bar-left">
<!-- Global Search -->
<button class="search-trigger" aria-label="Search" data-shortcut="⌘K">
<svg class="icon"><!-- search icon --></svg>
<span>Search...</span>
<kbd>⌘K</kbd>
</button>
<!-- Filters -->
<button class="filters-trigger" aria-label="Open filters">
<svg class="icon"><!-- filter icon --></svg>
<span>Filters</span>
<span class="badge" aria-label="3 filters active">3</span>
</button>
</div>
<div class="top-bar-center">
<!-- Breadcrumbs -->
<nav aria-label="Breadcrumb">
<ol class="breadcrumb">
<li><a href="#/">Home</a></li>
<li><a href="#/projects">Projects</a></li>
<li aria-current="page">Core</li>
</ol>
</nav>
</div>
<div class="top-bar-right">
<!-- User Menu -->
<button class="user-menu-trigger" aria-haspopup="true" aria-expanded="false">
<img src="avatar.jpg" alt="Hal Casteel" class="avatar" />
<span>Hal Casteel</span>
<svg class="icon"><!-- chevron down --></svg>
</button>
<!-- Help -->
<button class="help-trigger" aria-label="Help">
<svg class="icon"><!-- question mark --></svg>
</button>
</div>
</header>
.top-bar {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 60px;
background: var(--white);
border-bottom: 1px solid var(--gray-300);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 var(--spacing-lg);
z-index: 100;
gap: var(--spacing-lg);
}
.top-bar-left,
.top-bar-right {
display: flex;
align-items: center;
gap: var(--spacing-md);
}
.top-bar-center {
flex: 1;
min-width: 0; /* Allow breadcrumb truncation */
}
/* Search Trigger */
.search-trigger {
display: flex;
align-items: center;
gap: var(--spacing-sm);
padding: var(--spacing-sm) var(--spacing-md);
background: var(--gray-100);
border: 1px solid var(--gray-300);
border-radius: 4px;
font-size: var(--font-size-sm);
color: var(--gray-700);
cursor: pointer;
min-width: 200px;
transition: all 0.2s;
}
.search-trigger:hover {
background: var(--white);
border-color: var(--gray-500);
}
.search-trigger:focus {
outline: 2px solid var(--primary-blue);
outline-offset: 2px;
}
.search-trigger kbd {
margin-left: auto;
padding: 0.125rem 0.375rem;
background: var(--white);
border: 1px solid var(--gray-300);
border-radius: 3px;
font-size: var(--font-size-xs);
font-family: monospace;
}
/* Filters Trigger */
.filters-trigger {
position: relative;
display: flex;
align-items: center;
gap: var(--spacing-sm);
padding: var(--spacing-sm) var(--spacing-md);
background: transparent;
border: 1px solid var(--gray-300);
border-radius: 4px;
font-size: var(--font-size-sm);
cursor: pointer;
transition: all 0.2s;
}
.filters-trigger:hover {
background: var(--gray-100);
}
.filters-trigger .badge {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 20px;
height: 20px;
padding: 0 0.375rem;
background: var(--primary-blue);
color: var(--white);
border-radius: 10px;
font-size: var(--font-size-xs);
font-weight: var(--font-weight-semibold);
}
/* Breadcrumbs */
.breadcrumb {
display: flex;
align-items: center;
gap: var(--spacing-sm);
list-style: none;
margin: 0;
padding: 0;
font-size: var(--font-size-sm);
}
.breadcrumb li {
display: flex;
align-items: center;
gap: var(--spacing-sm);
}
.breadcrumb li:not(:last-child)::after {
content: "›";
color: var(--gray-500);
font-size: var(--font-size-lg);
}
.breadcrumb a {
color: var(--primary-blue);
text-decoration: none;
}
.breadcrumb a:hover {
text-decoration: underline;
}
.breadcrumb [aria-current="page"] {
color: var(--gray-900);
font-weight: var(--font-weight-medium);
}
/* User Menu */
.user-menu-trigger {
display: flex;
align-items: center;
gap: var(--spacing-sm);
padding: var(--spacing-sm);
background: transparent;
border: 1px solid transparent;
border-radius: 4px;
font-size: var(--font-size-sm);
cursor: pointer;
transition: all 0.2s;
}
.user-menu-trigger:hover {
background: var(--gray-100);
border-color: var(--gray-300);
}
.avatar {
width: 32px;
height: 32px;
border-radius: 50%;
object-fit: cover;
}
Behavior:
Search Trigger:
- Click: Opens global search modal (see Section 11)
- Keyboard: Cmd+K (Mac) or Ctrl+K (Windows/Linux)
- Focus: Tab to focus, Enter to open
Filters Trigger:
- Click: Opens filter modal (see Section 9)
- Badge: Shows number of active filters (0 = hidden)
- Badge color: Blue (#0066CC)
Breadcrumbs:
- Click link: Navigate to that level
- Truncation: Show last 3 levels if path too long ("... > Projects > Core")
- Mobile: Hide breadcrumbs <768px (show in hamburger menu)
User Menu:
- Click: Open dropdown menu
- Menu items: Profile, Settings, Sign Out
- Menu position: Right-aligned below trigger
- Close on: Click outside, Esc key, or menu item click