diff --git a/docs/plans/2026-02-15-visual-glow-up-design.md b/docs/plans/2026-02-15-visual-glow-up-design.md new file mode 100644 index 0000000..f552af0 --- /dev/null +++ b/docs/plans/2026-02-15-visual-glow-up-design.md @@ -0,0 +1,235 @@ +# OpenPylon Visual Glow-Up Design + +**Date:** 2026-02-15 +**Goal:** Transform OpenPylon from functional-but-bare to visually polished and delightful +**Approach:** Settings-first foundation — build the settings infrastructure, then layer visual features on top + +--- + +## 1. Settings Model & Infrastructure + +Expand `AppSettings` in `src/types/settings.ts`: + +```typescript +export interface AppSettings { + theme: "light" | "dark" | "system"; + dataDirectory: string | null; + recentBoardIds: string[]; + + // Appearance + accentColor: string; // OKLCH hue (0-360), default "160" (teal) + uiZoom: number; // 0.75-1.5, default 1.0 + density: "compact" | "comfortable" | "spacious"; + + // Board defaults + defaultColumnWidth: ColumnWidth; // default "standard" +} +``` + +### Zoom +Set `font-size` on `` to `uiZoom * 16px`. Everything uses `rem` via Tailwind, so the entire UI scales proportionally. + +### Accent Color +Store an OKLCH hue value. On apply, regenerate `--pylon-accent` as `oklch(55% 0.12 {hue})` (light) / `oklch(60% 0.12 {hue})` (dark). + +### Density +Set CSS custom property `--density-factor` (compact=0.75, comfortable=1.0, spacious=1.25). Use it to scale padding on columns, cards, and gaps. + +### App Store Changes +Add `setAccentColor`, `setUiZoom`, `setDensity`, `setDefaultColumnWidth` actions to `app-store.ts`. Each saves immediately (no Save button). Add `applyAppearance()` function that applies zoom, accent, and density to the DOM — called on init and on any change. + +--- + +## 2. Settings Panel UI + +Transform `SettingsDialog.tsx` from a tiny modal into a tabbed panel. + +- Widen to `sm:max-w-lg` +- 4 tabs: **Appearance** | **Boards** | **Keyboard Shortcuts** | **About** +- Simple button-based tab navigation (no library needed) + +### Appearance Tab +- **Theme** — existing 3-button toggle (unchanged) +- **UI Zoom** — slider 75%-150% in 5% steps, live preview, reset button, shows current % +- **Accent Color** — 10 preset OKLCH hue swatches: teal/160, blue/240, purple/300, pink/350, red/25, orange/55, yellow/85, lime/130, cyan/200, slate/achromatic. Click to apply immediately. +- **Density** — 3-button toggle: Compact / Comfortable / Spacious + +### Boards Tab +- **Default column width** — 3-button toggle: Narrow / Standard / Wide + +### Keyboard Shortcuts Tab +- Read-only reference table, two-column: key combo (mono font) | description +- All shortcuts: Ctrl+K, Ctrl+Z, Ctrl+Y, Ctrl+N, ?, etc. + +### About Tab +- App name, version, tagline +- Link to repo (opens via Tauri shell) + +--- + +## 3. Board Color Applied to UI + +Currently `board.color` only shows on BoardCard in the home screen. + +- **TopBar:** 2px bottom border in board color when viewing a board. Color dot next to board title. +- **Column headers:** 3px top-border in board color at 30% opacity. +- **No full background tinting** — structural accents only (borders, dots). + +--- + +## 4. Column Colors + +Extend `Column` interface: + +```typescript +export interface Column { + id: string; + title: string; + cardIds: string[]; + width: ColumnWidth; + color: string | null; // optional OKLCH hue, null = use board color +} +``` + +- Set via "Color" submenu in ColumnHeader dropdown (same 10 swatches + "None") +- Column's 3px top-border uses column color when set, falls back to board color +- Column background stays neutral + +--- + +## 5. Card Cover Colors + +Extend `Card` interface: + +```typescript +export interface Card { + // ...existing + coverColor: string | null; // OKLCH hue for color strip +} +``` + +- No image uploads for v1 — just a color bar +- 4px colored bar at top of CardThumbnail +- Set via swatch picker in CardDetailModal +- Simple CSS, no layout disruption + +--- + +## 6. Richer Card Thumbnails + +Add to existing CardThumbnail footer row: + +- **Attachment indicator** — paperclip icon + count (if `attachments.length > 0`) +- **Description indicator** — text-lines icon (if `description` is non-empty) +- **Cover color bar** — from Section 5 + +No priority badges or assignees — keeping thumbnails clean. + +--- + +## 7. Toast Notification System + +- `useToastStore` — Zustand store: `{ id, message, type }[]` +- `` in App.tsx — fixed bottom-right, pills with auto-dismiss (3s + fade) +- Types: `success` (green), `error` (red), `info` (neutral) +- Fires on: board deleted, board exported, board imported, import failed, save error + +--- + +## 8. Undo/Redo Buttons in TopBar + +- Two icon buttons: RotateCcw (undo) and RotateCw (redo) +- Placed in TopBar right section, before command palette button +- Disabled when at start/end of history +- Only visible in board view +- Tooltips show keyboard shortcuts (Ctrl+Z / Ctrl+Y) + +--- + +## 9. Keyboard Shortcut Help Modal + +- Triggered by `?` key (when not in an input/textarea) +- Two-column grid grouped by category: Navigation, Board, Cards +- Same data as Settings keyboard shortcuts tab +- Lightweight modal, dismissible with Escape or clicking outside + +--- + +## 10. Board Backgrounds + +Extend `BoardSettings`: + +```typescript +export interface BoardSettings { + attachmentMode: "link" | "copy"; + background: "none" | "dots" | "grid" | "gradient"; +} +``` + +- **none** — plain (current) +- **dots** — subtle radial-gradient dot pattern, 5% opacity +- **grid** — subtle grid lines via CSS +- **gradient** — soft gradient using board color at 3-5% opacity +- Set via board settings dropdown (gear icon in TopBar when viewing a board) + +--- + +## 11. Onboarding / Empty States + +- **First launch (zero boards):** Upgraded empty state — welcoming message, prominent "Create Board" button, secondary "Import Board" option +- **Empty column:** Dashed-border area with "Drop or add a card" text +- **Empty description:** "Click to add a description..." placeholder +- **Empty checklist:** "Add your first item..." when empty + +--- + +## 12. Polish Pass + +- Consistent hover transitions (200ms ease) across all interactive elements +- Verify focus rings work with all accent colors +- Test Framer Motion springs at different zoom levels +- Dark mode testing for all new features (column colors, card covers, backgrounds) +- Thin, themed scrollbars on column scroll areas + +--- + +## Implementation Order + +1. Settings model + app store actions + CSS variable application +2. Settings panel UI (tabbed, all sections) +3. UI zoom +4. Accent color +5. Density toggle +6. Board color in UI (TopBar + column headers) +7. Column colors +8. Card cover colors +9. Richer card thumbnails +10. Toast notification system +11. Undo/redo buttons +12. Keyboard shortcut help modal +13. Board backgrounds +14. Onboarding / empty states +15. Polish pass + +## Files Affected + +- `src/types/settings.ts` — expanded AppSettings +- `src/types/board.ts` — Column.color, Card.coverColor, BoardSettings.background +- `src/stores/app-store.ts` — new actions, applyAppearance() +- `src/components/settings/SettingsDialog.tsx` — full rewrite (tabbed) +- `src/index.css` — density variables, zoom hook, background patterns +- `src/components/layout/TopBar.tsx` — board color, undo/redo buttons, board settings gear +- `src/components/board/KanbanColumn.tsx` — column color border +- `src/components/board/ColumnHeader.tsx` — color submenu +- `src/components/board/CardThumbnail.tsx` — cover bar, attachment/description indicators +- `src/components/card-detail/CardDetailModal.tsx` — cover color picker +- `src/components/board/BoardView.tsx` — background patterns +- `src/App.tsx` — ToastContainer, shortcut help modal, appearance init +- `src/stores/toast-store.ts` — NEW +- `src/components/toast/ToastContainer.tsx` — NEW +- `src/components/shortcuts/ShortcutHelpModal.tsx` — NEW +- `src/stores/board-store.ts` — new actions for column color, card cover +- `src/lib/board-factory.ts` — defaults for new fields +- `src/lib/schemas.ts` — migration for new fields +- `src/components/boards/BoardList.tsx` — upgraded empty state +- `src/hooks/useKeyboardShortcuts.ts` — ? key handler