@@ -139,7 +139,7 @@ export default function UsagePage() {
Monthly Tokens
-
+
@@ -150,7 +150,7 @@ export default function UsagePage() {
Sessions
-
+
{monthlyStats?.sessionCount ?? 0}
@@ -159,7 +159,7 @@ export default function UsagePage() {
Avg Cost/Session
-
+
@@ -182,16 +182,16 @@ export default function UsagePage() {
{dailyData.length > 0 ? (
-
-
+
+
`$${v}`}
/>
@@ -239,8 +239,8 @@ export default function UsagePage() {
-
-
- `$${v}`} />
+
+
+ `$${v}`} />
[`$${Number(value).toFixed(3)}`, "Cost"]}
/>
-
+
diff --git a/new-ui/src/styles/ag-grid.css b/new-ui/src/styles/ag-grid.css
index 2503ed2..389123e 100644
--- a/new-ui/src/styles/ag-grid.css
+++ b/new-ui/src/styles/ag-grid.css
@@ -3,20 +3,22 @@
/* Import AG Grid Quartz theme at the grid layer */
@import "ag-grid-community/styles/ag-theme-quartz.css" layer(grid);
-/* Override AG Grid variables with beehive colors */
+/* Neutral theme overrides — maps to shadcn/ui CSS vars */
.ag-theme-quartz {
- --ag-background-color: var(--color-hive-surface);
- --ag-header-background-color: var(--color-hive-earth);
- --ag-odd-row-background-color: var(--color-hive-body);
- --ag-row-hover-color: rgba(245, 166, 35, 0.05);
- --ag-border-color: var(--color-hive-border);
- --ag-header-foreground-color: var(--color-hive-text-secondary);
- --ag-foreground-color: var(--color-hive-text-primary);
- --ag-selected-row-background-color: rgba(245, 166, 35, 0.1);
- --ag-font-family: var(--font-sans);
+ --ag-background-color: var(--color-background);
+ --ag-foreground-color: var(--color-foreground);
+ --ag-header-background-color: var(--color-muted);
+ --ag-header-foreground-color: var(--color-muted-foreground);
+ --ag-odd-row-background-color: transparent;
+ --ag-row-hover-color: var(--color-accent);
+ --ag-selected-row-background-color: var(--color-accent);
+ --ag-border-color: var(--color-border);
+ --ag-secondary-border-color: var(--color-border);
+ --ag-row-border-color: var(--color-border);
+ --ag-header-column-separator-color: var(--color-border);
+ --ag-font-family: "Space Grotesk", system-ui, sans-serif;
--ag-font-size: 13px;
- --ag-row-border-color: var(--color-hive-border);
- --ag-header-column-separator-color: var(--color-hive-border);
- --ag-range-selection-border-color: var(--color-hive-amber);
- --ag-input-focus-border-color: var(--color-hive-amber);
+ --ag-header-column-resize-handle-color: var(--color-border);
+ --ag-range-selection-border-color: var(--color-primary);
+ --ag-input-focus-border-color: var(--color-primary);
}
diff --git a/new-ui/src/styles/globals.css b/new-ui/src/styles/globals.css
index 392ee41..37eb227 100644
--- a/new-ui/src/styles/globals.css
+++ b/new-ui/src/styles/globals.css
@@ -4,118 +4,87 @@
@custom-variant dark (&:is(.dark *));
@theme {
- /* shadcn/ui OKLCH semantic colors — light base (standard Tailwind v4 pattern) */
- --color-background: oklch(0.98 0.005 60);
- --color-foreground: oklch(0.15 0.02 60);
+ /* shadcn/ui Zinc theme — light base with amber primary */
+ --color-background: oklch(1 0 0);
+ --color-foreground: oklch(0.141 0.005 285.823);
--color-card: oklch(1 0 0);
- --color-card-foreground: oklch(0.15 0.02 60);
+ --color-card-foreground: oklch(0.141 0.005 285.823);
--color-popover: oklch(1 0 0);
- --color-popover-foreground: oklch(0.15 0.02 60);
- --color-primary: oklch(0.65 0.15 60);
- --color-primary-foreground: oklch(0.98 0.005 60);
- --color-secondary: oklch(0.96 0.005 60);
- --color-secondary-foreground: oklch(0.15 0.02 60);
- --color-muted: oklch(0.96 0.005 60);
- --color-muted-foreground: oklch(0.45 0.03 60);
- --color-accent: oklch(0.96 0.005 60);
- --color-accent-foreground: oklch(0.15 0.02 60);
- --color-destructive: oklch(0.55 0.2 25);
- --color-destructive-foreground: oklch(0.98 0.005 60);
- --color-border: oklch(0.9 0.01 60);
- --color-input: oklch(0.9 0.01 60);
- --color-ring: oklch(0.65 0.15 60);
- --color-chart-1: oklch(0.75 0.15 70);
- --color-chart-2: oklch(0.65 0.12 160);
- --color-chart-3: oklch(0.6 0.15 250);
- --color-chart-4: oklch(0.7 0.1 320);
- --color-chart-5: oklch(0.8 0.12 90);
- --color-sidebar: oklch(0.98 0.005 60);
- --color-sidebar-foreground: oklch(0.15 0.02 60);
- --color-sidebar-primary: oklch(0.65 0.15 60);
- --color-sidebar-primary-foreground: oklch(0.98 0.005 60);
- --color-sidebar-accent: oklch(0.96 0.005 60);
- --color-sidebar-accent-foreground: oklch(0.15 0.02 60);
- --color-sidebar-border: oklch(0.9 0.01 60);
- --color-sidebar-ring: oklch(0.65 0.15 60);
+ --color-popover-foreground: oklch(0.141 0.005 285.823);
+ --color-primary: oklch(0.555 0.163 48.998);
+ --color-primary-foreground: oklch(0.985 0 0);
+ --color-secondary: oklch(0.967 0.001 286.375);
+ --color-secondary-foreground: oklch(0.21 0.006 285.885);
+ --color-muted: oklch(0.967 0.001 286.375);
+ --color-muted-foreground: oklch(0.552 0.016 285.938);
+ --color-accent: oklch(0.967 0.001 286.375);
+ --color-accent-foreground: oklch(0.21 0.006 285.885);
+ --color-destructive: oklch(0.577 0.245 27.325);
+ --color-destructive-foreground: oklch(0.985 0 0);
+ --color-border: oklch(0.92 0.004 286.32);
+ --color-input: oklch(0.92 0.004 286.32);
+ --color-ring: oklch(0.555 0.163 48.998);
+ --color-chart-1: oklch(0.646 0.222 41.116);
+ --color-chart-2: oklch(0.6 0.118 184.704);
+ --color-chart-3: oklch(0.398 0.07 227.392);
+ --color-chart-4: oklch(0.828 0.189 84.429);
+ --color-chart-5: oklch(0.769 0.188 70.08);
+ --color-sidebar: oklch(0.985 0 0);
+ --color-sidebar-foreground: oklch(0.141 0.005 285.823);
+ --color-sidebar-primary: oklch(0.555 0.163 48.998);
+ --color-sidebar-primary-foreground: oklch(0.985 0 0);
+ --color-sidebar-accent: oklch(0.967 0.001 286.375);
+ --color-sidebar-accent-foreground: oklch(0.21 0.006 285.885);
+ --color-sidebar-border: oklch(0.92 0.004 286.32);
+ --color-sidebar-ring: oklch(0.555 0.163 48.998);
- /* Beehive custom colors — light base */
- --color-hive-amber: #d48806;
- --color-hive-honey: #b87300;
- --color-hive-gold: #8b6914;
- --color-hive-deep: #9a5f00;
- --color-hive-rust: #b54242;
- --color-hive-blue: #3b82f6;
- --color-hive-body: #fdf8f3;
- --color-hive-surface: #ffffff;
- --color-hive-earth: #f5ede4;
- --color-hive-border: #e5d9ca;
- --color-hive-text-primary: #1a130e;
- --color-hive-text-secondary: #5c4a3d;
- --color-hive-text-tertiary: #8b7355;
-
- /* Terminal palette */
- --color-terminal-bg: #0a0a0a;
- --color-terminal-surface: #111111;
- --color-terminal-green: #00ff88;
- --color-terminal-cyan: #00d4ff;
- --color-terminal-amber: #ffaa00;
- --color-terminal-red: #ff4444;
/* Fonts */
--font-sans: "Space Grotesk", sans-serif;
--font-mono: "Space Mono", monospace;
- --font-display: "Graduate", cursive;
- /* Border radius */
- --radius-sm: 0.25rem;
- --radius-md: 0.375rem;
- --radius-lg: 0.5rem;
+ /* Border radius — shadcn/ui default */
+ --radius-sm: 0.375rem;
+ --radius-md: 0.5rem;
+ --radius-lg: 0.625rem;
--radius-xl: 0.75rem;
}
-/* Dark mode overrides (applied via .dark class on ) */
+/* Dark mode overrides */
.dark,
.dark * {
- --color-background: oklch(0.145 0.015 60);
- --color-foreground: oklch(0.97 0.01 60);
- --color-card: oklch(0.17 0.02 55);
- --color-card-foreground: oklch(0.97 0.01 60);
- --color-popover: oklch(0.145 0.015 60);
- --color-popover-foreground: oklch(0.97 0.01 60);
- --color-primary: oklch(0.75 0.15 70);
- --color-primary-foreground: oklch(0.15 0.02 60);
- --color-secondary: oklch(0.25 0.02 55);
- --color-secondary-foreground: oklch(0.97 0.01 60);
- --color-muted: oklch(0.25 0.02 55);
- --color-muted-foreground: oklch(0.65 0.04 60);
- --color-accent: oklch(0.25 0.02 55);
- --color-accent-foreground: oklch(0.97 0.01 60);
- --color-destructive: oklch(0.55 0.2 25);
- --color-destructive-foreground: oklch(0.97 0.01 60);
- --color-border: oklch(0.3 0.03 55);
- --color-input: oklch(0.3 0.03 55);
- --color-ring: oklch(0.75 0.15 70);
- --color-sidebar: oklch(0.145 0.015 60);
- --color-sidebar-foreground: oklch(0.97 0.01 60);
- --color-sidebar-primary: oklch(0.75 0.15 70);
- --color-sidebar-primary-foreground: oklch(0.15 0.02 60);
- --color-sidebar-accent: oklch(0.25 0.02 55);
- --color-sidebar-accent-foreground: oklch(0.97 0.01 60);
- --color-sidebar-border: oklch(0.3 0.03 55);
- --color-sidebar-ring: oklch(0.75 0.15 70);
-
- --color-hive-amber: #f5a623;
- --color-hive-honey: #ffb84d;
- --color-hive-gold: #d4a574;
- --color-hive-deep: #c67c00;
- --color-hive-rust: #a85454;
- --color-hive-body: #0d0906;
- --color-hive-surface: #1a130e;
- --color-hive-earth: #251c15;
- --color-hive-border: #3a2d1f;
- --color-hive-text-primary: #fff8e7;
- --color-hive-text-secondary: #c9b896;
- --color-hive-text-tertiary: #8b7355;
+ --color-background: oklch(0.141 0.005 285.823);
+ --color-foreground: oklch(0.985 0 0);
+ --color-card: oklch(0.21 0.006 285.885);
+ --color-card-foreground: oklch(0.985 0 0);
+ --color-popover: oklch(0.21 0.006 285.885);
+ --color-popover-foreground: oklch(0.985 0 0);
+ --color-primary: oklch(0.769 0.188 70.08);
+ --color-primary-foreground: oklch(0.21 0.006 285.885);
+ --color-secondary: oklch(0.274 0.006 286.033);
+ --color-secondary-foreground: oklch(0.985 0 0);
+ --color-muted: oklch(0.274 0.006 286.033);
+ --color-muted-foreground: oklch(0.705 0.015 286.067);
+ --color-accent: oklch(0.274 0.006 286.033);
+ --color-accent-foreground: oklch(0.985 0 0);
+ --color-destructive: oklch(0.704 0.191 22.216);
+ --color-destructive-foreground: oklch(0.985 0 0);
+ --color-border: oklch(1 0 0 / 10%);
+ --color-input: oklch(1 0 0 / 15%);
+ --color-ring: oklch(0.769 0.188 70.08);
+ --color-chart-1: oklch(0.488 0.243 264.376);
+ --color-chart-2: oklch(0.696 0.17 162.48);
+ --color-chart-3: oklch(0.769 0.188 70.08);
+ --color-chart-4: oklch(0.627 0.265 303.9);
+ --color-chart-5: oklch(0.645 0.246 16.439);
+ --color-sidebar: oklch(0.21 0.006 285.885);
+ --color-sidebar-foreground: oklch(0.985 0 0);
+ --color-sidebar-primary: oklch(0.769 0.188 70.08);
+ --color-sidebar-primary-foreground: oklch(0.985 0 0);
+ --color-sidebar-accent: oklch(0.274 0.006 286.033);
+ --color-sidebar-accent-foreground: oklch(0.985 0 0);
+ --color-sidebar-border: oklch(1 0 0 / 10%);
+ --color-sidebar-ring: oklch(0.769 0.188 70.08);
}
:root {
@@ -123,243 +92,31 @@
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
- --sidebar: hsl(0 0% 98%);
- --sidebar-foreground: hsl(240 5.3% 26.1%);
- --sidebar-primary: hsl(240 5.9% 10%);
- --sidebar-primary-foreground: hsl(0 0% 98%);
- --sidebar-accent: hsl(240 4.8% 95.9%);
- --sidebar-accent-foreground: hsl(240 5.9% 10%);
- --sidebar-border: hsl(220 13% 91%);
- --sidebar-ring: hsl(217.2 91.2% 59.8%);
}
body {
margin: 0;
- background: var(--color-hive-body);
- color: var(--color-hive-text-primary);
+ background: var(--color-background);
+ color: var(--color-foreground);
font-family: var(--font-sans);
min-height: 100vh;
}
-/* Honeycomb pattern background */
-.honeycomb-bg {
- position: relative;
-}
-
-.honeycomb-bg::before {
- content: "";
- position: absolute;
- inset: 0;
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='49' viewBox='0 0 28 49'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23F5A623' fill-opacity='0.08'%3E%3Cpath d='M13.99 9.25l13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
- pointer-events: none;
- z-index: 0;
-}
-
-.honeycomb-bg > * {
- position: relative;
- z-index: 1;
-}
-
-/* Warm amber scrollbar */
+/* Scrollbar */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
- background: var(--color-hive-body);
+ background: var(--color-background);
}
::-webkit-scrollbar-thumb {
- background: var(--color-hive-border);
+ background: var(--color-border);
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
- background: var(--color-hive-text-tertiary);
-}
-
-/* Amber glow effects */
-.glow-amber {
- text-shadow:
- 0 0 10px rgba(245, 166, 35, 0.5),
- 0 0 20px rgba(245, 166, 35, 0.3);
-}
-
-.glow-gold {
- text-shadow:
- 0 0 10px rgba(212, 165, 116, 0.5),
- 0 0 20px rgba(212, 165, 116, 0.3);
-}
-
-.glow-rust {
- text-shadow:
- 0 0 10px rgba(168, 84, 84, 0.5),
- 0 0 20px rgba(168, 84, 84, 0.3);
-}
-
-.glow-blue {
- text-shadow:
- 0 0 10px rgba(59, 130, 246, 0.5),
- 0 0 20px rgba(59, 130, 246, 0.3);
-}
-
-/* Box glow effects */
-.box-glow-amber {
- box-shadow:
- 0 0 15px rgba(245, 166, 35, 0.3),
- 0 0 30px rgba(245, 166, 35, 0.15);
-}
-
-.box-glow-gold {
- box-shadow:
- 0 0 15px rgba(212, 165, 116, 0.3),
- 0 0 30px rgba(212, 165, 116, 0.15);
-}
-
-/* Breathing animation for active elements */
-@keyframes breathe {
- 0%,
- 100% {
- opacity: 0.85;
- transform: scale(1);
- }
- 50% {
- opacity: 1;
- transform: scale(1.02);
- }
-}
-
-.animate-breathe {
- animation: breathe 3s ease-in-out infinite;
-}
-
-/* Pulse animation */
-@keyframes pulse-amber {
- 0%,
- 100% {
- box-shadow: 0 0 5px rgba(245, 166, 35, 0.4);
- }
- 50% {
- box-shadow:
- 0 0 15px rgba(245, 166, 35, 0.6),
- 0 0 25px rgba(245, 166, 35, 0.3);
- }
-}
-
-.animate-pulse-amber {
- animation: pulse-amber 2s ease-in-out infinite;
-}
-
-/* Heartbeat animation for connection status */
-@keyframes heartbeat {
- 0%,
- 100% {
- transform: scale(1);
- }
- 14% {
- transform: scale(1.1);
- }
- 28% {
- transform: scale(1);
- }
- 42% {
- transform: scale(1.1);
- }
- 70% {
- transform: scale(1);
- }
-}
-
-.animate-heartbeat {
- animation: heartbeat 1.5s ease-in-out infinite;
-}
-
-/* Hexagonal clip path utility */
-.clip-hex {
- clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
-}
-
-/* Hexagonal border */
-.hex-border {
- position: relative;
-}
-
-.hex-border::before {
- content: "";
- position: absolute;
- inset: -2px;
- clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
- background: linear-gradient(135deg, var(--color-hive-amber) 0%, var(--color-hive-deep) 100%);
- z-index: -1;
-}
-
-/* Gradient text for headers */
-.text-gradient-amber {
- background: linear-gradient(
- 135deg,
- var(--color-hive-amber) 0%,
- var(--color-hive-honey) 50%,
- var(--color-hive-deep) 100%
- );
- -webkit-background-clip: text;
- background-clip: text;
- -webkit-text-fill-color: transparent;
-}
-
-/* Card hover effect */
-.card-hover {
- transition: all 0.3s ease;
-}
-
-.card-hover:hover {
- border-color: rgba(245, 166, 35, 0.3);
- box-shadow: 0 0 20px rgba(245, 166, 35, 0.1);
-}
-
-/* Table row hover */
-.row-hover {
- transition: background-color 0.2s ease;
-}
-
-.row-hover:hover {
- background-color: rgba(245, 166, 35, 0.05);
-}
-
-/* Focus ring */
-.focus-amber:focus-visible {
- outline: 2px solid var(--color-hive-amber);
- outline-offset: 2px;
-}
-
-/* Subtle grain overlay for texture */
-.grain-overlay::after {
- content: "";
- position: absolute;
- inset: 0;
- background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.02'/%3E%3C/svg%3E");
- pointer-events: none;
- z-index: 0;
-}
-
-.dark {
- --sidebar: hsl(240 5.9% 10%);
- --sidebar-foreground: hsl(240 4.8% 95.9%);
- --sidebar-primary: hsl(224.3 76.3% 48%);
- --sidebar-primary-foreground: hsl(0 0% 100%);
- --sidebar-accent: hsl(240 3.7% 15.9%);
- --sidebar-accent-foreground: hsl(240 4.8% 95.9%);
- --sidebar-border: hsl(240 3.7% 15.9%);
- --sidebar-ring: hsl(217.2 91.2% 59.8%);
-}
-
-@theme inline {
- --color-sidebar: var(--sidebar);
- --color-sidebar-foreground: var(--sidebar-foreground);
- --color-sidebar-primary: var(--sidebar-primary);
- --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
- --color-sidebar-accent: var(--sidebar-accent);
- --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
- --color-sidebar-border: var(--sidebar-border);
- --color-sidebar-ring: var(--sidebar-ring);
+ background: var(--color-muted-foreground);
}
diff --git a/thoughts/taras/plans/2026-02-25-feat-new-ui-visual-redesign-plan.md b/thoughts/taras/plans/2026-02-25-feat-new-ui-visual-redesign-plan.md
new file mode 100644
index 0000000..589124f
--- /dev/null
+++ b/thoughts/taras/plans/2026-02-25-feat-new-ui-visual-redesign-plan.md
@@ -0,0 +1,768 @@
+---
+title: "feat: New UI Visual Redesign"
+type: feat
+status: active
+date: 2026-02-25
+deepened: 2026-02-25
+generated_with: compound-engineering/workflows:plan + deepen-plan
+---
+
+# New UI Visual Redesign
+
+## Enhancement Summary
+
+**Deepened on:** 2026-02-25
+**Research agents used:** repo-research-analyst, learnings-researcher, best-practices-researcher, Context7 (shadcn/ui, Tailwind v4, AG Grid), pattern-recognition-specialist, architecture-strategist, kieran-typescript-reviewer, browser-navigator
+
+### Key Improvements
+1. **Concrete CSS variable values** — Exact oklch values for the new Zinc-based palette, sourced from shadcn/ui v4 official theming docs
+2. **AG Grid theming code** — Specific CSS variable overrides and JS theme API usage for neutral dark/light modes
+3. **shadcn/ui native patterns** — Sidebar CSS variables, chart color tokens, component customization patterns from official docs
+4. **Systematic approach for Phase 4** — Grep-and-replace strategy with token mapping table
+5. **Critical sequencing fix** — Phase 1 keeps hive tokens as aliases to prevent AG Grid/body breakage
+
+### New Considerations Discovered
+- Tailwind v4 uses `@theme` directive for custom colors (not `tailwind.config.js`)
+- AG Grid v35 supports JS theme API (`themeQuartz.withParams()`) for programmatic dark/light mode switching
+- shadcn/ui chart colors are defined as `--chart-1` through `--chart-5` CSS variables with oklch — use these instead of custom chart palette
+- Border color in dark mode should use `oklch(1 0 0 / 10%)` (white at 10% opacity) for subtle separation — this is the shadcn/ui v4 convention
+- **Most beehive CSS utility classes are dead code** — only `animate-breathe` (stats-bar.tsx) and `animate-heartbeat` (app-header.tsx) are actually referenced from TSX files
+- **Triple color system conflict** — The `globals.css` has oklch tokens in `@theme`, HSL tokens in `:root`, and an `@theme inline` bridge that overrides the oklch sidebar values with HSL ones. The oklch sidebar values are dead code.
+- **44 direct Tailwind amber references** exist across 14 TSX files — this is the real migration work, not the hive CSS variables
+- **Three independent status-to-color maps** exist (StatusBadge, services/page.tsx, dashboard/page.tsx) — should be consolidated
+- **Sparklines in stats cards are scope creep** — current `StatsBarProps` has no historical data, and adding it would require API changes (violating "no API changes" constraint)
+
+### Review Agent Findings
+
+**TypeScript Reviewer** flagged:
+- Phase 1 grep must catch `hive-` and `terminal-` Tailwind class usage (not just CSS utility classes)
+- `statusConfig` should use `satisfies` for type safety
+- Stats bar `color?: string` prop should become constrained variant union
+- Phase 4 should be split into sub-phases: (4a) Dashboard + list pages, (4b) detail pages, (4c) Chat + Usage
+
+**Architecture Strategist** flagged:
+- **Sequencing bug**: Phase 1 removes hive tokens that `ag-grid.css`, `body` styles, and scrollbar styles depend on → must keep aliases or update simultaneously
+- Phase 1 should be split: 1a (add new tokens alongside old), 1b (migrate references, remove old)
+- Phases 2 and 3 are independent — can run in parallel
+- Phase 5 (animations) is small enough to fold into Phase 1
+
+**Pattern Recognition** found:
+- Most `.glow-*`, `.honeycomb-bg`, `.hex-border`, `.text-gradient-amber`, `.card-hover`, `.row-hover`, `.clip-hex` CSS classes are **never referenced in any TSX file** — they're dead CSS
+- Only 3 TSX files reference hive/terminal tokens directly: `app-sidebar.tsx`, `app-header.tsx`, `ag-grid.css`
+- The real migration effort is 44 hardcoded Tailwind `text-amber-*`/`bg-amber-*` references across page components
+- `formatInterval` is duplicated between `schedules/page.tsx` and `schedules/[id]/page.tsx` (out of scope but worth noting)
+- Chart colors in `usage/page.tsx` are hardcoded hex (`#f59e0b`) not tokens
+
+---
+
+## Overview
+
+The `new-ui` dashboard was recently built (Phases 1-6, merged Feb 25) as a modern replacement for the old MUI Joy UI dashboard. While functionally complete, it's visually a 1:1 port of the old UI's "beehive" theme — same hex colors, same honeycomb SVG background, same hexagonal stats bar, same Graduate display font, same glow effects. The result feels like a cheap copy rather than a design evolution.
+
+The goal is to transform the new-ui into a polished, distinctive dashboard that leverages shadcn/ui's strengths instead of fighting them. Think **Linear**, **Vercel Dashboard**, **Raycast** — clean, sharp, professional, with purposeful use of color and motion.
+
+## Problem Statement
+
+**Why it looks like a cheap copy:**
+
+1. **Aesthetic mismatch** — shadcn/ui is minimal/clean by design. Ornate honeycomb patterns, hexagonal clip-paths, and amber glow effects bolted onto Radix primitives create visual dissonance.
+2. **Identical palette** — Exact same hex values (`#f5a623`, `#ffb84d`, `#d4a574`, `#c67c00`) carried over from the MUI Joy version. No design evolution occurred.
+3. **Graduate display font** — A novelty cursive font that feels unprofessional in a monitoring dashboard. Does not complement Space Grotesk.
+4. **Gimmicky decorations** — Hexagonal clip-path stats, honeycomb SVG backgrounds, breathing/pulsing animations on idle elements, grain overlays. These were coherent in the MUI Joy version but feel like CSS tricks in the shadcn/ui context.
+5. **Tiny border radii** (0.25–0.75rem) — Creates sharp corners that clash with the organic "hive" metaphor and don't match shadcn/ui's typical rounded aesthetic.
+6. **Color overload** — Amber everywhere (borders, hovers, glows, text, badges, stats, icons) makes everything blend together. No visual hierarchy.
+
+## Proposed Solution
+
+**Design Direction: "Mission Control"** — Clean, information-dense, professional. Amber/gold becomes a strategic accent (not the dominant color). Dark mode as the hero experience with cool neutrals and warm highlights for key data.
+
+### Design Principles
+
+1. **Let shadcn/ui breathe** — Use the library's native patterns, don't override everything with custom CSS
+2. **Color with purpose** — Amber for brand accent and active states only; semantic colors for status; neutral base
+3. **Typography hierarchy** — Professional font stack, clear size/weight scale, no novelty fonts
+4. **Purposeful motion** — Animations only where they communicate state changes, not decorative loops
+5. **Information density** — Pack data efficiently without clutter; let spacing and typography create hierarchy
+
+## Technical Approach
+
+### Architecture
+
+All changes are CSS/component-level within `new-ui/src/`. No API changes, no routing changes, no data model changes. The redesign touches:
+
+- `src/styles/globals.css` — Color system, CSS variables, animations, utility classes
+- `src/styles/ag-grid.css` — Grid theme overrides
+- `src/components/layout/` — Sidebar, header
+- `src/components/shared/` — Stats bar, status badges, data grid, empty states
+- `src/pages/` — Page-specific layout and visual updates
+- `src/components/ui/` — Minimal shadcn/ui customization tweaks
+
+### Implementation Phases
+
+---
+
+#### Phase 1: Color System & Typography Foundation
+
+**Goal:** Replace the beehive palette with a refined system. Establish typography scale.
+
+**Color System Changes** (`globals.css`):
+
+- **Base neutrals:** Replace warm brown-blacks (`#0d0906`, `#1a130e`, `#251c15`) with cool-neutral dark tones (Zinc family from shadcn/ui).
+- **Brand accent:** Keep amber but constrain it to `--primary` only — interactive elements, active nav items, focused inputs. One accent, not five shades.
+- **Semantic status colors:** Standardize on Tailwind defaults — emerald for success, red for destructive, amber for warning, blue for info. Remove custom `hive-rust`, `hive-blue` redundancies.
+- **Text hierarchy:** Use shadcn/ui's native `--foreground` / `--muted-foreground` system. Drop the custom `hive-text-*` vars.
+- **Surface elevation:** Use shadcn/ui's `--background` → `--card` → `--popover` hierarchy.
+
+### Research Insights: Exact CSS Variable Values
+
+**Use shadcn/ui Zinc theme as the base**, then override `--primary` with amber for brand accent. Here are the exact oklch values from shadcn/ui v4 docs:
+
+```css
+/* globals.css — NEW color system */
+@import "tailwindcss";
+
+@layer base {
+ :root {
+ --radius: 0.625rem;
+ --background: oklch(1 0 0);
+ --foreground: oklch(0.141 0.005 285.823);
+ --card: oklch(1 0 0);
+ --card-foreground: oklch(0.141 0.005 285.823);
+ --popover: oklch(1 0 0);
+ --popover-foreground: oklch(0.141 0.005 285.823);
+ /* BRAND: amber-700 as primary for light mode */
+ --primary: oklch(0.555 0.163 48.998);
+ --primary-foreground: oklch(0.985 0 0);
+ --secondary: oklch(0.967 0.001 286.375);
+ --secondary-foreground: oklch(0.21 0.006 285.885);
+ --muted: oklch(0.967 0.001 286.375);
+ --muted-foreground: oklch(0.552 0.016 285.938);
+ --accent: oklch(0.967 0.001 286.375);
+ --accent-foreground: oklch(0.21 0.006 285.885);
+ --destructive: oklch(0.577 0.245 27.325);
+ --destructive-foreground: oklch(0.985 0 0);
+ --border: oklch(0.92 0.004 286.32);
+ --input: oklch(0.92 0.004 286.32);
+ --ring: oklch(0.555 0.163 48.998); /* match primary */
+ /* Charts: shadcn/ui defaults — balanced palette */
+ --chart-1: oklch(0.646 0.222 41.116);
+ --chart-2: oklch(0.6 0.118 184.704);
+ --chart-3: oklch(0.398 0.07 227.392);
+ --chart-4: oklch(0.828 0.189 84.429);
+ --chart-5: oklch(0.769 0.188 70.08);
+ /* Sidebar: shadcn/ui native vars */
+ --sidebar: oklch(0.985 0 0);
+ --sidebar-foreground: oklch(0.141 0.005 285.823);
+ --sidebar-primary: oklch(0.555 0.163 48.998);
+ --sidebar-primary-foreground: oklch(0.985 0 0);
+ --sidebar-accent: oklch(0.967 0.001 286.375);
+ --sidebar-accent-foreground: oklch(0.21 0.006 285.885);
+ --sidebar-border: oklch(0.92 0.004 286.32);
+ --sidebar-ring: oklch(0.555 0.163 48.998);
+ }
+
+ .dark {
+ --background: oklch(0.141 0.005 285.823);
+ --foreground: oklch(0.985 0 0);
+ --card: oklch(0.21 0.006 285.885);
+ --card-foreground: oklch(0.985 0 0);
+ --popover: oklch(0.21 0.006 285.885);
+ --popover-foreground: oklch(0.985 0 0);
+ /* BRAND: amber-500 as primary for dark mode (brighter) */
+ --primary: oklch(0.769 0.188 70.08);
+ --primary-foreground: oklch(0.21 0.006 285.885);
+ --secondary: oklch(0.274 0.006 286.033);
+ --secondary-foreground: oklch(0.985 0 0);
+ --muted: oklch(0.274 0.006 286.033);
+ --muted-foreground: oklch(0.705 0.015 286.067);
+ --accent: oklch(0.274 0.006 286.033);
+ --accent-foreground: oklch(0.985 0 0);
+ --destructive: oklch(0.704 0.191 22.216);
+ --destructive-foreground: oklch(0.985 0 0);
+ /* KEY: white at 10% for borders — shadcn/ui v4 dark convention */
+ --border: oklch(1 0 0 / 10%);
+ --input: oklch(1 0 0 / 15%);
+ --ring: oklch(0.769 0.188 70.08); /* match primary */
+ /* Charts: dark mode balanced palette */
+ --chart-1: oklch(0.488 0.243 264.376);
+ --chart-2: oklch(0.696 0.17 162.48);
+ --chart-3: oklch(0.769 0.188 70.08);
+ --chart-4: oklch(0.627 0.265 303.9);
+ --chart-5: oklch(0.645 0.246 16.439);
+ /* Sidebar */
+ --sidebar: oklch(0.21 0.006 285.885);
+ --sidebar-foreground: oklch(0.985 0 0);
+ --sidebar-primary: oklch(0.769 0.188 70.08);
+ --sidebar-primary-foreground: oklch(0.985 0 0);
+ --sidebar-accent: oklch(0.274 0.006 286.033);
+ --sidebar-accent-foreground: oklch(0.985 0 0);
+ --sidebar-border: oklch(1 0 0 / 10%);
+ --sidebar-ring: oklch(0.769 0.188 70.08);
+ }
+}
+```
+
+**Key design decisions in this palette:**
+- Light `--primary` = Tailwind `amber-700` (`oklch(0.555 0.163 48.998)`) — darker amber for light mode contrast
+- Dark `--primary` = Tailwind `amber-500` (`oklch(0.769 0.188 70.08)`) — brighter for dark bg visibility
+- All neutrals are Zinc family (hue ~286) — cool gray, not warm brown
+- Borders in dark mode: `oklch(1 0 0 / 10%)` — the shadcn/ui v4 standard
+- Chart colors are shadcn/ui defaults — blue, teal, slate, yellow, amber. Balanced, not amber-dominant
+
+**Typography Changes:**
+
+- **Remove Graduate** display font entirely. Use Space Grotesk bold/semibold for headings.
+- **Keep Space Grotesk** — it's a solid geometric sans-serif. Don't add Geist/Inter unless Space Grotesk proves problematic. Fewer fonts = faster loads.
+- **Establish scale:** Page titles `text-xl font-semibold`, section headers `text-base font-medium`, body `text-sm`, detail `text-xs`. Reduce overall font sizes — the current `text-2xl` titles are too large for a data dashboard.
+- **Keep Space Mono** for monospace (data values, IDs, code blocks) — it works well.
+
+**Border Radius:**
+
+- Set to shadcn/ui default: `--radius: 0.625rem` (10px). This gives cards `rounded-xl` feel, buttons `rounded-lg`, badges `rounded-full`.
+
+**Phase 1a: Add new tokens alongside old ones**
+
+1. Replace the `@theme` oklch values with the new Zinc-based palette (see CSS above)
+2. **Remove the `:root` and `.dark` HSL sidebar variable blocks** (the ones using `hsl()`) — they override the oklch sidebar values via `@theme inline` and create dead code
+3. **Remove the `@theme inline` bridge block** that maps `--color-sidebar: var(--sidebar)` — no longer needed
+4. **Keep `--color-hive-*` vars temporarily** but redefine them as aliases to the new semantic tokens:
+ ```css
+ /* TEMPORARY ALIASES — remove in Phase 3 after AG Grid + body migration */
+ --color-hive-body: var(--color-background);
+ --color-hive-surface: var(--color-card);
+ --color-hive-earth: var(--color-muted);
+ --color-hive-border: var(--color-border);
+ --color-hive-text-primary: var(--color-foreground);
+ --color-hive-text-secondary: var(--color-muted-foreground);
+ --color-hive-text-tertiary: var(--color-muted-foreground);
+ --color-hive-amber: var(--color-primary);
+ --color-hive-honey: var(--color-primary);
+ --color-hive-gold: var(--color-primary);
+ --color-hive-deep: var(--color-primary);
+ --color-hive-rust: var(--color-destructive);
+ --color-hive-blue: var(--color-info, oklch(0.623 0.214 259.815));
+ ```
+ This prevents `ag-grid.css`, `body` styles, and scrollbar styles from breaking.
+5. Update `body` rule to use `var(--color-background)` and `var(--color-foreground)`
+6. Update scrollbar rules to use `var(--color-background)` and `var(--color-border)`
+
+**Phase 1b: Remove dead CSS and animations**
+
+All of these CSS classes are **dead code** (never referenced in any TSX file):
+- `.honeycomb-bg`, `.grain-overlay`
+- `.glow-amber`, `.glow-gold`, `.glow-rust`, `.glow-blue`, `.box-glow-amber`, `.box-glow-gold`
+- `.text-gradient-amber`
+- `.hex-border::before`, `.clip-hex`
+- `.card-hover`, `.row-hover`, `.focus-amber`
+- `animate-pulse-amber` keyframe
+
+Only 2 animation references exist in TSX:
+- `animate-breathe` → used in `stats-bar.tsx:34` (will be removed in Phase 3 rewrite)
+- `animate-heartbeat` → used in `app-header.tsx:32` (replace with static dot)
+
+Safe to remove now:
+- All dead CSS utility classes listed above
+- `animate-pulse-amber` and `animate-heartbeat` keyframes (fix `app-header.tsx` reference)
+- Graduate font from `index.html` Google Fonts link (reconstruct URL to keep Space Grotesk + Space Mono)
+- `--font-display` variable from `globals.css`
+- All `--color-terminal-*` variables (replace the 2 TSX references: `bg-terminal-green` → `bg-emerald-500` and `bg-terminal-red` → `bg-red-500` in `app-header.tsx`)
+
+**Files to modify:**
+- `src/styles/globals.css` — Complete overhaul (new tokens, aliases, remove dead CSS)
+- `src/components/layout/app-header.tsx` — Replace `animate-heartbeat` with static dot, replace `terminal-*` classes
+- `index.html` — Reconstruct Google Fonts link without Graduate
+
+**Verification:**
+```bash
+cd new-ui && pnpm build
+# Verify no build errors
+# Check all hive/terminal references are either aliased or fixed:
+grep -rE "(hive-|terminal-|honeycomb|glow-amber|glow-gold|text-gradient|hex-border|grain-overlay|font-display|clip-hex|Graduate)" src/ --include="*.tsx" --include="*.ts" --include="*.css"
+# Expected: only the temporary aliases in globals.css and animate-breathe in stats-bar.tsx
+pnpm dev # Verify UI renders correctly with new palette but same layout
+```
+
+---
+
+#### Phase 2: Layout & Navigation
+
+**Goal:** Polish sidebar and header to feel native to shadcn/ui.
+
+**Sidebar** (`app-sidebar.tsx`):
+
+- Remove amber text for title. Use `text-sidebar-foreground` with the brand accent only on the logo mark.
+- Navigation items: Remove left-border active indicator. Use `bg-sidebar-accent text-sidebar-accent-foreground` for active state — this is shadcn/ui's native sidebar pattern. These map to the CSS variables defined in Phase 1.
+- Hover: `hover:bg-sidebar-accent/50` subtle highlight, not amber text color change.
+- Group navigation items semantically with `SidebarGroup` + `SidebarGroupLabel`:
+ - **Core:** Dashboard, Agents, Tasks, Epics
+ - **Communication:** Chat
+ - **Operations:** Services, Schedules, Usage
+ - **System:** Config, Repos
+- Footer: Add version/connection status indicator (small, muted).
+
+### Research Insights: shadcn/ui Sidebar Pattern
+
+shadcn/ui Sidebar uses dedicated CSS variables (`--sidebar-*`) that are independent from the main theme. This is already wired up in the Phase 1 color system. The sidebar should use:
+- `data-[active=true]` attribute for active nav items (not custom classes)
+- `SidebarMenuButton` component's built-in `isActive` prop
+- Tooltip on collapsed state (built into shadcn/ui Sidebar)
+
+**Header** (`app-header.tsx`):
+
+- Simplify: breadcrumbs + right-side actions (theme toggle, command menu trigger, health dot).
+- Health indicator: Simple green/red 6px circle. No animation. Tooltip on hover for details.
+- Remove excess spacing; header should feel tight and functional.
+
+**Main content area:**
+
+- Keep full-width for data-dense pages (agents, tasks grids need horizontal space).
+- Page padding: `px-6 py-6` desktop, `px-4 py-4` mobile.
+- Do NOT add `max-w-7xl` — data grids benefit from full width on wide monitors.
+
+**Files to modify:**
+- `src/components/layout/app-sidebar.tsx`
+- `src/components/layout/app-header.tsx`
+- `src/components/layout/root-layout.tsx`
+
+**Verification:**
+```bash
+cd new-ui && pnpm build
+pnpm dev # Visual inspection of sidebar/header at multiple widths
+# Check: sidebar active state uses bg-accent, not amber border
+# Check: sidebar collapse shows icon-only with tooltips
+# Check: header is clean, health dot is simple
+```
+
+---
+
+#### Phase 3: Core Shared Components
+
+**Goal:** Upgrade the visual quality of reusable components.
+
+**Stats Display** (`stats-bar.tsx`) — **Complete rewrite:**
+
+- **Remove hexagonal clip-paths entirely.** Replace with a clean card grid.
+- Use a row of compact stat cards: `grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 gap-3`.
+- Each stat card: small icon + large number + label. No colored borders — keep it clean.
+- Numbers in `font-mono tabular-nums text-2xl font-bold`.
+- Labels in `text-xs text-muted-foreground uppercase tracking-wider`.
+- **Sparklines/trends: OUT OF SCOPE** — `StatsBarProps` has no historical data, adding it requires API changes.
+- Remove breathing animation — stats are static numbers.
+
+```tsx
+// stats-bar.tsx — simplified stat card
+function StatCard({ icon: Icon, label, value, trend }: StatCardProps) {
+ return (
+
+
+
+
+ {label}
+
+
+
+ {value}
+
+ {trend && (
+ 0 ? "text-emerald-500" : "text-red-500"
+ )}>
+ {trend > 0 ? "+" : ""}{trend}%
+
+ )}
+
+
+
+ );
+}
+```
+
+**Status Badges** (`status-badge.tsx`):
+
+- Keep the color-coded system but refine:
+ - Use shadcn/ui `Badge` with variant `outline` as base.
+ - Active states (busy, in_progress): subtle `animate-pulse` on a small dot next to the text, not the whole badge.
+ - Text: `text-[11px] font-medium` (not bold + uppercase + tracking-wide).
+ - Small colored dot (6px `rounded-full`) before the text.
+
+```tsx
+// status-badge.tsx — refined
+const statusConfig = {
+ idle: { dot: "bg-emerald-500", text: "text-emerald-600 dark:text-emerald-400" },
+ busy: { dot: "bg-amber-500 animate-pulse", text: "text-amber-600 dark:text-amber-400" },
+ offline: { dot: "bg-zinc-400", text: "text-zinc-500 dark:text-zinc-400" },
+ pending: { dot: "bg-yellow-500", text: "text-yellow-600 dark:text-yellow-400" },
+ in_progress: { dot: "bg-amber-500 animate-pulse", text: "text-amber-600 dark:text-amber-400" },
+ completed: { dot: "bg-emerald-500", text: "text-emerald-600 dark:text-emerald-400" },
+ failed: { dot: "bg-red-500", text: "text-red-600 dark:text-red-400" },
+ cancelled: { dot: "bg-zinc-400", text: "text-zinc-500 dark:text-zinc-400" },
+} as const;
+
+function StatusBadge({ status }: { status: string }) {
+ const config = statusConfig[status] ?? statusConfig.offline;
+ return (
+
+
+ {status.replace("_", " ")}
+
+ );
+}
+```
+
+**Data Grid** (`data-grid.tsx` + `ag-grid.css`):
+
+### Research Insights: AG Grid v35 Theming
+
+AG Grid v35 supports a JS theme API alongside CSS variables. Use CSS variables for the color overrides since they integrate with the shadcn/ui CSS variable system:
+
+```css
+/* ag-grid.css — neutral theme overrides */
+.ag-theme-quartz,
+.ag-theme-quartz-dark {
+ /* Map to shadcn/ui CSS vars */
+ --ag-background-color: var(--background);
+ --ag-foreground-color: var(--foreground);
+ --ag-header-background-color: var(--muted);
+ --ag-header-foreground-color: var(--muted-foreground);
+ --ag-odd-row-background-color: transparent;
+ --ag-row-hover-color: var(--accent);
+ --ag-selected-row-background-color: var(--accent);
+ --ag-border-color: var(--border);
+ --ag-secondary-border-color: var(--border);
+ --ag-font-family: "Space Grotesk", system-ui, sans-serif;
+ --ag-font-size: 13px;
+ --ag-header-column-resize-handle-color: var(--border);
+ --ag-range-selection-border-color: var(--primary);
+}
+```
+
+This approach ties AG Grid's colors directly to the shadcn/ui theme vars, so dark/light mode switching works automatically.
+
+**Empty States** (`empty-state.tsx`):
+
+- Add illustration or icon + title + description + optional CTA button.
+- Center vertically in the available space.
+- Muted colors, clean design.
+
+**Also in Phase 3: Remove hive token aliases from globals.css**
+
+After AG Grid is rethemed to use standard semantic tokens, the temporary `--color-hive-*` aliases from Phase 1a are no longer needed. Remove them:
+```bash
+grep -n "TEMPORARY ALIASES" src/styles/globals.css
+# Remove the entire alias block
+```
+
+**Type safety improvements (while touching these files):**
+- `StatusBadge`: Use `satisfies Record` for the config map
+- Stats bar: Replace `color?: string` prop with `variant?: "amber" | "emerald" | "blue" | "red" | "yellow" | "zinc"`
+- Standardize on `cn()` for all conditional class merging
+
+**Files to modify:**
+- `src/components/shared/stats-bar.tsx` — Rewrite
+- `src/components/shared/status-badge.tsx` — Refine
+- `src/components/shared/data-grid.tsx` — Retheme
+- `src/components/shared/empty-state.tsx` — Polish
+- `src/styles/ag-grid.css` — Neutral palette (use semantic CSS vars)
+- `src/styles/globals.css` — Remove hive aliases
+
+**Verification:**
+```bash
+cd new-ui && pnpm build
+pnpm dev # Check dashboard stats, agent/task grids, empty states
+# Verify: AG Grid colors match theme in both dark and light mode
+# Verify: status badges use dot pattern, not full-bg color
+# Verify: no more hive aliases in globals.css
+grep -rE "color-hive-" src/ --include="*.css" --include="*.tsx"
+# Should return 0 results
+```
+
+---
+
+#### Phase 4: Page-by-Page Visual Polish
+
+**Goal:** Update each page to use the new design system consistently.
+
+### Research Insights: Systematic Approach
+
+Instead of editing 13 files individually, use a systematic grep-and-replace strategy:
+
+**Step 1: Global search-and-replace** for common patterns across all pages:
+```bash
+# Find all amber hardcoded references
+grep -rn "amber-\|hive-\|text-amber\|bg-amber\|border-amber" src/pages/ --include="*.tsx"
+
+# Find all font-display (Graduate) references
+grep -rn "font-display" src/pages/ --include="*.tsx"
+
+# Find all glow/animation references
+grep -rn "glow\|breathe\|heartbeat\|pulse-amber" src/pages/ --include="*.tsx"
+```
+
+**Step 2: Replace patterns:**
+- `text-amber-500` → `text-primary` (uses CSS var, adapts to theme)
+- `bg-amber-500` → `bg-primary`
+- `border-amber-500/30` → `border-border`
+- `text-hive-amber` → `text-primary`
+- `font-display` → `font-sans font-semibold` (or just remove, use default)
+- `text-2xl` page titles → `text-xl`
+- Any amber icon color (`text-amber-400/500`) → `text-muted-foreground` (for decorative icons) or `text-primary` (for interactive icons)
+
+### Token Mapping Table (for systematic replacement)
+
+| Old Pattern | New Pattern | Context |
+|-------------|-------------|---------|
+| `text-hive-amber` | `text-primary` | Brand accent text |
+| `border-hive-amber` | `border-primary` | Brand accent border |
+| `bg-amber-600 hover:bg-amber-700` | `bg-primary hover:bg-primary/90` | Primary action buttons |
+| `text-amber-400` (icons) | `text-muted-foreground` | Decorative icons in cards |
+| `text-amber-400` (links) | `text-primary` | Interactive links |
+| `bg-amber-500/15 text-amber-400` | `bg-primary/15 text-primary` | Active channel highlight |
+| `bg-amber-500/20 text-amber-400` | `bg-muted text-muted-foreground` | Chat avatar circles |
+| `bg-amber-500` (progress) | `bg-primary` | Progress bars |
+| `hover:border-amber-500/30` | `hover:border-primary/30` | Card hover effect |
+| `font-display text-2xl font-bold` | `text-xl font-semibold` | Page titles (21 occurrences!) |
+| `hover:text-hive-amber` | `hover:text-primary` | Sidebar hover |
+| `#f59e0b` (chart) | `var(--chart-1)` via Recharts | Chart colors |
+| `#18181b` (tooltip bg) | CSS var reference | Recharts tooltip |
+
+**Step 3: Sub-phased page updates**
+
+**Phase 4a: Dashboard + list pages** (agents, tasks, epics, services, schedules, repos)
+- Apply token mapping table globally across these files
+- These are mostly grids + filter toolbars — changes are mechanical
+
+**Phase 4b: Detail pages** (agents/[id], tasks/[id], epics/[id], schedules/[id])
+- Apply token mapping table
+- Task detail: terminal-styled log block (dark bg with `bg-zinc-950` and neutral text)
+- Metadata sections: clean key-value pairs
+
+**Phase 4c: Chat + Usage + Config** (most complex pages)
+- Chat: avatar circles, send button, active channel highlight, message styling
+- Usage: hardcoded `CHART_COLORS` array → use `--chart-*` CSS vars. Replace `background: "#18181b"` tooltip styles with CSS var references.
+- Config: connection status, form styling
+
+**Phase 4d: Consolidate status color maps**
+- Extract `services/page.tsx:statusColors` and `dashboard/page.tsx:eventColors` to use shared constants or route through StatusBadge
+
+**Verification gates between sub-phases:**
+```bash
+# After each sub-phase:
+cd new-ui && pnpm build
+pnpm dev # Visual check of affected pages
+grep -rn "amber-[0-9]\|hive-\|#f5a623\|#ffb84d\|#d4a574\|#c67c00" src/pages/ --include="*.tsx"
+```
+
+**Files to modify:**
+- All files in `src/pages/` (13 page components)
+- Focus on: replacing amber hardcodes with CSS var references, consistent spacing
+
+**Verification (final):**
+```bash
+cd new-ui && pnpm build
+pnpm dev # Navigate through all pages, check visual consistency
+# Verify no remaining hardcoded amber:
+grep -rn "amber-[0-9]\|hive-\|#f5a623\|#ffb84d\|#d4a574\|#c67c00\|font-display" src/pages/ --include="*.tsx"
+# Should return 0 results
+```
+
+---
+
+#### Phase 5: Animations & Micro-interactions
+
+**Goal:** Replace decorative animations with purposeful transitions.
+
+**Remove from `globals.css`:**
+```css
+/* DELETE these keyframes */
+@keyframes breathe { ... }
+@keyframes pulse-amber { ... }
+@keyframes heartbeat { ... }
+```
+
+**Keep (already in Tailwind):**
+- `animate-pulse` — Only on actively in-progress status badge dots
+- `animate-spin` — For loading spinners
+
+**Hover transitions** — add to `globals.css`:
+```css
+/* Minimal utility for interactive element transitions */
+.transition-default {
+ @apply transition-colors duration-150 ease-in-out;
+}
+```
+
+Actually, don't add a custom class. Just use Tailwind's built-in `transition-colors duration-150` directly in components. Fewer abstractions.
+
+**Skeleton loading:** shadcn/ui `Skeleton` component already has a shimmer animation. Use it for loading states in data grids and stat cards.
+
+**Files to modify:**
+- `src/styles/globals.css` — Remove animation keyframes
+- `src/components/shared/status-badge.tsx` — Ensure pulse only on dot, not whole badge
+
+**Verification:**
+```bash
+cd new-ui && pnpm build
+pnpm dev # Test interactions, hover states, loading states
+# Verify no breathing/heartbeat animations remain:
+grep -rn "breathe\|heartbeat\|pulse-amber" src/ --include="*.tsx" --include="*.ts" --include="*.css"
+```
+
+---
+
+#### Phase 6: Dark/Light Mode Consistency & Responsive Polish
+
+**Goal:** Ensure both themes look great and responsive works well.
+
+**Dark mode** (primary experience):
+
+- The Zinc theme values from Phase 1 handle dark mode automatically via the `.dark` class.
+- Key contrast check: `--primary` (amber-500, oklch 0.769) on `--background` (oklch 0.141) = sufficient contrast.
+- `--muted-foreground` (oklch 0.705) on `--background` (oklch 0.141) = contrast ratio ~5:1, passes WCAG AA.
+- Borders at `oklch(1 0 0 / 10%)` provide subtle separation without harsh lines.
+
+**Light mode:**
+
+- `--primary` in light mode is amber-700 (oklch 0.555), darker for contrast on white.
+- Verify card borders (`oklch(0.92 0.004 286.32)`) are visible but subtle.
+
+**Responsive:**
+
+- Test at 320px, 768px, 1024px, 1440px, 1920px.
+- Sidebar: Fully collapsed/hidden on mobile, expandable via trigger (built into shadcn/ui Sidebar).
+- Stats grid: 2 cols on mobile, 4-5 on desktop.
+- AG Grid: Horizontal scroll on mobile, full view on desktop.
+- Chat: Full-width on mobile, split view on desktop.
+
+**Accessibility:**
+
+- Focus rings: shadcn/ui default ring uses `--ring` CSS var (set to match `--primary` in our palette).
+- Color contrast: The Zinc palette is designed for WCAG AA compliance.
+- Touch targets: Minimum 44x44px on mobile for buttons and nav items (check sidebar items).
+
+**Files to modify:**
+- `src/styles/globals.css` — Final audit of dark/light variables
+- Various components — Responsive class adjustments if needed
+
+**Verification:**
+```bash
+cd new-ui && pnpm build
+pnpm dev
+# Test both themes (toggle via header button)
+# Test at: 320px, 768px, 1024px, 1440px, 1920px viewport widths
+# Run Lighthouse audit for accessibility score
+```
+
+---
+
+## Acceptance Criteria
+
+### Functional Requirements
+
+- [ ] All existing pages render correctly with no visual regressions in functionality
+- [ ] Dark mode and light mode both look polished and consistent
+- [ ] AG Grid data grids are readable and well-styled in both themes
+- [ ] Status badges clearly communicate state with semantic colors
+- [ ] Navigation is intuitive with clear active state indication
+- [ ] Charts/visualizations use shadcn/ui chart color tokens (`--chart-1` through `--chart-5`)
+- [ ] Command palette (Cmd+K) works correctly with new styling
+
+### Visual Quality
+
+- [ ] No honeycomb SVG backgrounds anywhere
+- [ ] No hexagonal clip-path shapes
+- [ ] No Graduate display font
+- [ ] No amber glow effects (text-shadow or box-shadow)
+- [ ] No breathing/heartbeat animations on static elements
+- [ ] No `--color-hive-*` or `--color-terminal-*` CSS variables
+- [ ] Amber/gold used only via `--primary` CSS variable, not hardcoded hex
+- [ ] Consistent spacing and typography scale across all pages
+- [ ] Professional appearance suitable for a monitoring/ops dashboard
+
+### Non-Functional Requirements
+
+- [ ] Build succeeds with no TypeScript errors (`pnpm build`)
+- [ ] No unused CSS classes or imports
+- [ ] Performance: No visible jank from CSS changes
+- [ ] Responsive: Works at 320px through 1920px widths
+- [ ] Accessibility: WCAG AA contrast ratios on text
+- [ ] Font loading: Only Space Grotesk + Space Mono (no Graduate)
+
+## Success Metrics
+
+- The dashboard looks like it could be a product page for a YC startup — clean, professional, distinctive
+- A screenshot of any page could be shared publicly without embarrassment
+- New users can immediately understand status at a glance through color and layout alone
+- The design feels native to shadcn/ui, not like a ported theme
+
+## Dependencies & Risks
+
+**Dependencies:**
+- No external dependencies added. All changes use existing packages.
+- shadcn/ui components are already installed.
+
+**Risks:**
+- **Scope creep** — Phase 4 (page-by-page) is the largest. The systematic grep approach mitigates this — most changes are mechanical find-replace.
+- **AG Grid theming** — Mapping AG Grid CSS vars to shadcn/ui CSS vars is the key insight. Test with real data to verify colors render correctly.
+- **oklch browser support** — oklch is supported in all modern browsers (Chrome 111+, Firefox 113+, Safari 15.4+). Not a concern for a developer tool dashboard.
+- **Color accessibility** — The Zinc palette from shadcn/ui is pre-tested for WCAG AA. Our amber accent choices (amber-500 dark, amber-700 light) also pass.
+
+## Sources & References
+
+### Internal References
+- Old UI theme: `ui/src/lib/theme.ts`, `ui/src/index.css`
+- New UI styles: `new-ui/src/styles/globals.css`, `new-ui/src/styles/ag-grid.css`
+- Layout: `new-ui/src/components/layout/`
+- Shared components: `new-ui/src/components/shared/`
+- All pages: `new-ui/src/pages/`
+
+### External References (from Context7 research)
+- shadcn/ui v4 theming (Zinc theme): https://ui.shadcn.com/docs/theming
+- shadcn/ui Sidebar CSS variables: https://ui.shadcn.com/docs/components/sidebar
+- shadcn/ui Chart color tokens: https://ui.shadcn.com/docs/components/chart
+- Tailwind CSS v4 colors (oklch): https://tailwindcss.com/docs/colors
+- Tailwind CSS v4 `@theme` directive: https://tailwindcss.com/docs/theme
+- AG Grid React theming: https://ag-grid.com/react-data-grid/theming-colors
+- AG Grid CSS variable customization: https://ag-grid.com/react-data-grid/theming-v32-customisation
+
+### Design Inspiration
+- Linear (linear.app) — Clean sidebar, neutral palette, subtle animations
+- Vercel Dashboard — Information density, dark mode as primary
+- Raycast — Typography hierarchy, status indicators
+
+## Manual E2E Verification
+
+After all phases:
+
+```bash
+cd new-ui
+
+# Build check
+pnpm build
+
+# Start dev server
+pnpm dev
+
+# Open in browser and verify each page:
+# http://localhost:5274/ — Dashboard with stats, activity feed
+# http://localhost:5274/agents — Agent grid with filters
+# http://localhost:5274/agents/ — Agent detail with tabs
+# http://localhost:5274/tasks — Task grid with filters
+# http://localhost:5274/tasks/ — Task detail with logs
+# http://localhost:5274/epics — Epics grid
+# http://localhost:5274/chat — Chat with channels
+# http://localhost:5274/services — Services grid
+# http://localhost:5274/schedules — Schedules grid
+# http://localhost:5274/usage — Charts and analytics
+# http://localhost:5274/config — Config panel
+# http://localhost:5274/repos — Repos grid
+
+# Test both themes (toggle via header button)
+# Test sidebar collapse/expand
+# Test Cmd+K command palette
+# Test at mobile viewport (320px) and desktop (1920px)
+
+# Verify no CSS remnants:
+grep -r "honeycomb\|glow-amber\|glow-gold\|Graduate\|hex-border\|grain-overlay\|breathe\|heartbeat\|pulse-amber\|hive-\|terminal-\|font-display\|clip-hex" src/ --include="*.tsx" --include="*.ts" --include="*.css"
+# Should return 0 results
+```
diff --git a/thoughts/taras/research/2026-02-25-dashboard-ui-design-best-practices.md b/thoughts/taras/research/2026-02-25-dashboard-ui-design-best-practices.md
new file mode 100644
index 0000000..90f3ff2
--- /dev/null
+++ b/thoughts/taras/research/2026-02-25-dashboard-ui-design-best-practices.md
@@ -0,0 +1,825 @@
+---
+date: 2026-02-25T12:00:00Z
+topic: "Modern Dashboard UI Design Best Practices (2025-2026)"
+---
+
+# Modern Dashboard UI Design Best Practices (2025-2026)
+
+Research date: 2026-02-25
+Context: Agent Swarm monitoring dashboard redesign, moving from MUI Joy + amber/beehive theme to a modern, polished design system.
+
+---
+
+## Table of Contents
+
+1. [Color Palette Design for Dark-Mode-First Dashboards](#1-color-palette-design)
+2. [Visual Hierarchy, Spacing, and Typography](#2-visual-hierarchy-spacing-typography)
+3. [shadcn/ui + Tailwind CSS v4 Dashboard Patterns](#3-shadcn-tailwind-v4)
+4. [AG Grid Theming Best Practices](#4-ag-grid-theming)
+5. [Sidebar Navigation Design Patterns](#5-sidebar-navigation)
+6. [Status Indicators and Badge Design](#6-status-indicators)
+7. [Card vs Table Layouts for Monitoring](#7-card-vs-table-layouts)
+8. [Micro-Animations and Transitions](#8-micro-animations)
+9. [Reference Dashboards and Design Systems](#9-reference-dashboards)
+10. [Concrete Recommendations for Agent Swarm](#10-agent-swarm-recommendations)
+
+---
+
+## 1. Color Palette Design
+
+### Moving Beyond Amber/Gold
+
+The current Agent Swarm UI uses a warm amber/honey/gold palette (#F5A623 primary, #D4A574 gold, #0d0906 body). While thematic ("beehive"), this approach has several issues:
+
+- Amber/warm tones on dark backgrounds produce a "dated" or "retro terminal" aesthetic
+- Limited semantic range: amber already means "warning" in most color systems, so using it as a primary creates confusion
+- The warm brown surfaces (#1a130e, #251c15) reduce contrast compared to neutral darks
+
+### Modern Dark Mode Color Theory
+
+**Source: Material Design, Linear, Vercel Geist, shadcn/ui defaults**
+
+The industry consensus in 2025-2026:
+
+1. **Use near-black neutrals, not pure black or tinted blacks**
+ - Pure #000000 is too harsh and eliminates elevation perception
+ - Tinted blacks (like the current #0d0906 warm brown) bias the entire palette
+ - Best practice: neutral grays with very slight cool or warm tint
+
+2. **OKLCH color space** is the new standard for generating perceptually uniform palettes
+ - Linear migrated to LCH for theme generation
+ - shadcn/ui now uses OKLCH as default format
+ - Key advantage: changing lightness doesn't cause hue/saturation drift
+
+3. **Layered darkness for elevation** (Material Design principle)
+ - Base: #09111A to #121212 range
+ - Surface +1: 5% lighter (cards, panels)
+ - Surface +2: 8-10% lighter (popovers, dropdowns)
+ - Surface +3: 12-15% lighter (elevated modals)
+
+### Recommended Dark Palette: Cool Neutral
+
+A cool neutral palette that doesn't commit to a strong brand hue, keeping the focus on content:
+
+```css
+/* === BACKGROUNDS (layered darkness) === */
+--background: oklch(0.145 0 0); /* ~#0a0a0a - page base */
+--surface-1: oklch(0.175 0.005 270); /* ~#111318 - cards, panels */
+--surface-2: oklch(0.21 0.006 270); /* ~#181b22 - elevated cards */
+--surface-3: oklch(0.25 0.007 270); /* ~#1f2330 - popovers, modals */
+
+/* === BORDERS === */
+--border: oklch(1 0 0 / 8%); /* subtle white overlay */
+--border-strong: oklch(1 0 0 / 14%); /* active/focused borders */
+
+/* === TEXT === */
+--text-primary: oklch(0.985 0 0); /* ~#fafafa - headings, primary */
+--text-secondary: oklch(0.71 0.01 270); /* ~#a1a1aa - descriptions */
+--text-tertiary: oklch(0.55 0.01 270); /* ~#71717a - timestamps, hints */
+--text-muted: oklch(0.45 0.01 270); /* ~#52525b - disabled text */
+```
+
+### Accent Color: Moving to Blue-Indigo
+
+Instead of amber as the primary accent, use a blue-indigo which:
+- Is universally understood as "interactive/clickable"
+- Provides clear contrast against warm semantic colors (success green, warning amber, error red)
+- Works well for selection highlights, links, and focus rings
+
+```css
+/* === ACCENT (Blue-Indigo) === */
+--accent: oklch(0.62 0.19 264); /* ~#6366f1 - indigo-500 */
+--accent-hover: oklch(0.56 0.21 264); /* ~#4f46e5 - indigo-600 */
+--accent-muted: oklch(0.62 0.19 264 / 15%); /* selection backgrounds */
+--accent-foreground: oklch(0.985 0 0); /* white text on accent */
+
+/* === SEMANTIC COLORS === */
+/* Success - Emerald */
+--success: oklch(0.70 0.17 162); /* ~#10b981 - emerald-500 */
+--success-muted: oklch(0.70 0.17 162 / 15%);
+
+/* Warning - Amber (now properly semantic, not primary) */
+--warning: oklch(0.75 0.18 80); /* ~#f59e0b - amber-500 */
+--warning-muted: oklch(0.75 0.18 80 / 15%);
+
+/* Error/Destructive - Red */
+--error: oklch(0.63 0.21 25); /* ~#ef4444 - red-500 */
+--error-muted: oklch(0.63 0.21 25 / 15%);
+
+/* Info - Sky Blue */
+--info: oklch(0.68 0.14 230); /* ~#38bdf8 - sky-400 */
+--info-muted: oklch(0.68 0.14 230 / 15%);
+```
+
+### Alternative Accent: Teal-Cyan
+
+If indigo feels too "generic", teal-cyan is a distinctive alternative that's popular in monitoring/DevOps tools (Datadog, Grafana):
+
+```css
+--accent: oklch(0.72 0.15 190); /* ~#14b8a6 - teal-500 */
+--accent-hover: oklch(0.66 0.16 190); /* ~#0d9488 - teal-600 */
+```
+
+### Chart Colors (5-color data visualization palette)
+
+```css
+--chart-1: oklch(0.62 0.19 264); /* indigo - primary series */
+--chart-2: oklch(0.70 0.17 162); /* emerald - secondary */
+--chart-3: oklch(0.68 0.14 230); /* sky blue */
+--chart-4: oklch(0.72 0.16 310); /* purple/violet */
+--chart-5: oklch(0.75 0.18 80); /* amber */
+```
+
+---
+
+## 2. Visual Hierarchy, Spacing, and Typography
+
+### Typography
+
+**Source: Linear redesign, font pairing research, data-dense UI studies**
+
+**Recommendation: Inter + JetBrains Mono (or Geist Sans + Geist Mono)**
+
+| Use Case | Font | Weight | Size |
+|---|---|---|---|
+| Page titles | Inter Display (or Inter) | 600 | 20-24px |
+| Section headings | Inter | 600 | 16-18px |
+| Card titles | Inter | 500 | 14-15px |
+| Body text | Inter | 400 | 13-14px |
+| Table data | Inter (tabular nums) | 400 | 13px |
+| Code/IDs/timestamps | JetBrains Mono | 400 | 12-13px |
+| Badges/labels | Inter | 600 | 11-12px (UPPERCASE, 0.05em tracking) |
+
+Key insight from research: **Use tabular numerals in proportional fonts for numeric data** rather than monospace. Monospace is overkill for numbers. Inter supports `font-variant-numeric: tabular-nums` which gives aligned columns with better readability.
+
+Current UI uses Space Grotesk + Space Mono. These are fine fonts but:
+- Space Grotesk has a more "playful" personality than a monitoring dashboard warrants
+- Inter is the industry standard for data-dense UIs (Linear, Vercel, shadcn, Raycast all use it)
+
+### Spacing Scale
+
+Follow the Tailwind 4px grid (each unit = 0.25rem = 4px):
+
+```
+Micro: 4px (gap between icon and label)
+Small: 8px (gap between related items, padding in small components)
+Medium: 12px (card internal padding, gap between list items)
+Regular: 16px (standard content padding)
+Large: 24px (section gaps, card padding)
+XLarge: 32px (page-level section spacing)
+XXLarge: 48px (major layout divisions)
+```
+
+**Dashboard-specific spacing rules:**
+- Card padding: 16px (p-4) for standard, 20px (p-5) for featured cards
+- Gap between cards in a grid: 16px (gap-4)
+- Sidebar width: 240px expanded, 48px collapsed (icon-only)
+- Tab bar height: 40px
+- Table row height: 40-44px for data density without feeling cramped
+- Header height: 48-56px
+
+### Visual Hierarchy Principles
+
+1. **Size contrast for emphasis**: Titles 20-24px, body 13-14px (1.5-1.8x ratio)
+2. **Color contrast for importance**: Primary text (#fafafa) vs secondary (#a1a1aa) - clear 2-level system
+3. **Weight contrast for scanability**: 600 weight for headings/labels, 400 for body
+4. **Spatial grouping**: Related content is 8-12px apart; unrelated content 24-32px apart
+5. **Border-free elevation**: Use background color differences instead of visible borders where possible (Linear's approach)
+
+---
+
+## 3. shadcn/ui + Tailwind CSS v4 Dashboard Patterns
+
+### Tailwind v4 Architecture
+
+Tailwind v4 fundamentally changes how you configure themes:
+
+```css
+/* No more tailwind.config.js - everything in CSS */
+@import "tailwindcss";
+
+@theme {
+ /* Design tokens become CSS variables that auto-generate utilities */
+ --color-background: oklch(0.145 0 0);
+ --color-surface: oklch(0.175 0.005 270);
+ --color-accent: oklch(0.62 0.19 264);
+
+ --spacing-xs: 0.25rem;
+ --spacing-sm: 0.5rem;
+ --spacing-md: 0.75rem;
+ --spacing-lg: 1rem;
+
+ --font-sans: "Inter", system-ui, sans-serif;
+ --font-mono: "JetBrains Mono", monospace;
+
+ --radius-sm: 0.375rem;
+ --radius-md: 0.5rem;
+ --radius-lg: 0.75rem;
+}
+```
+
+### Three-Layer Token Hierarchy (Best Practice)
+
+```css
+/* Layer 1: Base (raw palette) */
+--color-gray-50: oklch(0.985 0 0);
+--color-gray-100: oklch(0.95 0.003 270);
+--color-gray-900: oklch(0.21 0.006 270);
+--color-gray-950: oklch(0.145 0 0);
+
+/* Layer 2: Semantic (maps to purpose) */
+--color-background: var(--color-gray-950);
+--color-foreground: var(--color-gray-50);
+--color-muted: var(--color-gray-900);
+--color-muted-foreground: var(--color-gray-400);
+
+/* Layer 3: Component (variant-specific) */
+--sidebar-background: var(--color-gray-900);
+--sidebar-foreground: var(--color-gray-50);
+--card-background: var(--color-surface);
+```
+
+Never skip the semantic layer -- it's what makes refactors safe.
+
+### shadcn/ui Default Dark Theme (Reference)
+
+As of 2025-2026, shadcn/ui uses OKLCH by default:
+
+```css
+.dark {
+ --background: oklch(0.145 0 0);
+ --foreground: oklch(0.985 0 0);
+ --card: oklch(0.205 0 0);
+ --card-foreground: oklch(0.985 0 0);
+ --popover: oklch(0.205 0 0);
+ --popover-foreground: oklch(0.985 0 0);
+ --primary: oklch(0.92 0.004 286.32);
+ --primary-foreground: oklch(0.21 0.006 285.885);
+ --secondary: oklch(0.274 0.006 286.033);
+ --secondary-foreground: oklch(0.985 0 0);
+ --muted: oklch(0.274 0.006 286.033);
+ --muted-foreground: oklch(0.705 0.015 286.067);
+ --accent: oklch(0.274 0.006 286.033);
+ --accent-foreground: oklch(0.985 0 0);
+ --destructive: oklch(0.704 0.191 22.216);
+ --border: oklch(1 0 0 / 10%);
+ --input: oklch(1 0 0 / 15%);
+ --ring: oklch(0.552 0.016 285.938);
+ --sidebar: oklch(0.21 0.006 285.885);
+ --sidebar-foreground: oklch(0.985 0 0);
+ --sidebar-primary: oklch(0.488 0.243 264.376);
+ --sidebar-primary-foreground: oklch(0.985 0 0);
+ --sidebar-accent: oklch(0.274 0.006 286.033);
+ --sidebar-accent-foreground: oklch(0.985 0 0);
+ --sidebar-border: oklch(1 0 0 / 10%);
+}
+```
+
+### Essential shadcn Components for Dashboards
+
+- **Card** -- metric containers, KPI displays
+- **DataTable** -- powered by TanStack Table, sorting/filtering/pagination built in
+- **Sidebar** -- collapsible navigation with icon-only mode
+- **Tabs** -- content section switching
+- **Badge** -- status indicators
+- **Sheet** -- mobile-responsive slide-in panels
+- **Command** -- command palette (Cmd+K)
+- **Chart** -- built on Recharts, inherits theme colors
+
+---
+
+## 4. AG Grid Theming Best Practices
+
+### Modern AG Grid Theming API
+
+AG Grid's Theming API (v31+) uses `themeQuartz` with `withParams`:
+
+```typescript
+import { themeQuartz, colorSchemeDark } from "ag-grid-community";
+
+const customDarkTheme = themeQuartz
+ .withPart(colorSchemeDark)
+ .withParams({
+ // Match your dashboard background
+ backgroundColor: "#111318",
+
+ // Match your text colors
+ foregroundColor: "#fafafa",
+
+ // Match your accent color
+ accentColor: "#6366f1",
+
+ // Borders -- subtle
+ borderColor: "rgba(255, 255, 255, 0.08)",
+
+ // Row alternation
+ oddRowBackgroundColor: "rgba(255, 255, 255, 0.02)",
+
+ // Header styling
+ headerBackgroundColor: "#0f1116",
+ headerTextColor: "#a1a1aa",
+ headerFontWeight: 600,
+ headerFontSize: 12,
+
+ // Cell text
+ cellTextColor: "#e4e4e7",
+ fontSize: 13,
+
+ // Selection
+ selectedRowBackgroundColor: "rgba(99, 102, 241, 0.12)",
+ rangeSelectionBorderColor: "#6366f1",
+
+ // Chrome (panels, toolbars)
+ chromeBackgroundColor: "#0f1116",
+
+ // Spacing
+ cellHorizontalPadding: 12,
+ rowHeight: 40,
+ headerHeight: 40,
+
+ // Borders
+ rowBorderColor: "rgba(255, 255, 255, 0.04)",
+ columnBorderColor: "transparent",
+
+ // Font
+ fontFamily: "'Inter', system-ui, sans-serif",
+ });
+```
+
+### Key AG Grid Dark Mode Principles
+
+1. **Match the grid background to your card/surface color** -- the grid should feel embedded, not floating
+2. **Reduce border prominence** -- use very subtle borders (4-8% white opacity) or eliminate column borders entirely
+3. **Dim the header** -- header should be slightly darker than data rows, with muted text color
+4. **Use subtle row alternation** -- 2-3% white overlay for odd rows, not a visible color difference
+5. **Accent color for selection only** -- don't overuse the accent; let data be neutral
+6. **Match font to your dashboard** -- set fontFamily to match your UI typography
+7. **Consistent row height** -- 40px is the sweet spot for data density with touch-friendliness
+
+### Custom CSS Overrides for Polish
+
+```css
+/* Remove the outer grid border for seamless card integration */
+.ag-root-wrapper {
+ border: none !important;
+ border-radius: 0 !important;
+}
+
+/* Soften header separator */
+.ag-header {
+ border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
+}
+
+/* Status cell with colored dot */
+.ag-cell.status-cell {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+}
+
+/* Smooth hover transition */
+.ag-row:hover {
+ transition: background-color 150ms ease;
+}
+```
+
+---
+
+## 5. Sidebar Navigation Design Patterns
+
+### shadcn/ui Sidebar Architecture
+
+The shadcn sidebar component provides a battle-tested pattern:
+
+```
+SidebarProvider (manages state)
+ Sidebar (collapsible="icon" | "offcanvas" | "none")
+ SidebarHeader
+ Logo / App name (hidden when collapsed)
+ SidebarContent
+ SidebarGroup (label: "Navigation")
+ SidebarMenu
+ SidebarMenuItem -> SidebarMenuButton
+ SidebarGroup (label: "Management")
+ Collapsible
+ SidebarGroupLabel -> CollapsibleTrigger
+ CollapsibleContent
+ SidebarMenu -> items
+ SidebarFooter
+ User avatar / settings
+ SidebarRail (thin resize/toggle rail)
+```
+
+### Design Token Setup
+
+```css
+--sidebar-width: 16rem; /* 256px expanded */
+--sidebar-width-mobile: 18rem; /* 288px on mobile sheet */
+--sidebar-width-icon: 3rem; /* 48px collapsed */
+```
+
+### Navigation Grouping for Agent Swarm
+
+Recommended sidebar structure:
+
+```
+[Icon] Agent Swarm <- Logo/app name
+
+--- Core ---
+ Agents (Users icon)
+ Tasks (ListTodo icon)
+ Epics (Target icon)
+ Chat (MessageSquare icon)
+
+--- System ---
+ Services (Server icon)
+ Schedules (Clock icon)
+ Repos (GitBranch icon)
+
+--- Analytics ---
+ Usage (BarChart3 icon)
+
+--- Bottom (footer) ---
+ Config (Settings icon)
+ Theme toggle (Sun/Moon icon)
+```
+
+### Collapse Behavior
+
+1. **Desktop**: Default expanded, user can collapse to icon-only mode
+2. **Collapsed mode**: Show only icons (24px), tooltip on hover for label
+3. **Mobile**: Off-canvas sheet that slides in from left
+4. **Active state**: Highlighted with accent-muted background + accent left border or indicator dot
+5. **Persist state**: Store collapse preference in localStorage
+
+### Active Item Styling
+
+```css
+/* Active nav item */
+.nav-item-active {
+ background: oklch(0.62 0.19 264 / 12%); /* accent at 12% opacity */
+ color: oklch(0.75 0.15 264); /* lighter accent for text */
+ border-left: 2px solid oklch(0.62 0.19 264);
+ font-weight: 500;
+}
+
+/* Hover state */
+.nav-item:hover {
+ background: oklch(1 0 0 / 5%);
+}
+```
+
+---
+
+## 6. Status Indicators and Badge Design
+
+### Semantic Status Colors
+
+**Source: Carbon Design System, Material Design, AIA Qi Design System, industry consensus**
+
+For a monitoring dashboard, define status by semantic meaning, not arbitrary colors:
+
+| Status | Color | Hex (Dark Mode) | OKLCH | Use Case |
+|---|---|---|---|---|
+| Success/Online/Completed | Emerald | #10b981 | oklch(0.70 0.17 162) | Healthy, done, active |
+| Warning/Busy/In Progress | Amber | #f59e0b | oklch(0.75 0.18 80) | Attention needed |
+| Error/Failed | Red | #ef4444 | oklch(0.63 0.21 25) | Critical, broken |
+| Info/Reviewing | Blue | #3b82f6 | oklch(0.62 0.16 255) | Informational |
+| Neutral/Offline/Cancelled | Gray | #71717a | oklch(0.55 0.01 270) | Inactive, disabled |
+| Special/Offered | Violet | #8b5cf6 | oklch(0.58 0.22 293) | Queued, pending action |
+
+### Badge Design Pattern
+
+```tsx
+// Minimal badge - colored dot + uppercase label
+
+
+ Online
+
+```
+
+### Design Rules for Status Badges
+
+1. **Use a colored dot + text** -- never rely on color alone (accessibility)
+2. **Background at 10-15% opacity** of the status color -- just enough to create a "pill"
+3. **Border at 15-20% opacity** -- adds definition without heaviness
+4. **Text in a lighter shade** of the status color (400 weight in Tailwind scale)
+5. **Uppercase, small, tracked** -- 11-12px, font-weight 600, letter-spacing 0.05em
+6. **Monospace or tabular font** not needed for badges -- use the UI font
+7. **Animated pulse only for truly active states** -- "in_progress" and "busy" only, not everything
+
+### Dot Indicator Patterns
+
+For compact spaces (table cells, sidebar), use dot-only indicators:
+
+```css
+/* Pulsing dot for active */
+.status-dot-active {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ background: #10b981;
+ box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4);
+ animation: pulse-ring 2s ease-out infinite;
+}
+
+@keyframes pulse-ring {
+ 0% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4); }
+ 70% { box-shadow: 0 0 0 6px rgba(16, 185, 129, 0); }
+ 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }
+}
+
+/* Static dot for stable states */
+.status-dot-static {
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+}
+```
+
+---
+
+## 7. Card vs Table Layouts for Monitoring
+
+### When to Use Each
+
+| Layout | Best For | Agent Swarm Context |
+|---|---|---|
+| **Card grid** | Aggregate stats, KPIs, individual entity detail | Stats bar (top), agent overview cards, epic cards |
+| **Data table** | Large lists, sortable/filterable data, homogeneous items | Tasks list, agent list (when many), services registry |
+| **Hybrid** | Master-detail patterns | Agent list (table) + detail panel (cards) |
+
+### Card Layout Best Practices
+
+- **Maximum 5-6 cards** in initial viewport -- don't overwhelm
+- **Consistent card dimensions** within a row
+- **KPI cards**: Large number (24-32px), label below (12-13px muted), optional sparkline
+- **Entity cards**: Title, 2-3 key properties, status badge, timestamp
+- **Card padding**: 16-20px, border-radius 8-12px
+- **Card hover**: Subtle border glow or slight background lighten (not scale transform)
+
+### KPI Card Example
+
+```tsx
+
+
+
+ Active Agents
+
+
+
+
12
+
+ +3 from last hour
+
+
+```
+
+### Table Layout Best Practices
+
+- **Row height**: 40-44px -- compact but not cramped
+- **Horizontal padding**: 12-16px per cell
+- **No visible column dividers** -- use spacing and alignment instead
+- **Subtle row hover**: 3-5% white overlay on hover
+- **Row alternation**: Optional, very subtle (2% white overlay)
+- **Sticky header**: Always visible when scrolling
+- **Truncation**: Ellipsis with tooltip for long text, never wrap table text
+
+---
+
+## 8. Micro-Animations and Transitions
+
+### Timing Constants
+
+```css
+:root {
+ --duration-fast: 100ms; /* instant feedback (button press) */
+ --duration-normal: 200ms; /* standard transitions */
+ --duration-slow: 300ms; /* panel open/close */
+ --duration-enter: 200ms; /* elements appearing */
+ --duration-exit: 150ms; /* elements disappearing (faster = snappier) */
+
+ --ease-default: cubic-bezier(0.4, 0, 0.2, 1); /* general purpose */
+ --ease-in: cubic-bezier(0.4, 0, 1, 1); /* accelerate */
+ --ease-out: cubic-bezier(0, 0, 0.2, 1); /* decelerate */
+ --ease-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275); /* bouncy */
+}
+```
+
+### Where to Animate (and Where NOT to)
+
+**Do animate:**
+- Sidebar collapse/expand (width transition, 200ms)
+- Panel slide-in (transform translateX, 200ms ease-out)
+- Tab content switch (opacity fade, 150ms)
+- Hover states (background-color, 150ms)
+- Status dot pulse (only for active states, 2s infinite)
+- Toast/notification entrance (slide up + fade, 200ms)
+- Skeleton loading pulse (1.5s infinite)
+- Row hover highlight (background-color, 100ms)
+
+**Do NOT animate:**
+- Table data updates (just swap, no fade)
+- Badge color changes (instant)
+- Large layout shifts
+- Anything during initial page load (except skeleton)
+- Multiple animations simultaneously
+- Anything that fires more than once per second
+
+### Key Animation Patterns
+
+**Fade in on mount:**
+```css
+@keyframes fade-in {
+ from { opacity: 0; transform: translateY(4px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+.animate-in {
+ animation: fade-in 200ms ease-out;
+}
+```
+
+**Skeleton loading:**
+```css
+@keyframes shimmer {
+ 0% { background-position: -200% 0; }
+ 100% { background-position: 200% 0; }
+}
+.skeleton {
+ background: linear-gradient(90deg,
+ oklch(0.21 0 0) 25%,
+ oklch(0.26 0 0) 50%,
+ oklch(0.21 0 0) 75%
+ );
+ background-size: 200% 100%;
+ animation: shimmer 1.5s ease-in-out infinite;
+ border-radius: 4px;
+}
+```
+
+**Sidebar collapse:**
+```css
+.sidebar {
+ width: var(--sidebar-width);
+ transition: width var(--duration-slow) var(--ease-default);
+ overflow: hidden;
+}
+.sidebar[data-collapsed="true"] {
+ width: var(--sidebar-width-icon);
+}
+```
+
+### Accessibility: Respect prefers-reduced-motion
+
+```css
+@media (prefers-reduced-motion: reduce) {
+ *, *::before, *::after {
+ animation-duration: 0.01ms !important;
+ animation-iteration-count: 1 !important;
+ transition-duration: 0.01ms !important;
+ scroll-behavior: auto !important;
+ }
+}
+```
+
+---
+
+## 9. Reference Dashboards and Design Systems
+
+### Linear
+
+- **Color approach**: Near-monochrome (neutral blacks/whites) with very few bold accent colors. Migrated to LCH color space. Significantly reduced color usage compared to earlier versions.
+- **Typography**: Inter Display for headings, regular Inter for body.
+- **Sidebar**: Inverted L-shape. Tight alignment of labels, icons, buttons. Density-focused with reduced visual noise.
+- **Layout**: Structured layouts with headers for filters, side panels for meta properties, multiple display types (list, board, timeline, split, fullscreen).
+- **Design philosophy**: "Neutral and timeless appearance." Make text and icons darker in light mode, lighter in dark mode for improved contrast.
+
+### Vercel (Geist Design System)
+
+- **Color system**: 10 color scales using OKLCH/P3 with numeric steps (100-1000). Two background colors (Background-1 for page, Background-2 for differentiation).
+- **Component colors**: Color-1 (default), Color-2 (hover), Color-3 (active).
+- **Typography**: Geist Sans + Geist Mono.
+- **Key principle**: Minimal color, maximum clarity. Black/white are the primary colors, with accent used very sparingly.
+- **URL**: https://vercel.com/geist
+
+### Cal.com
+
+- **Design tokens** in CSS variables:
+ - Dark mode: `--cal-bg: #101010`, `--cal-bg-emphasis: #2b2b2b`, `--cal-bg-subtle: #1c1c1c`, `--cal-bg-muted: #141414`
+ - Light mode: `--cal-bg: white`, `--cal-bg-emphasis: #e5e7eb`, `--cal-bg-subtle: #f3f4f6`, `--cal-bg-muted: #f9fafb`
+- **Approach**: Clean, functional, minimal decoration
+
+### Raycast
+
+- **Known for**: Extreme polish, smooth animations, keyboard-first UX
+- **Color**: Muted backgrounds, vibrant icons, high contrast text
+- **Design system**: Connected to Supernova.io for token management
+
+### PatternFly (Red Hat)
+
+- **Dashboard patterns**: Comprehensive documentation on card-based dashboard layouts
+- **Status indicators**: Well-documented severity levels and aggregate status patterns
+- **Layout**: Dashboard with cards for KPIs, lists for detail, consistent spacing
+
+---
+
+## 10. Concrete Recommendations for Agent Swarm
+
+### Migration Path
+
+The current UI uses MUI Joy + custom amber CSS variables. A migration to shadcn/ui + Tailwind v4 would be a significant rewrite. Here is what I recommend for either approach:
+
+### If Staying with MUI Joy (Evolution)
+
+1. **Replace the amber palette** with the cool neutral + indigo/teal accent proposed above
+2. **Drop the honeycomb background pattern** -- decorative patterns fight against data-dense UIs
+3. **Drop the glow effects** -- they scream "template", not "production tool"
+4. **Switch to Inter** from Space Grotesk
+5. **Simplify the StatusBadge** -- remove the "pulse-amber" animation from non-active states
+6. **Add a proper sidebar** instead of tab-based navigation
+
+### If Migrating to shadcn/ui + Tailwind v4 (Recommended)
+
+1. **Use shadcn/ui default dark theme as the base** with OKLCH colors (listed in section 3)
+2. **Customize the accent** to indigo or teal
+3. **Use the shadcn Sidebar component** for navigation
+4. **Use shadcn DataTable** (TanStack Table) instead of AG Grid for most tables, or theme AG Grid to match (section 4)
+5. **Adopt the three-layer token hierarchy** for maintainability
+6. **Inter + JetBrains Mono** font pairing
+7. **Follow the animation timing** in section 8
+8. **Use shadcn Badge** for status indicators with the semantic colors in section 6
+
+### Top Priority Visual Changes
+
+Regardless of framework choice:
+
+1. **Kill the amber/honey/gold theme** -- replace with neutral darks + semantic accents
+2. **Remove honeycomb SVG background** -- clean, flat surfaces
+3. **Remove glow effects** on text and boxes
+4. **Move from horizontal tabs to sidebar navigation** -- tabs don't scale with 9+ sections
+5. **Adopt Inter** -- the dashboard standard for a reason
+6. **Standardize status colors** to emerald/amber/red/gray/violet (not all amber variations)
+7. **Reduce border opacity** -- current #3a2d1f borders are too visible; use 6-10% white overlay instead
+
+### CSS Variables Migration
+
+From current:
+```css
+:root {
+ --hive-amber: #f5a623;
+ --hive-honey: #ffb84d;
+ --hive-gold: #d4a574;
+ --hive-body: #0d0906;
+ --hive-surface: #1a130e;
+ --hive-border: #3a2d1f;
+}
+```
+
+To proposed:
+```css
+.dark {
+ --background: oklch(0.13 0.005 270);
+ --foreground: oklch(0.985 0 0);
+ --surface: oklch(0.175 0.005 270);
+ --surface-elevated: oklch(0.21 0.006 270);
+ --border: oklch(1 0 0 / 8%);
+ --accent: oklch(0.62 0.19 264);
+ --accent-muted: oklch(0.62 0.19 264 / 15%);
+ --muted-foreground: oklch(0.55 0.01 270);
+}
+```
+
+---
+
+## Sources
+
+### Design Systems and Official Documentation
+- [shadcn/ui Theming](https://ui.shadcn.com/docs/theming) - OKLCH variables, dark theme defaults
+- [shadcn/ui Sidebar](https://ui.shadcn.com/docs/components/radix/sidebar) - Sidebar component architecture
+- [Vercel Geist Design System](https://vercel.com/geist) - Color system, typography
+- [Vercel Geist Colors](https://vercel.com/geist/colors) - 10 color scales
+- [AG Grid Theming Colors](https://www.ag-grid.com/javascript-data-grid/theming-colors/) - Dark mode theming API
+- [AG Grid Built-in Themes](https://www.ag-grid.com/javascript-data-grid/themes/) - Theme builder
+- [Material Design Dark Theme](https://m2.material.io/design/color/dark-theme.html) - Elevation overlay system
+- [Material Design 3 Color Roles](https://m3.material.io/styles/color/roles) - Semantic color system
+- [Carbon Design System Status Indicators](https://carbondesignsystem.com/patterns/status-indicator-pattern/) - Status patterns
+- [Tailwind CSS Colors](https://tailwindcss.com/docs/colors) - Color palette reference
+- [Tailwind CSS Dark Mode](https://tailwindcss.com/docs/dark-mode) - v4 dark mode approach
+- [Cal.com Instance Theming](https://cal.com/docs/enterprise-features/instance-wide-theming) - CSS variable tokens
+
+### Design Articles and Guides
+- [Linear UI Redesign](https://linear.app/now/how-we-redesigned-the-linear-ui) - LCH migration, design philosophy
+- [Design Tokens That Scale with Tailwind v4](https://www.maviklabs.com/blog/design-tokens-tailwind-v4-2026) - Three-layer token hierarchy
+- [Scalable Accessible Dark Mode](https://www.fourzerothree.in/p/scalable-accessible-dark-mode) - Dark theme implementation
+- [Dark Mode Design Best Practices 2026](https://www.tech-rz.com/blog/dark-mode-design-best-practices-in-2026/) - Layered darkness
+- [Dashboard Design Principles 2025](https://www.uxpin.com/studio/blog/dashboard-design-principles/) - UX patterns
+- [CSS/JS Animation Trends 2026](https://webpeak.org/blog/css-js-animation-trends/) - Micro-interactions
+- [Best Fonts for Dense Dashboards](https://fontalternatives.com/blog/best-fonts-dense-dashboards/) - Typography
+- [Sidebar Navigation Examples 2025](https://www.navbar.gallery/blog/best-side-bar-navigation-menu-design-examples) - Sidebar patterns
+
+### Tools
+- [OKLCH Color Picker](https://oklch.fyi/) - OKLCH converter and generator
+- [OKLCH Palette Generator](https://oklch-palette.vercel.app/) - Palette generation
+- [Data Viz Color Picker](https://www.learnui.design/tools/data-color-picker.html) - Chart palette generator