Full visual overhaul spec — new color system, typography (Manrope + IBM Plex Mono), component language, layout restructure with Context Strip, and 4-phase implementation plan. WCAG AA compliant in both modes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
12 KiB
Deep Space UI Redesign
Full visual overhaul of The Other Dude's frontend — replacing the generic shadcn/slate/cyan aesthetic with a distinctive identity built for network engineers and MSPs.
Problem
The current UI is visually indistinguishable from every other AI-generated dashboard. The slate/cyan color scheme, default shadcn component styling, and feature-organized navigation are so generic that other MikroTik dashboard projects (e.g., MikroDash) look like the same app. TOD has no visual identity.
Goals
- Distinctive identity — you should never confuse TOD with a template
- Functional clarity — DigitalOcean/Hetzner energy, not Unifi complexity
- WCAG AA compliance — 4.5:1 text contrast, 3:1 UI elements, both modes
- Both modes polished — dark is the primary identity, light is equally considered
- Desktop-first — responsive works, but optimized for laptop/desktop workflows
Design Direction: Deep Space
Dark but not cold. Deep blue-blacks instead of gray-slate. Indigo/violet accent instead of cyan. Subtle gradients for depth. Typography and spacing create hierarchy instead of colored cards and heavy borders.
Reference points: DigitalOcean, Hetzner, Linode for functional clarity. cPanel for density that works. Not Unifi. Not generic shadcn.
1. Color System
Dark Mode (Primary)
| Token | Value | Usage |
|---|---|---|
| background | #111113 |
Page background, near-black with warm undertone |
| surface | #141420 |
Cards, panels, elevated content areas |
| elevated | #1a1a2e |
Inputs, hover states, KPI card gradient base |
| border | rgba(255,255,255,0.06) |
Default borders — thin, not heavy |
| border-bright | #24243d |
Emphasized borders, section dividers |
| text-primary | #e4e4ed |
Headings, device names, primary content |
| text-secondary | #8a8aa0 |
Metadata, secondary labels, IP addresses (4.6:1 on background) |
| text-muted | #62627f |
Placeholders, column headers, tertiary info (3.2:1 on background) |
| accent | #818cf8 |
Primary interactive color (indigo-400) |
| accent-hover | #6366f1 |
Hover/pressed state (indigo-500) |
| accent-subtle | rgba(99,102,241,0.15) |
Active nav, selected states, ghost-fill buttons |
Light Mode
| Token | Value | Usage |
|---|---|---|
| background | #fafafe |
Page background, barely-tinted white |
| surface | #ffffff |
Cards, panels |
| elevated | #f0f0f8 |
Inputs, hover states — blue-violet undertone |
| border | rgba(0,0,0,0.08) |
Default borders |
| border-bright | #dcdce8 |
Emphasized borders |
| text-primary | #111113 |
Headings, primary content |
| text-secondary | #52526b |
Metadata, secondary labels |
| text-muted | #8585a0 |
Placeholders, disabled text |
| accent | #5558e6 |
Primary interactive color (4.6:1 on white, 4.4:1 on background) |
| accent-hover | #4f46e5 |
Hover/pressed state (indigo-600) |
| accent-subtle | rgba(99,102,241,0.1) |
Active states |
Status Colors
| Status | Dark | Light | Meaning |
|---|---|---|---|
| success | #22c55e |
#16a34a |
Online, healthy |
| warning | #f59e0b |
#d97706 |
Degraded, attention needed |
| error | #ef4444 |
#dc2626 |
Offline, critical |
| info | #3b82f6 |
#2563eb |
Informational |
Gradient Pattern
KPI cards and elevated surfaces use a subtle directional gradient for depth:
Dark: linear-gradient(135deg, #1a1a2e 0%, #16162a 100%)
Light: linear-gradient(135deg, #f8f8ff 0%, #f0f0f8 100%)
Status indicator dots use a subtle glow:
box-shadow: 0 0 6px rgba({color}, 0.3)
2. Typography
Fonts
- UI text: Manrope — geometric, semi-rounded, modern without being trendy
- Data values: IBM Plex Mono — wider and more readable than most monospaces, designed for infrastructure UIs
- Fallbacks: system-ui, -apple-system, sans-serif (UI) / ui-monospace, monospace (data)
Type Scale
| Role | Size | Weight | Font | Extra |
|---|---|---|---|---|
| Page title | 18px | 600 | Manrope | letter-spacing: -0.3px |
| Section heading | 14px | 600 | Manrope | — |
| Body text | 13px | 500 | Manrope | Nav items, device names |
| Small text | 11px | 500 | Manrope | Metadata, model names |
| Micro label | 10px | 600 | Manrope | uppercase, letter-spacing: 1.2px |
| Mono large | 22-24px | 500 | IBM Plex Mono | tabular-nums, KPI values |
| Mono inline | 12px | 400 | IBM Plex Mono | tabular-nums, IPs/percentages |
| Mono small | 11px | 400 | IBM Plex Mono | tabular-nums, table cells |
Principles
- No text larger than 18px — this is a dense tool, not a marketing site
- Monospace only for actual data values (numbers, IPs, percentages, durations)
- Uppercase micro labels for section/column headers create hierarchy without size
font-variant-numeric: tabular-numson all monospace so numbers align
Font Loading
Self-host both fonts via @fontsource/manrope and @fontsource-variable/ibm-plex-mono npm packages. No Google Fonts CDN — the app may run on air-gapped or restricted networks. Import only the weights used (400, 500, 600, 700 for Manrope; 400, 500 for IBM Plex Mono).
Transitions
All interactive state changes (hover, focus, active, color-scheme toggle): 150ms ease. Sidebar collapse: 200ms ease. Dialog enter/exit: 150ms ease. Respect prefers-reduced-motion by disabling all transitions/animations.
3. Component Language
Border Radius
- Cards/panels: 8px
- Buttons/inputs/pills: 6px
- Status dots/avatars: 50%
- No
rounded-fullpill buttons
Depth Model
- Borders over shadows — zero box-shadows on cards. Thin borders for structure.
- Dark:
rgba(255,255,255,0.06)default,#24243demphasized - Light:
rgba(0,0,0,0.08)default,#dcdce8emphasized
Buttons
- Primary: Ghost-fill —
background: accent-subtle; color: accent. Solid indigo only for critical CTAs (e.g., "Add device" getsbackground: accent; color: white). - Secondary: Border-only —
border: 1px solid border; color: text-secondary - Destructive: Ghost-fill in red — same pattern as primary but with error tokens
- All 6px radius, no pill shapes
- All button colors derive from mode-aware tokens — no hardcoded values
Inputs
- Background:
#1a1a2e(dark) /#f0f0f8(light) - Border: thin, default color
- Focus: border-color changes to accent — no ring glow
- Radius: 6px
- Placeholder: text-muted color
Tables
- No alternating row colors
- Thin bottom borders:
rgba(255,255,255,0.06)(dark) /rgba(0,0,0,0.06)(light) — uses border token, intentionally subtle - Column headers: uppercase micro labels in text-muted
- Status dots inline, not colored row backgrounds
- Monospace for data columns (IP, CPU, uptime)
Tabs/Pills
- Active: ghost-fill accent background + accent text color
- Inactive: plain muted text, no background
- No underlines or heavy active indicators
Dialogs/Modals
- Surface background with thin border
- Backdrop:
rgba(0,0,0,0.6)with subtle blur - Same 8px radius as cards
4. Layout Structure
Context Strip (Top Bar — 36px height)
Always-visible horizontal bar providing at-a-glance status:
- Left: Org switcher — icon + name + dropdown chevron. Adaptive: prominent for multi-org MSPs, minimal for single-org users. Separated from status indicators by a thin vertical border.
- Center: Live status indicators — clickable items that filter/navigate:
- Red dot + "2 down" (navigates to offline devices)
- Amber dot + "4 degraded" (navigates to degraded devices)
- "WiFi OK" or "WiFi 3 issues" (navigates to wireless view)
- "BW 4.2G" in monospace (navigates to traffic view)
- Right: Command palette shortcut (⌘K), connection status dot, user avatar
The strip replaces the need for a separate alerts page as the primary "is anything broken" indicator.
Data source: The strip derives its counts from the existing fleet summary API (metricsApi.fleetSummary) which already returns device status counts and aggregate metrics. No new API endpoint needed — the strip subscribes to the same React Query cache that the dashboard uses. Status updates arrive via the existing WebSocket device-status subscription. WiFi and bandwidth indicators aggregate from the same data source.
Sidebar (180px, collapsible to 56px icon-only)
Three sections organized by user intent:
Fleet (monitoring — "what's happening")
- Overview — dashboard with KPIs, fleet health
- Devices — full device table with search/filter
- Wireless — AP status, client counts, signal quality
- Traffic — bandwidth charts, top talkers
Config (changes — "do something")
- Editor — live config editor with menu tree
- Templates — config templates, push wizard
- Firmware — version management, upgrades
Admin (management — "who and how")
- Users — user management, roles
- Audit Log — action history
- Settings — tenant settings, alert rules, notifications
Section labels: uppercase micro labels in muted text. Active nav item: ghost-fill accent background. Inactive: plain muted text.
Version identifier at bottom: TOD v9.5 in mono micro text.
Main Content Area
- Full width of remaining space
- 20px padding
- Page header: title (18px semibold) + subtitle (11px muted) left, action buttons right
- KPI cards in a row below header where applicable
- Primary content (tables, charts, forms) below KPIs
5. Responsive Strategy
Desktop-first. Mobile works in a pinch.
- Context strip: Collapses to thin bar with alert count badge on mobile. Tap to expand.
- Sidebar: Slide-out drawer via hamburger on mobile.
- KPI cards: 4-col → 2-col (tablet) → 1-col (phone)
- Device table: Switches to card/list view on phone (no horizontal scroll tables)
- Touch targets: Minimum 44px height on interactive elements (WCAG 2.5.8)
- Type scale: No changes needed — 11-13px body is native mobile scale. 10px micro labels stay legible due to uppercase + wide letter-spacing.
6. Implementation Phases
Phase 1 — Design Tokens & Foundation
Risk: Low | Impact: High | Disruption: Minimal
- Replace HSL color tokens in
index.csswith Deep Space palette (dark + light) - Swap Geist for Manrope + IBM Plex Mono in Tailwind config
- Update custom properties and Tailwind theme mapping
- Add new border/radius/shadow conventions to base styles
- At end of phase: flip the switch — entire app gets new palette and fonts via tokens
Files touched: index.css, tailwind.config.ts, font imports
Phase 2 — Component Restyling
Risk: Low | Impact: High | Disruption: Low
- Update shared UI primitives: Button, Input, Card, Dialog, Select, Checkbox, Skeleton, Badge, Tabs
- Kill box-shadows, update border radii, implement ghost-fill button style
- Update focus states (border-color change instead of ring glow)
- Changes propagate through entire app via shared components
Files touched: components/ui/*.tsx
Phase 3 — Layout Restructure
Risk: Medium | Impact: High | Disruption: Medium
- Replace AppLayout shell — new sidebar structure, new Context Strip header
- Build the Context Strip component with live status indicators
- Reorganize sidebar navigation (Fleet / Config / Admin)
- Update route structure if nav paths change
- Remove old header component
Files touched: components/layout/AppLayout.tsx, Sidebar.tsx, new ContextStrip.tsx, route files
Phase 4 — Page-Level Polish
Risk: Low | Impact: Medium | Disruption: Low
- Refine each page: dashboard KPIs, device table, config editor, alerts integration
- Ensure gradient KPI cards, table styling, form layouts match spec
- Light mode QA pass — verify WCAG contrast on every page
- Fix any spots where old layout assumptions break with new structure
Files touched: page components, dashboard widgets, table components
7. What This Is Not
- Not a rewrite — same React/Radix/Tailwind stack, same business logic
- Not a mobile redesign — responsive adaptations only
- Not a component library migration — still Radix UI primitives, restyled
Note: The Context Strip is the one piece of genuinely new UI (not just restyling). It replaces the current header and surfaces existing data in a new way. Phase 3 should be scoped accordingly — it's the only phase that introduces a new component with its own data needs.
8. Success Criteria
- The app is visually unrecognizable compared to its current state
- Nobody mistakes it for a shadcn template or another MikroTik dashboard
- Both dark and light modes pass WCAG AA contrast checks
- The indigo/violet accent and Manrope/IBM Plex Mono pairing create a recognizable identity
- Network engineers see a tool that respects their workflow, not a generic SaaS dashboard