From fc79996468fa981faf5563240727429e0d3a446d Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 19 Mar 2026 08:50:36 -0400 Subject: [PATCH] docs: add UI improvement pass design spec Co-Authored-By: Claude Sonnet 4.6 --- .../2026-03-19-ui-improvement-pass-design.md | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 docs/superpowers/specs/2026-03-19-ui-improvement-pass-design.md diff --git a/docs/superpowers/specs/2026-03-19-ui-improvement-pass-design.md b/docs/superpowers/specs/2026-03-19-ui-improvement-pass-design.md new file mode 100644 index 0000000..6137568 --- /dev/null +++ b/docs/superpowers/specs/2026-03-19-ui-improvement-pass-design.md @@ -0,0 +1,184 @@ +# UI Improvement Pass — Design Spec + +**Date:** 2026-03-19 +**Scope:** All 6 pages — visual polish + UX usability, equal weight +**Direction:** Darker, cooler blue-grey tone ("monitoring dashboard" feel), lifted nav branding + +--- + +## Goals + +1. Replace the generic default-Vuetify color palette with a distinctive monitoring-dashboard identity +2. Give the nav drawer meaningful visual structure and branding +3. Add a WebSocket connection indicator in the app bar +4. Improve Dashboard information hierarchy and action bar layout +5. Fix dark-mode-breaking hardcoded colour classes across all pages +6. Consistent empty states and loading treatment throughout +7. Per-page UX improvements (Downloads filter, Credentials visual state, Subscriptions dark mode) + +--- + +## Section 1: Color System (`frontend/src/plugins/vuetify.js`) + +Replace both theme palettes entirely. + +### Dark theme (primary use case) +```js +dark: { + dark: true, + colors: { + background: '#0F172A', // slate-900 — deep navy + surface: '#1E293B', // slate-800 — card surfaces + primary: '#60A5FA', // blue-400 — cooler accent + secondary: '#94A3B8', // slate-400 + error: '#F87171', // red-400 + warning: '#FBBF24', // amber-400 + success: '#34D399', // emerald-400 + info: '#38BDF8', // sky-400 + }, +} +``` + +### Light theme +```js +light: { + dark: false, + colors: { + background: '#F1F5F9', // slate-100 — cool grey workspace + surface: '#FFFFFF', + primary: '#2563EB', // blue-600 — deeper, more serious + secondary: '#475569', // slate-600 + error: '#EF4444', + warning: '#F59E0B', + success: '#10B981', + info: '#0EA5E9', + }, +} +``` + +### Global component defaults (add to existing `defaults`) +```js +VCard: { elevation: 0, border: true }, +VBtn: { variant: 'flat' }, +VChip: { rounded: 'md' }, +``` + +Removing shadow elevation in favour of a subtle border gives cards a cleaner, more modern feel at both themes. The border adapts to theme colours automatically. + +--- + +## Section 2: Nav Drawer & App Bar (`frontend/src/App.vue`) + +### Nav drawer brand header +Replace the plain `v-list-item` brand block with a styled header: +- Container: `pa-4` padding, `bg-surface` background to visually separate from nav list +- Icon: `mdi-download-network` at size 32, `color="primary"` +- Title: `"GallerySubscriber"` in `font-weight-bold text-subtitle-1` +- Subtitle: `"Download Manager"` in `text-caption text-medium-emphasis` +- Followed by a `v-divider` + +### Nav list items +Change from `density="compact"` to `density="comfortable"`. Add `rounded="lg"` and `active-color="primary"` to each `v-list-item`. The built-in Vuetify active state renders a tinted pill highlight on the current route. + +### App bar +- Change `elevation="1"` to `elevation="0"` with `border="b"` — flat bar with bottom border +- Add a WebSocket status indicator to the right of the title, before the theme toggle: + - A `v-chip` or icon+dot combination showing three states: + - **Connected:** small green dot (`color="success"`) + tooltip "Connected" + - **Connecting:** amber dot with CSS pulse animation + tooltip "Connecting…" + - **Disconnected:** red dot + tooltip "Disconnected — real-time updates paused" + - Reads from `useWebSocketStore().status` (the store already tracks connection state) + - `variant="text"` so it's unobtrusive + +--- + +## Section 3: Dashboard (`frontend/src/views/Dashboard.vue`) + +### Stat cards (number-forward layout) +Replace the `v-avatar` + side-by-side number layout with a vertical number-forward design: +- Large `text-h3 font-weight-bold` number at top +- `text-caption text-medium-emphasis` label below +- A 4px left border accent stripe using inline style `border-left: 4px solid ` matching the card's semantic colour (primary, success, error, warning) +- Remove the `v-avatar` entirely — the border provides the colour signal + +### Action bar (split into two rows) +**Row 1** (actions): The three action buttons unchanged — Check All Sources, Retry All Failed, Reset Stuck. + +**Row 2** (status): Two groups separated by a `v-divider vertical`: +- Left: credential status chips (the existing platform chips, unchanged) +- Right: storage stats (existing display, unchanged) + +Each row is its own `v-card-text`. This removes the single-line cramming. + +### Active downloads list +Running items get a subtle animated left border: +```css +.download-running { + border-left: 3px solid rgb(var(--v-theme-primary)); + animation: pulse-border 2s ease-in-out infinite; +} +@keyframes pulse-border { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.4; } +} +``` + +### Consistent empty states +All three empty panels (active downloads, recent activity, sources needing attention) use the same pattern: +```html +
+ mdi-[relevant-icon] +
[Primary message]
+
[Helper text]
+
+``` +- Active downloads empty: icon `mdi-check-circle-outline`, "No active downloads", "All sources are idle" +- Recent activity empty: icon `mdi-history`, "No recent activity", "Failures and new downloads appear here" +- Sources needing attention empty: icon `mdi-check-all`, "All sources healthy", "No failures in the last 7 days" + +--- + +## Section 4: Per-Page Fixes + +### Subscriptions (`frontend/src/views/Subscriptions.vue`) +- Replace `class="bg-grey-lighten-4"` on the expanded inner table with `class="bg-surface"`. This is the only dark-mode-breaking class in the file. +- Add `class="border-t"` to the inner table container for visual separation. + +### Downloads (`frontend/src/views/Downloads.vue`) +- Add an `exclude_superseded` toggle to the filters row: a `v-switch` or `v-chip` labelled "Hide superseded failures" that adds `exclude_superseded: true` to the fetch params when active. Defaults to `true` (consistent with the dashboard behaviour). +- No table layout changes. + +### Credentials (`frontend/src/views/Credentials.vue`) +Two visual states for platform cards: + +**Configured:** Card gets `border-color` set to the success colour via inline style or a CSS class. Existing content unchanged. + +**Not configured:** Card gets a dashed border (`border: 2px dashed`), the `v-alert` info block is replaced with a concise empty-state message, and the "Add Credentials" button is promoted to `color="primary" variant="flat"` (currently `variant="text"`), making the call to action visually prominent. + +### Settings & Logs +No structural changes — both pages inherit the new palette and card border style from the vuetify.js update automatically. + +--- + +## Files Changed + +| File | Change | +|------|--------| +| `frontend/src/plugins/vuetify.js` | Full palette replacement, component defaults update | +| `frontend/src/App.vue` | Nav branding, nav item density/rounding, app bar border+ws indicator | +| `frontend/src/views/Dashboard.vue` | Stat card layout, action bar split, running item pulse, empty states | +| `frontend/src/views/Subscriptions.vue` | Replace `bg-grey-lighten-4` with `bg-surface` | +| `frontend/src/views/Downloads.vue` | Add `exclude_superseded` filter toggle | +| `frontend/src/views/Credentials.vue` | Configured/unconfigured card visual states | + +Settings.vue and Logs.vue are **not modified** — they benefit from the theme update without code changes. + +--- + +## Non-Goals + +- No new pages or routes +- No layout restructuring (grid columns, page structure unchanged) +- No new API endpoints +- No component extraction / shared component library +- Settings.vue and Logs.vue: no structural changes