docs: add Deep Space UI redesign spec
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>
This commit is contained in:
292
docs/superpowers/specs/2026-03-16-deep-space-ui-redesign.md
Normal file
292
docs/superpowers/specs/2026-03-16-deep-space-ui-redesign.md
Normal file
@@ -0,0 +1,292 @@
|
||||
# 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-nums` on 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-full` pill buttons
|
||||
|
||||
### Depth Model
|
||||
- **Borders over shadows** — zero box-shadows on cards. Thin borders for structure.
|
||||
- Dark: `rgba(255,255,255,0.06)` default, `#24243d` emphasized
|
||||
- Light: `rgba(0,0,0,0.08)` default, `#dcdce8` emphasized
|
||||
|
||||
### Buttons
|
||||
- **Primary:** Ghost-fill — `background: accent-subtle; color: accent`. Solid indigo only for critical CTAs (e.g., "Add device" gets `background: 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.css` with 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
|
||||
Reference in New Issue
Block a user