--- stepsCompleted: [step-01-init, step-02-discovery, step-03-core-experience, step-04-emotional-response, step-05-inspiration, step-06-design-system, step-07-defining-experience, step-08-visual-foundation, step-09-design-directions, step-10-user-journeys, step-11-component-strategy, step-12-ux-patterns, step-13-responsive-accessibility, step-14-complete] inputDocuments: - "prd.md" - "product-brief-gitpulse.md" - "product-brief-gitpulse-distillate.md" - "architecture.md" - "research/market-git-dashboard-ia-research-2026-04-24.md" workflowType: 'ux-design' project_name: 'GitPulse' user_name: 'Ramez' date: '2025-04-25' lastStep: 14 status: 'complete' completedAt: '2025-04-25' --- # UX Design Specification GitPulse **Author:** Ramez **Date:** 2025-04-25 --- ## Executive Summary ### Project Vision GitPulse is an open source desktop dashboard that solves multi-repo chaos: a developer launches the app and instantly sees the state of all their Git repositories — status, branches, pending commits, and alerts. The vision is the "command center" for the local code ecosystem. **Fundamental UX Constraints:** - Zero-config, zero-login — user sees dashboard in < 30 seconds after download - Offline-first — no feature depends on network - Native performance — ~15 MB binary, <200 MB RAM, 60fps - Cross-platform — same experience on Windows, macOS, Linux ### Target Users **Persona 1 — Sarah, Indie Dev Poly-Project (primary)** Freelancer with 10-50+ repos across clients, OSS, personal. Daily context-switching. Loses track of unpushed commits, stale branches. Wants instant visibility, zero configuration. Tool budget: $0-10/month. **Persona 2 — Leo, Power User / Tech Lead (secondary)** Senior dev in microservices architecture, 12-30+ repos. Uses CLI + GUI hybrid. Wants batch ops, cross-repo visibility, configures cloud API keys for advanced analysis. **Persona 3 — Max, Maker / Side-Project Builder (tertiary)** Creative developer with 20+ side projects, many dormant. Needs dormancy detection and cleanup prompts. **Persona 4 — Jay, New Dev (onboarding)** < 10 repos. Experience must remain valuable — no "empty" feeling with a small number of repositories. ### Key Design Challenges 1. **Information density vs readability** — Each repo displays branch, status (clean/dirty/ahead/behind), last commit, stash count, and optionally an AI summary. For 5 to 100+ repos, the challenge is instant pattern recognition without visual overload. 2. **Consistent multi-view navigation** — Card Grid ↔ List View toggle must maintain a consistent visual status language (colors, badges, icons) and preserve selection when switching views (useful for batch ops). 3. **Trust through transparency** — The privacy indicator (FR27) is a key differentiator. Users must always know whether data stays local or transits to cloud, without being intrusive. 4. **"5-Second Wow"** — The conversion moment: first launch → auto-scan → full dashboard in < 30 seconds. The empty experience (0 repos) and small experience (< 10 repos, Jay) must also be engaging. 5. **Platform-specific integration** — System tray, notifications, auto-launch have different native behaviors on Windows, macOS, Linux. UX must be consistent while respecting each platform's conventions. 6. **Progressive AI enhancement** — Smart Status is an enrichment, never a dependency. The interface must be complete without AI, and naturally enriched when a provider is configured. ### Design Opportunities 1. **Unified visual status language** — A consistent color/badge system (green = clean, orange = ahead/behind, red = dirty, grey = dormant) that works across Card Grid, List View, system tray, and notifications. This is the #1 UX lever for instant pattern recognition. 2. **Batch ops with granular feedback** — Selecting 15 repos and seeing results appear in real-time (success/failure per repo) is a major functional differentiator. The partial success UX can transform a tedious task into a satisfying interaction. 3. **Trust as a feature** — The Privacy Badge and local-first default can become a visual selling point. "Your code never leaves your machine" as a design element, not just text. 4. **Smart Status as subtle enrichment** — Rather than a separate AI panel, health summaries can appear naturally in RepoCards as an additional text line, with a discreet "AI" badge indicating the source. ## Core User Experience ### Defining Experience **Core loop: Scan → See → Act** The central action is the "visual status check" — the user opens GitPulse and immediately knows which repos need attention. It's a "check-in tool" like a weather app or monitoring dashboard: open, visually scan, act if needed, close. Usage frequency varies by persona: - **Sarah**: 2-3x/day (morning check, post-commit check, end-of-day check) - **Leo**: 1-2x/day + occasional batch ops - **Max**: 1x/week + monthly cleanup - **Jay**: 1x/day to build familiarity **The one interaction to nail: The Card Grid visual scan.** If the user can open GitPulse and in 2 seconds identify the 3 repos that need attention among 30+ repos, everything else follows. ### Platform Strategy **Platform: Native Desktop (Tauri v2)** - Windows, macOS, Linux — same codebase, same UX - Interaction: mouse + keyboard (desktop-first, no touch) - Native WebView per platform (WebView2/WebKit/WebKitGTK) **Two interaction surfaces:** 1. **Main Dashboard** — Full desktop window with Card Grid / List View. The complete experience. 2. **System Tray** — Always-present background agent. Push notifications + quick actions (pull, push, status). Functions with dashboard closed. **Platform constraints:** - Tray behavior differs by OS (Windows: taskbar, macOS: menu bar, Linux: D-Bus). UX must be functionally identical but visually native. - OS notifications must respect each platform's system settings. - Keyboard + shortcuts for all core operations (NFR25). ### Effortless Interactions **Zero-effort by design:** - Launch → auto-scan (no action required) - Scan results → persistent cache (instant reload on next launch) - Repo status → updated via background batch fetch **One-effort:** - Batch pull/push: multi-select → one click → streaming results - Rescan: single button (or keyboard shortcut) - View toggle: one click or shortcut (Ctrl/Cmd+G grid, Ctrl/Cmd+L list) **What should disappear vs competitors:** - No login/password (vs GitKraken) - No manual repo config (vs gita) - No repo-by-repo navigation (vs lazygit) - No setup wizard — dashboard appears directly ### Critical Success Moments **Moment 1 — "5-Second Wow" (first launch)** User downloads, launches, sees full dashboard in < 30 seconds. If repos appear with clear visual status, they instantly understand the value. **Moment 2 — First status check (first minute)** User visually identifies a forgotten repo (behind, dirty, or dormant). The "oh, I forgot about that one!" reaction is instant product validation. **Moment 3 — First batch op (first session)** Select 5-10 repos → batch pull → see results stream in real-time. Time savings are tangible and measurable. **Moment 4 — First Smart Status (first week)** Configure Ollama → see an AI summary appear on a repo. The enrichment is subtle but rewarding. **Break moment — Empty state or error** Empty dashboard (0 repos found) or failed scan. If the empty state isn't engaging with a clear call-to-action, the user abandons. ### Experience Principles 1. **Instant Visibility** — All repo states visible at a glance. No navigation, no loading, no setup. Open = know. 2. **Zero Friction Entry** — No obstacles between download and value. No account, no config, no wizard. First scan starts automatically. 3. **Progressive Power** — Base interface is simple (visual status). Power (batch ops, AI, filters) reveals itself as needed, without overwhelming the initial user. 4. **Trust by Default** — Privacy is the default mode. The Privacy Badge isn't an intrusive notification but a reassuring design element, always visible but never blocking. 5. **Native Feel** — No "web app in a window." Native desktop behavior: keyboard shortcuts, system tray, OS notifications, fluid resizing, responsive performance. ## Desired Emotional Response ### Primary Emotional Goals **Emotion #1 — Relief** The immediate feeling: "I don't have to check 30 repos manually anymore." GitPulse eliminates the anxiety of the unknown — the developer knows exactly where things stand. This is the emotion that drives recommendations: "You have to try this, it saved me." **Emotion #2 — Control** The lasting feeling: "I dominate my code ecosystem." The user feels organized, informed, proactive rather than reactive. The Card Grid is the visual projection of this mastery. **Emotion #3 — Trust** The underlying feeling: "My code stays on my machine." Trust isn't a feature but an absence of doubt. The Privacy Badge silently reinforces this confidence with every use. ### Emotional Journey Mapping **Discovery → First Launch (curiosity → relief)** User arrives with curiosity ("a free multi-repo tool?") and leaves with relief ("wow, I had 3 repos I forgot about"). The auto-scan is the emotional trigger. **Daily check-in (routine → confidence)** After adoption, the daily check becomes routine. The target emotion is quiet confidence — user opens, confirms all is well, closes. No alerts = success. **Batch operation (hesitation → satisfaction)** First batch op: user hesitates ("will this work on 15 repos at once?"). Result: tangible satisfaction. Partial failures must inspire confidence ("the failed ones are clearly flagged, I know what to do"). **AI discovery (intrigue → delight)** First Smart Status: curiosity ("what will the AI say about my repo?"). Result: subtle delight if the summary is relevant. AI must never disappoint — a useless summary is worse than no summary. **Empty/error state (confusion → clarity)** 0 repos found or scan error. Emotion must shift quickly from confusion to clarity through a clear message/action ("Add directories to scan" with direct button to Settings). ### Micro-Emotions | Micro-Emotion | GitPulse Context | Design Response | |---|---|---| | **Confidence vs Confusion** | Scan results appearing | Progressive results, never a blank screen without feedback | | **Trust vs Skepticism** | AI/Cloud data flow | Privacy Badge always visible, explicit opt-in for cloud | | **Accomplishment vs Frustration** | Batch operations | Per-repo success/failure visual, no endless spinners | | **Delight vs Indifference** | Smart Status summaries | Relevant, concise summaries, no generic filler text | | **Control vs Overwhelm** | 50+ repos dashboard | Instant filters/sorts, status colors for pattern recognition | | **Belonging vs Isolation** | Open source community | Discreet GitHub link, contributing hints | ### Design Implications - **Relief → Visible instant scan**: Scan must show progressive results (repo count climbing), never a blank screen with spinner. Each appearing repo reinforces relief. - **Control → Immediate visual status**: Colors and badges must be interpretable in < 1 second without a legend. The color pattern must be instinctive (green = ok, red = problem). - **Trust → Privacy as architecture**: The Privacy Badge isn't a popup or banner but a permanent interface element, like the padlock in a browser. Present, discreet, reassuring. - **Satisfaction → Streaming batch results**: Each successful repo appears in green as it completes. Failures appear in red with detail. No "all or nothing" — progress is visible. - **Delight → Subtle AI**: Smart Status appears as a natural text line in the RepoCard, not a separate panel. A micro-badge "AI" indicates the source. If no AI is configured, the slot doesn't exist as an empty hole — it simply isn't there. ### Emotional Design Principles 1. **Show, don't tell** — Value is visible at first glance. No text onboarding, no explanatory tooltips. The dashboard is visually self-explanatory. 2. **Silent reassurance** — Trust is built through absence of problems, not through messages. The Privacy Badge is like the HTTPS padlock — noticed when sought, never intrusive. 3. **Celebrate progress, isolate failure** — Batch ops show each success in real-time. Failures are isolated and actionable, never blocking the whole. 4. **Calm competence** — GitPulse doesn't try to impress. It is competent, reliable, understated. The design reflects this: no flashy animations, no sounds, no confetti. Just a tool that works. ## UX Pattern Analysis & Inspiration ### Inspiring Products Analysis **Linear (project management)** The gold standard for developer tools. Keyboard-first interface, clean design, instant performance. Every interaction is fast and predictable. Information density is high without overload. Command palette (Cmd+K) for everything. Transferable: the "fast by default, power on demand" principle matches GitPulse's experience exactly. **Raycast (productivity launcher)** Master of "zero-friction entry." Opens instantly, real-time results, closes fast. The "check-in tool" model is identical to GitPulse: open → see → act → close. Silent trust (no unnecessary notifications, no bloat) is a model for the system tray. **Docker Desktop (container dashboard)** Multi-item dashboard with colored status indicators (green/yellow/red). Similar to GitPulse: multiple "entities" with visual states, possible batch actions. Their weakness: heavy, slow, Electron. GitPulse can adopt the dashboard pattern but with native lightness. **1Password (security app)** The security padlock as a permanent, reassuring design element. Exactly the analogy for GitPulse's Privacy Badge. Trust is integrated into the interface, not added on top. The visual lock/unlock is a model for the local/cloud indicator. **lazygit (terminal git UI)** The reference git TUI. Instant, keyboard-driven, all info visible on one screen. Proves developers want speed and density. Its limitation: single repo only. GitPulse extends this pattern to multiple repos. ### Transferable UX Patterns **Navigation Patterns:** - **Command palette (Linear/Raycast)** — Cmd/Ctrl+K for quick access to any action (rescan, toggle view, batch pull). Scales without complicating the interface. - **Single-page dashboard** — No tab-based hierarchical navigation. Everything visible on one page with filters/toggles to change perspective. **Interaction Patterns:** - **Inline batch selection** — Checkbox on each card/row for multi-select. Context toolbar appears when items are selected (batch pull/push/fetch). - **Streaming progress** — Batch results appearing one by one (like Docker Desktop pull progress), no blocking until completion. - **Zero-setup first experience** — Like Raycast: launch → immediate action, no wizard. **Visual Patterns:** - **Status color system (Docker Desktop)** — Green/yellow/red/grey for status with legend integrated into badge (icon + color, not color alone for accessibility). - **Trust indicator (1Password)** — Permanent badge in a corner of the interface. Small, discreet, always present. Visually changes state when mode changes. - **Skeleton loading** — Instead of spinners, placeholder cards showing structure while awaiting data. ### Anti-Patterns to Avoid - **Mandatory login for local features (GitKraken)** — Users must use 100% of local features without an account. Login does not exist in GitPulse. - **Blocking modal wizards** — No "setup wizard" on first launch. Scan starts automatically, results appear directly. - **Global spinners without feedback** — Never a central spinner without progress indication. Always show advancement (repo count, progress bar, streaming results). - **Web-like chrome in a desktop app** — No web app sidebar navigation, no breadcrumbs, no hamburger menu header. The interface is a native dashboard. - **Excessive notifications** — System tray alerts only when relevant (repo behind, unpushed commits older than X days). No "tip of the day" or marketing notifications. - **AI as intrusive feature** — No "Configure AI!" popup on launch. AI is discoverable via Settings, and Smart Status appears naturally once configured. - **Color as sole status indicator** — Status badges use color + icon + label text for accessibility (NFR26-27). Never color alone. ### Design Inspiration Strategy **What to Adopt:** - Command palette (Cmd/Ctrl+K) — supports keyboard-first developer workflow - Status color + icon system (green/yellow/red/grey) — instant pattern recognition - Streaming batch results — tangible progress visibility - Privacy Badge as permanent element — trust through consistent presence - Skeleton loading — no layout shift during loading **What to Adapt:** - Card Grid layout — adapt Docker Desktop's multi-entity grid for repo context (branch, status, ahead/behind, stash) - System tray — adapt Raycast's "silent but present" background model with quick actions - Empty state — create an engaging first experience for Jay (0-10 repos) that encourages exploration rather than feeling sparse **What to Avoid:** - Web navigation patterns (sidebars, breadcrumbs, hamburger menus) - Setup wizards and mandatory configuration steps - Modal-heavy workflows - Notification spam - AI-first messaging or aggressive AI onboarding ## Design System Foundation ### Design System Choice **Approach: Tailwind CSS + Radix UI Primitives (Headless)** GitPulse uses a hybrid approach: Tailwind CSS for styling and the token system, combined with Radix UI for accessible component primitives (Dialog, Select, Tooltip, Dropdown). No full design system like Material/Ant — too heavy and too opinionated for a solo project with a custom visual identity. **Component Stack:** | Concern | Solution | Rationale | |---------|----------|-----------| | Styling & tokens | Tailwind CSS | Already chosen in architecture. Utility-first, fast for solo dev | | Component primitives | Radix UI | Accessible by default, unstyled (Tailwind controls visuals), lightweight | | Icons | Lucide React | Open source, tree-shakeable, consistent linear style | | Animations | Tailwind transitions + prefers-reduced-motion | Minimal, no animation library | | Virtualization | @tanstack/react-virtual | For rendering 100+ repos (FR14/NFR6 gap identified in architecture) | ### Rationale for Selection **Why not a full design system (Material, Ant, Chakra):** - GitPulse has a specific visual identity (status colors, Privacy Badge, card grid) that doesn't match Material/Ant conventions - Complete design systems add 50-100 KB to bundle — contradicts ~15 MB binary target - A solo developer doesn't benefit from full system velocity — customization takes longer than building from scratch with Tailwind - Desktop native architecture (Tauri webview) benefits from lean CSS **Why Radix UI over Headless UI or alternatives:** - Built-in accessibility (ARIA, keyboard nav) — directly addresses NFR25-27 - Unstyled: no CSS override battles, Tailwind controls 100% of visuals - Exact components GitPulse needs: Dialog (settings), Select (filters), Tooltip (status details), Dropdown (tray menu), Checkbox (batch select) - Maintained by Radix team, used in production by Linear, Vercel **Why Lucide React:** - Linear icon style consistent with "calm competence" aesthetic - Tree-shakeable — only used icons are included - Open source (ISC), no license constraints - 1000+ icons covering git, status, settings, AI ### Implementation Approach **Design tokens via Tailwind config:** ``` Status colors (core visual language): - status-clean: green-500 (clean repo) - status-dirty: red-500 (uncommitted changes) - status-ahead: blue-500 (ahead of remote) - status-behind: orange-500 (behind remote) - status-dormant: gray-400 (no activity > threshold) Neutrals: - bg-primary, bg-secondary, bg-surface - text-primary, text-secondary, text-muted Privacy indicator: - privacy-local: green-600 (Ollama / no AI) - privacy-cloud: amber-500 (cloud API active) ``` **Component architecture:** - `components/ui/` — Tailwind-styled primitives (Button, Badge, Card, Input, Dialog, Select, Skeleton, Tooltip) - Each primitive wraps a Radix component with Tailwind styling - Business components (RepoCard, PrivacyBadge, BatchToolbar) compose from primitives - No runtime theming — tokens are compiled into CSS ### Customization Strategy **Custom components (not in Radix, to be built):** - `RepoCard` / `RepoRow` — Card with status badge, branch label, ahead/behind counter, AI summary line - `PrivacyBadge` — Permanent local/cloud indicator with icon and label - `StatusBadge` — Colored badge with icon for each status (clean/dirty/ahead/behind/dormant) - `BatchProgress` — Repo list with streaming success/failure - `ViewToggle` — Grid/list toggle with icons - `EmptyState` — Illustration + CTA for 0 repos and < 10 repos **Accessibility in each custom component:** - StatusBadge: color + icon + aria-label (never color alone) - RepoCard: role="article", tabindex for keyboard nav - PrivacyBadge: aria-live="polite" when mode changes - BatchProgress: role="list", aria-label per repo result ## Core User Experience ### Defining Experience **"Launch and Know" — Open and immediately know.** The defining experience is the moment the user opens GitPulse and sees the state of all repos at a glance. No navigation, no setup, no searching. The Card Grid is GitPulse's "swipe" — the interaction that, if perfected, makes everything else natural. **What the user describes to a friend:** *"You launch it and you immediately see which repos are dirty, which are behind, which are dormant. No more checking one by one."* **The equation:** Repo count × info per repo = instant pattern recognition. If the Card Grid lets Sarah see in 2 seconds that 3 out of 30 repos need attention, the experience succeeds. ### User Mental Model **How developers currently think:** - Existing mental model: `cd repo && git status` — one repo at a time, mental stack limited to ~5 repos - Frustration: "I know I forgot to push something but I don't remember where" - Workarounds: shell scripts (fragile), mental notes (imperfect), growing anxiety with repo count **Expectations for GitPulse:** - Expects an "overview" — not a per-repo tool - Expects to understand status without reading text — visual recognition - Expects to act directly from the view — no additional navigation - Expects it to "just work" without config — like `ls` in a terminal **Potential confusion points:** - "Where are my repos?" if scan doesn't cover the right directories → Empty State with clear CTA - "What does this color mean?" if status system isn't instinctive → icons + labels, not color alone - "How do I act on a repo?" if actions aren't discoverable → right-click + command palette ### Success Criteria **The "Launch and Know" interaction succeeds when:** 1. **2-second scan** — User identifies problematic repos in < 2 seconds visually 2. **Zero learning curve** — First use without documentation, status meanings are instinctive 3. **Pattern recognition** — User perceives patterns ("3 repos behind", "all clean") without individual reading 4. **Action proximity** — User can act on a repo in < 2 clicks from the Card Grid 5. **Scale gracefully** — Experience is equally satisfying with 5 repos (Jay) as with 50+ (Sarah) **Success feedback:** - Status badges immediately interpretable (color + icon + count) - Ahead/behind counts visible directly on cards - "All clean" is a satisfying visual state — all green = peace of mind - Dirty/dormant repos "pop" visually — the eye is naturally drawn to problems ### Novel UX Patterns **Established patterns adopted:** - Card Grid (Docker Desktop, Trello) — familiar, adapted for multi-entity - Status color system (traffic lights, Docker) — universally understood - Multi-select + batch actions (email clients, file managers) — known pattern - Command palette (VS Code, Linear) — developers know it **GitPulse's unique twist:** - The **Privacy Badge** is a novel pattern in git tools. No competitor offers a privacy indicator. It's a visual differentiator — the green "local" padlock becomes GitPulse's visual signature. - **Smart Status inline** — AI summaries aren't in a separate panel but integrated directly into cards as natural content. A discreet "AI" badge indicates the source. This "invisible AI augmentation" pattern is new in git tools. - **Dormancy glow** — Dormant repos get subtle visual treatment (reduced opacity, "sleeping" badge) that signals inactivity without being alarmist. No red — it's information, not a problem. ### Experience Mechanics **Flow: Launch and Know** **1. Initiation:** - Double-click exe/dmg → window opens directly (no splash screen) - First launch: auto-scan of home directory. Results appear progressively. - Subsequent launches: cache loaded instantly, then background rescan for updates. **2. Visual scan (2-second pattern recognition):** - Eye scans Card Grid left-to-right, top-to-bottom - Status badges (color + icon) are first fixation point — brain automatically filters by color - "Problematic" cards (red, orange) attract attention first - "Clean" cards (green) form a reassuring background - "Dormant" cards (grey, reduced opacity) blend into the background **3. Action proximity:** - Click on card → expand detail (branch, last commit, stash, AI summary) - Right-click → context menu (pull, push, fetch, open in terminal) - Multi-select (checkbox or Shift/Ctrl+click) → batch toolbar appears - Cmd/Ctrl+K → command palette for quick actions **4. Feedback loop:** - Batch op in progress → each repo visually transitions (grey → spinner → green/red) - Results visible in real-time — no need to wait for batch completion - Errors displayed inline on the concerned repo's card (no global error modal) **5. Completion:** - "All clean" is the resting state — user closes dashboard, confident - System tray continues passive monitoring - Notification only if a repo changes state (new behind, dirty detected) ## Visual Design Foundation ### Color System **Philosophy:** GitPulse is a developer desktop tool. Dark mode is the default (developer preference), with full light mode support. Status colors are the heart of the visual system. **Dark Mode (default):** | Token | Value | Usage | |-------|-------|-------| | `bg-primary` | `gray-950` (#0a0a0a) | Main background | | `bg-surface` | `gray-900` (#171717) | Card backgrounds | | `bg-elevated` | `gray-800` (#262626) | Hovered cards, dropdowns | | `border` | `gray-700` (#404040) | Card borders, dividers | | `text-primary` | `gray-50` (#fafafa) | Main text | | `text-secondary` | `gray-300` (#d4d4d4) | Secondary text, labels | | `text-muted` | `gray-500` (#737373) | Muted text, timestamps | **Status Colors (shared dark/light):** | Status | Color | Icon | Tailwind | |--------|-------|------|----------| | Clean | Green | CheckCircle | `text-green-500` / `bg-green-500/10` | | Dirty | Red | AlertCircle | `text-red-500` / `bg-red-500/10` | | Ahead | Blue | ArrowUpCircle | `text-blue-500` / `bg-blue-500/10` | | Behind | Orange | ArrowDownCircle | `text-orange-500` / `bg-orange-500/10` | | Dormant | Gray | Moon | `text-gray-400` / `bg-gray-400/10` | **Privacy Indicator:** - Local: `text-green-600` + shield icon + label "Local" - Cloud: `text-amber-500` + cloud icon + label provider name **Accessibility:** All text/background combos meet WCAG AA contrast ratio (4.5:1 normal text, 3:1 large text). Status badges always use color + icon + label, never color alone. ### Typography System **Principle: "Native feel" = system fonts by default.** GitPulse uses platform system fonts for native rendering. No web fonts to load — instant performance and OS consistency. **Font stack:** ```css font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, Arial, sans-serif; ``` - macOS: San Francisco - Windows: Segoe UI - Linux: Noto Sans **Code/monospace (branch names, commit hashes):** ```css font-family: "SF Mono", "Cascadia Code", "Fira Code", "Consolas", monospace; ``` **Type Scale:** | Role | Size | Weight | Usage | |------|------|--------|-------| | `text-xl` | 20px | Semibold (600) | Window title, empty state heading | | `text-lg` | 18px | Medium (500) | Section headings | | `text-base` | 16px | Regular (400) | Card repo name, primary content | | `text-sm` | 14px | Regular (400) | Branch names, status text, AI summaries | | `text-xs` | 12px | Medium (500) | Timestamps, badges, counts, muted info | **Line heights:** 1.5 for body text, 1.2 for headings, 1.0 for single-line data (counts, badges). ### Spacing & Layout Foundation **Base unit: 4px.** All spacing is a multiple of 4px for consistency. **Spacing Scale:** | Token | Value | Usage | |-------|-------|-------| | `space-1` | 4px | Inline gaps, icon padding | | `space-2` | 8px | Tight component spacing, badge padding | | `space-3` | 12px | Card internal padding | | `space-4` | 16px | Standard padding, card gaps | | `space-6` | 24px | Section spacing | | `space-8` | 32px | Major section breaks | **Card Grid Layout:** - Grid gap: 16px (`space-4`) - Card min-width: 280px, max-width: 360px - Responsive: auto-fill with `minmax(280px, 1fr)` - Cards per row: adapts to window width (2-5 cards) **List View Layout:** - Row height: 56px - Columns: checkbox | status icon | repo name | branch | ahead/behind | last commit | actions - Column widths: fixed for status (32px), flexible for name, fixed for counts **Window Layout:** - Min window size: 800×600 - Default window size: 1200×800 - Top bar: 48px (title + view toggle + filters + Privacy Badge) - No sidebar — single-page dashboard ### Accessibility Considerations - **Contrast:** All text/background combos meet WCAG AA (4.5:1 normal, 3:1 large text) - **Status identification:** Never color alone — always color + icon + text label - **Focus indicators:** Visible focus rings (2px ring, offset 2px) on all interactive elements - **Keyboard navigation:** Tab order logical (top bar → cards → actions), arrow keys within card grid - **Screen readers:** ARIA labels on all status badges, live regions for batch results and privacy mode changes - **Reduced motion:** `prefers-reduced-motion` respected — no animations when OS setting is active - **High contrast:** OS high contrast mode triggers fallback to system colors with enhanced borders ## Design Direction Decision ### Design Directions Explored Six design directions were generated and evaluated as interactive HTML mockups (`ux-design-directions.html`): 1. **Compact Grid** — Maximum density, tight cards, status badges pop 2. **Spacious Cards** — Breathing room, metric boxes, AI summaries prominent 3. **List-First** — Table layout, batch-native, power user focus 4. **Stats Dashboard + Grid** — Summary metrics bar above card grid 5. **Hybrid Detail Panel** — Split view with left list + right detail panel 6. **Minimal Zen** — Ultra-clean status dots, click-to-expand ### Chosen Direction **D1 Compact Grid + D4 Stats Bar (combined)** The compact card grid delivers the 2-second pattern recognition that defines GitPulse's core experience. The collapsible stats bar adds "mission control" context without sacrificing grid density. **Layout structure (top to bottom):** 1. **Top bar** (48px) — Title, Grid/List toggle, filter pills with counts, rescan button, Privacy Badge 2. **Stats bar** (collapsible, ~60px) — 5 metric cards: Clean / Dirty / Ahead / Behind / Dormant counts 3. **Card Grid** (main area) — Compact repo cards with status badge, branch, ahead/behind/stash, last commit time 4. **Batch toolbar** (appears on multi-select) — Pull, Push, Fetch, Status actions with count **Card Grid is default view. List View (D3 table) available via toggle for batch operations and power-user sorting/filtering.** ### Design Rationale **Why Compact Grid (not Spacious):** - GitPulse's core value is seeing ALL repos at once. More cards visible = better pattern recognition. - Sarah (30+ repos) needs density. Jay (< 10 repos) doesn't need spaciousness — the empty space would feel worse, not better. - AI Smart Status fits as a subtle one-liner in the card footer. It enriches without requiring card expansion. **Why Stats Bar (collapsible):** - "7 clean, 1 dirty, 2 behind" visible without scanning cards = instant health overview. - Collapsible because power users (Leo) may find it redundant after the first week. - Stats bar doubles as a filter — clicking a stat card filters the grid to that status. **Why not Hybrid Panel (D5):** - Only one repo visible in detail at a time contradicts GitPulse's "see everything at a glance" principle. - Detail info (commits, AI summary) accessible via click-to-expand on individual cards instead. **Why not Minimal Zen (D6):** - Too minimal for a tool users rely on daily. Branch names and counts are essential, not optional. - Risks perception of "incomplete" rather than "elegant." ### Implementation Approach **Component hierarchy:** ``` App ├── TopBar │ ├── ViewToggle (Grid/List) │ ├── FilterPills (All, Dirty, Behind, Dormant) with counts │ ├── RescanButton │ └── PrivacyBadge ├── StatsBar (collapsible) │ └── StatCard × 5 (Clean, Dirty, Ahead, Behind, Dormant) ├── CardGrid (default view, virtualized) │ └── RepoCard × N │ ├── StatusBadge │ ├── BranchLabel │ ├── CountStats (ahead/behind/stash) │ ├── SmartStatusLine (optional, when AI configured) │ └── LastCommitTime ├── ListView (toggled view) │ ├── ListHeader (sortable columns) │ └── RepoRow × N (with checkboxes) └── BatchToolbar (appears on multi-select) ├── SelectionCount └── ActionButtons (Pull, Push, Fetch, Status) ``` ## User Journey Flows ### Journey 1: First Launch (Jay's Journey — 5-Second Wow) **Goal:** Jay downloads GitPulse, launches, and sees a full dashboard in < 30 seconds. Zero config, zero login. ```mermaid flowchart TD A[Download binary] --> B[Launch GitPulse] B --> C{First launch?} C -->|Yes| D[Auto-scan home directory] C -->|No| E[Load cached repos instantly] D --> F[Show scan progress: repo count climbing] F --> G{Repos found?} G -->|0 repos| H[Empty State: Add scan directories CTA] G -->|1-9 repos| I[Card Grid + Stats Bar] G -->|10+ repos| I E --> I H --> J[User adds scan root] J --> D I --> K[User sees status badges at a glance] K --> L{Problem repos visible?} L -->|Yes| M[Click dirty/behind card for detail] L -->|No| N[All clean = peace of mind] M --> O[Right-click context menu: Pull / Open terminal] N --> P[Close dashboard or minimize to tray] ``` **Entry points:** Double-click binary, system tray icon click **Success criteria:** Dashboard visible with repo statuses in < 30 seconds from launch **Error recovery:** 0 repos → Empty State with clear CTA to add scan directories **Feedback:** Scan progress shows repo count climbing, skeleton cards during load ### Journey 2: Daily Status Check (Sarah's Journey — Morning Check-in) **Goal:** Sarah opens GitPulse in the morning, identifies in 2 seconds the 3 repos needing attention among 30+ repos. ```mermaid flowchart TD A[Launch GitPulse] --> B[Cache loads instantly] B --> C[Background rescan starts] C --> D[Stats Bar: 24 clean, 3 dirty, 2 behind, 1 dormant] D --> E[Sarah scans Card Grid visually] E --> F[Eye drawn to red/orange cards] F --> G[auth-service: Dirty, 3 uncommitted] F --> H[shared-libs: Behind 12 commits] F --> I[old-experiment: Dormant, 3 months] G --> J[Click auth-service card] J --> K[Card expands: branch, stash, AI summary] K --> L[Right-click: Open in terminal] H --> M[Select shared-libs checkbox] M --> N[Batch toolbar appears] N --> O[Click Pull] O --> P[Streaming results: green checkmark appears] I --> Q[Note: will clean up later] L --> R[Commit and push in terminal] P --> S[Stats Bar updates: behind count drops to 0] R --> T[Rescan: auth-service turns green] T --> U[All clean. Close dashboard. Tray continues monitoring.] ``` **Entry points:** App launch, system tray click **Success criteria:** Problem repos identified in < 2 seconds, action taken in < 30 seconds **Feedback:** Stats bar provides numeric context, card colors provide instant pattern recognition **Error recovery:** Pull fails on shared-libs → red X with error detail inline, other repos unaffected ### Journey 3: Batch Operations (Leo's Journey — Sprint Start) **Goal:** Leo batch-pulls 12 microservice repos at sprint start, then uses Smart Status to verify overall health. ```mermaid flowchart TD A[Leo opens GitPulse] --> B[Switch to List View] B --> C[Click column header: Sort by Behind] C --> D[12 repos behind remote] D --> E[Select All behind] E --> F[Batch toolbar: 12 repos selected] F --> G[Click Pull] G --> H[Streaming results appear row by row] H --> I{Per-repo result} I -->|Success| J[Row turns green, checkmark] I -->|Auth error| K[Row turns red, error detail inline] I -->|Conflict| L[Row turns red, merge conflict message] J --> M[10/12 succeeded] K --> N[2/12 failed: api-auth, payment-svc] L --> N M --> O[Click failed repo for error detail] N --> O O --> P[Resolve in terminal or retry] P --> Q[Rescan: all green] Q --> R[Configure DeepSeek API key in Settings] R --> S[Privacy Badge: Local changes to Cloud DeepSeek] S --> T[Smart Status summaries appear on cards] T --> U[AI: All microservices synced. Shared auth library version mismatch in 2 repos.] ``` **Entry points:** App launch, Monday morning routine **Success criteria:** 12 repos pulled in < 30 seconds, partial failures clearly reported **Feedback:** Streaming per-repo results, success count updating in real-time **Error recovery:** Failed repos show specific error (auth, conflict), successful repos complete independently ### Journey 4: Dormancy Cleanup (Max's Journey — Monthly Review) **Goal:** Max discovers 8 dormant repos and decides which to archive. ```mermaid flowchart TD A[Max opens GitPulse] --> B[Filter: Dormant] B --> C[8 repos shown with reduced opacity] C --> D[Stats Bar: 8 dormant more than 90 days] D --> E[Scan cards: old-prototype, tutorial-clone...] E --> F[Click old-prototype card] F --> G[Smart Status: Last commit 6 months ago. Safe to archive.] G --> H{Action?} H -->|Archive| I[Right-click: Open in file manager] H -->|Keep| J[Move on to next] I --> K[Manually archive/move directory] J --> L[Rescan: dormant repos update] K --> L L --> M[Check remaining repos] M --> N[3 repos have uncommitted changes from weeks ago] N --> O[Select 3 then Batch status] O --> P[Review uncommitted changes] P --> Q[Decide: commit and push or discard] ``` **Entry points:** Weekly/monthly review, tray notification ("3 repos dormant for 90+ days") **Success criteria:** Identify and action dormant repos in a single session **Feedback:** Dormant filter shows only relevant repos, reduced opacity visually deprioritizes them **Error recovery:** No destructive actions in GitPulse — "archive" opens file manager, user decides ### Journey Patterns **Navigation Pattern — Filter then Act:** 1. User applies a filter (status, or click stat card) → grid shows only matching repos 2. User scans filtered results → identifies targets 3. User selects and acts → batch toolbar appears 4. Results stream in → grid updates in real-time **Feedback Pattern — Streaming Progress:** 1. Action triggered → all selected items show "loading" state (grey spinner) 2. Each item completes → transitions to success (green) or failure (red + detail) 3. Progress counter in toolbar: "10/12 complete" 4. Stats bar updates after all items finish **Error Pattern — Isolate and Report:** 1. Error occurs on one item → only that item affected 2. Item shows inline error detail (not modal) 3. User clicks error for expanded detail 4. Other items continue processing unaffected ### Flow Optimization Principles 1. **Minimize steps to value** — Every journey starts with "open and see." No intermediate screens between launch and dashboard. 2. **Progressive disclosure** — Card shows essential info. Click expands detail. Right-click offers actions. No information overload on first glance. 3. **Batch by default** — Multi-select and batch toolbar make acting on multiple repos as natural as acting on one. 4. **Error isolation** — Failures never block successes. Every batch operation shows per-item results independently. 5. **Stats as navigation** — Clicking a stat card (e.g., "3 dirty") filters the grid, combining overview and action in one interaction. ## Component Strategy ### Design System Components **From Radix UI (styled with Tailwind tokens):** | Radix Primitive | GitPulse Usage | Styling | |----------------|----------------|---------| | `Dialog` | Settings panels, AI config | Tailwind: bg-surface, border, rounded-xl | | `Select` | Sort dropdown, filter selector | Tailwind: custom trigger, status-colored options | | `Tooltip` | Status badge hover details, counts | Tailwind: bg-elevated, text-sm, delay-300 | | `DropdownMenu` | Right-click context on cards/rows | Tailwind: bg-surface, items with icons | | `Checkbox` | Batch selection in List View | Tailwind: border, rounded, checked:bg-blue-500 | | `ToggleGroup` | Grid/List view switch | Tailwind: border, rounded-lg, active:bg-elevated | | `Popover` | Card detail expansion on click | Tailwind: bg-surface, shadow-xl | | `Separator` | Stats bar dividers, card sections | Tailwind: bg-border | **From Lucide React (icons):** | Icon | Usage | Component | |------|-------|-----------| | CheckCircle | Clean status | StatusBadge | | AlertCircle | Dirty status | StatusBadge | | ArrowUpCircle | Ahead status | StatusBadge | | ArrowDownCircle | Behind status | StatusBadge | | Moon | Dormant status | StatusBadge | | Shield | Privacy local | PrivacyBadge | | Cloud | Privacy cloud | PrivacyBadge | | RefreshCw | Rescan | TopBar | | Grid / List | View toggle | ViewToggle | | GitBranch | Branch label | RepoCard | | Clock | Last commit | RepoCard | | Inbox | Stash count | RepoCard | ### Custom Components #### RepoCard **Purpose:** Display a single repository's status in the Card Grid. The fundamental unit of the GitPulse dashboard. **Anatomy:** ``` +------------------------------+ | repo-name [Badge] | header: name + StatusBadge | branch-name | monospace branch label | Ahead: 3 Behind: 0 S: 0 | count stats | --------------------------- | subtle divider | 2h ago 3 unpushed | footer: time + action badge | AI: 3 unpushed commits... | SmartStatusLine (optional) +------------------------------+ ``` **States:** default, hover (border-lighten, bg-elevated), selected (border-blue), loading (skeleton), error (border-red), dormant (opacity-50) **Accessibility:** role="article", tabindex=0, aria-label="Repository {name}: {status}, {ahead} ahead, {behind} behind", Enter/Space opens detail popover #### RepoRow **Purpose:** Table row for List View with sortable columns and checkbox selection. **Anatomy:** ``` [checkbox] [icon] repo-name branch up:3 down:0 2h ago [menu] ``` **States:** default, hover (bg-elevated), selected (bg-blue/5), loading, error (bg-red/5) **Accessibility:** role="row", aria-selected, checkbox keyboard accessible #### StatusBadge **Purpose:** Compact visual indicator for repository status. Always uses color + icon + label text. **Variants:** | Variant | Color | Icon | Label | |---------|-------|------|-------| | clean | green-500 | CheckCircle | "Clean" | | dirty | red-500 | AlertCircle | "Dirty" | | ahead | blue-500 | ArrowUpCircle | "Ahead" | | behind | orange-500 | ArrowDownCircle | "Behind" | | dormant | gray-400 | Moon | "Dormant" | **Sizes:** sm (10px text, compact cards), md (12px text, default), lg (14px text, stats bar) **Accessibility:** aria-label="{status} repository", never relies on color alone #### StatsBar **Purpose:** Summary metrics bar at top of dashboard. Collapsible. Each stat card is clickable to filter grid. **Anatomy:** ``` +--------+ +--------+ +--------+ +--------+ +--------+ | 7 | | 1 | | 3 | | 2 | | 1 | | Clean | | Dirty | | Ahead | | Behind | |Dormant | +--------+ +--------+ +--------+ +--------+ +--------+ ``` **States:** Each stat card: default, hover (cursor-pointer, bg-elevated), active/filtered (border-status-color) **Accessibility:** Each card has aria-label="{count} {status} repositories", role="button", click filters grid #### PrivacyBadge **Purpose:** Permanent indicator showing local vs cloud data processing mode. Always visible in TopBar. **Variants:** | Mode | Icon | Color | Label | |------|------|-------|-------| | local/no AI | Shield | green-600 | "Local" | | Ollama | Shield | green-600 | "Local" | | Cloud provider | Cloud | amber-500 | "{Provider}" | **States:** Transition animation when mode changes (subtle color crossfade), aria-live="polite" announces change to screen readers #### BatchToolbar **Purpose:** Appears when repos are selected. Shows count and action buttons. **Anatomy:** ``` | 3 selected [Pull] [Push] [Fetch] [Status] [Cancel] | ``` **States:** Appears with slide-down animation, disappears when selection clears, buttons disabled during active operation, progress counter replaces selection count during operation **Accessibility:** role="toolbar", aria-label="{count} repositories selected", each button has aria-label with action + count #### SmartStatusLine **Purpose:** AI-generated one-line health summary. Appears in RepoCard footer when AI is configured. **Anatomy:** ``` | AI: 3 unpushed commits on feature branch. Ready for PR. | ``` Blue left border (2px), text-sm, text-secondary, italic, optional "AI" micro-badge **States:** loading (skeleton pulse), loaded (text), error (hidden — no error shown, graceful absence) **Accessibility:** aria-label="AI summary: {text}", visually indicated by left border color #### EmptyState **Purpose:** Displayed when no repos are found. Engaging CTA to add scan directories. **Anatomy:** ``` +----------------------------------+ | [Git illustration] | | No repositories found | | Add directories to scan | | [Open Settings] | | | | Tip: GitPulse scans for | | .git folders recursively | +----------------------------------+ ``` **Accessibility:** role="status", aria-live="polite", CTA button keyboard focusable ### Component Implementation Strategy **Layer 1 — Radix + Tailwind Primitives** (`components/ui/`): - Button, Card, Dialog, Select, Tooltip, DropdownMenu, Checkbox, ToggleGroup, Input, Skeleton - Each wraps Radix with Tailwind styling. No custom logic. **Layer 2 — GitPulse Domain Components** (`components/dashboard/`, `components/batch/`, `components/ai/`): - RepoCard, RepoRow, StatusBadge, StatsBar, PrivacyBadge, BatchToolbar, SmartStatusLine, EmptyState - Composed from Layer 1 primitives + domain logic (Tauri IPC calls via hooks) **Layer 3 — Feature Compositions** (`App.tsx`): - TopBar, CardGrid, ListView - Wire Layer 2 components together with stores and hooks ### Implementation Roadmap **Phase 1 — Core Dashboard (FR1-FR13):** 1. StatusBadge — foundation for all visual status 2. RepoCard — core card component 3. CardGrid — virtualized grid with @tanstack/react-virtual 4. StatsBar — summary metrics 5. EmptyState — 0 repos experience **Phase 2 — Batch Operations (FR15-FR21):** 6. RepoRow — list view row with checkbox 7. BatchToolbar — selection actions 8. ListView — sortable table with virtualization **Phase 3 — AI & Settings (FR22-FR41):** 9. PrivacyBadge — trust indicator 10. SmartStatusLine — AI summary in cards 11. Settings panels — using Radix Dialog + primitives ## UX Consistency Patterns ### Button Hierarchy | Priority | Style | Usage | Example | |----------|-------|-------|---------| | **Primary** | bg-blue-500, text-white, rounded-lg | Main action per context | "Pull", "Save Settings" | | **Secondary** | bg-elevated, border, text-primary | Alternative actions | "Push", "Fetch", "Cancel" | | **Destructive** | bg-red-500/10, text-red-500, border-red | Irreversible actions | "Reset All Settings" | | **Ghost** | transparent, text-secondary, hover:bg-elevated | Low-priority, toolbar | "Rescan", view toggle icons | | **Disabled** | opacity-50, cursor-not-allowed | Unavailable action | Batch buttons during active op | **Rules:** - Only one primary button visible per context - Destructive actions always require confirmation (Radix Dialog) - Button text is always a verb ("Pull", not "OK") - Icon + text for primary, icon-only for ghost/toolbar with tooltip ### Feedback Patterns **Success:** - Repo-level: card/row transitions to green checkmark, brief green flash on status badge - Batch-level: counter updates "10/12 complete", stats bar numbers animate - No toast/notification for success — the visual state change IS the feedback **Error:** - Repo-level: card/row shows red border + inline error text (e.g., "Auth failed", "Merge conflict") - Batch-level: failed repos highlighted, successful repos remain green. "2/12 failed" in toolbar - Error detail: click failed repo → popover with full error message + suggested action - Never modal for batch errors — always inline **Warning:** - Privacy mode change: PrivacyBadge transitions with amber flash + aria-live announcement - Dormancy: reduced opacity + dormant badge, no red/orange alarm **Info:** - Scan progress: repo count climbs in real-time ("Scanning... 12 repos found") - Background rescan: subtle progress indicator in top bar, non-blocking ### Loading States **Skeleton loading (initial load):** - Card grid shows skeleton cards (grey rectangles matching RepoCard shape) during first scan - No central spinner — skeleton cards communicate layout and progress simultaneously - Skeleton count matches cached repo count if available, otherwise show 6 skeletons **Streaming loading (batch operations):** - Each repo transitions individually: default → spinner overlay → green/red result - Other repos remain interactive during batch — user can still click and explore - Batch toolbar shows progress counter: "Pulling... 7/12" **Inline loading (AI queries):** - SmartStatusLine shows skeleton pulse animation while AI generates summary - Other card content remains visible and interactive during AI load - If AI fails or times out: SmartStatusLine simply doesn't appear (graceful absence) **Never:** - Never a full-page spinner blocking all interaction - Never a modal "Loading..." dialog - Never disable the entire UI during an operation ### Empty States **0 repos found:** - Center of dashboard: Git illustration, "No repositories found", "Add directories to scan" - Primary CTA button: "Open Settings" → opens Settings to Scan Roots tab - Secondary text: "GitPulse scans for .git folders recursively" - Stats bar hidden (no data to show) **0 results after filter:** - Center of grid area: "No {status} repositories" with filter icon - Ghost button: "Clear filter" → resets filter to "All" - Suggestion: "Try a different filter or rescan" **First launch scanning:** - "Scanning your directories..." with animated repo count - First repo appears immediately as skeleton → fills in as discovered - Transition from empty state to card grid is seamless (cards appear progressively) ### Navigation Patterns **Primary navigation — single page:** - No sidebar, no tabs, no routing. The dashboard IS the app. - Content changes via: filters, view toggle, card expansion **Context menus — right-click:** ``` [Repo name] ───────────── Pull Push Fetch ───────────── Open in Terminal Open in File Manager Copy Path ───────────── Refresh Status ``` - Dividers separate action groups (git ops / system / utility) - Actions use Lucide icons + text label - Disabled items shown greyed, not hidden **Command palette — Cmd/Ctrl+K:** ``` +----------------------------------+ | Search commands... | +----------------------------------+ | Rescan All Repositories | | Toggle Grid / List View | | Filter: Dirty Repos | | Filter: Behind Repos | | Batch Pull Selected | | Open Settings | | Open AI Configuration | | Check for Updates | +----------------------------------+ ``` - Fuzzy search on command names - Keyboard navigable (arrow keys + Enter) - Esc to close ### Additional Patterns **Toastless design:** - GitPulse does not use toast notifications in the dashboard - All feedback is inline (card states, toolbar counters, stats bar) - System tray uses native OS notifications for background alerts only **Keyboard shortcuts:** | Shortcut | Action | |----------|--------| | Cmd/Ctrl+K | Command palette | | Cmd/Ctrl+G | Switch to Grid view | | Cmd/Ctrl+L | Switch to List view | | Cmd/Ctrl+R | Rescan | | Cmd/Ctrl+, | Open Settings | | Cmd/Ctrl+A | Select all repos | | Escape | Clear selection / close palette | | Space (on card) | Toggle selection | | Enter (on card) | Expand detail | **Confirmation patterns:** - Destructive actions (Reset Settings): Radix Dialog with "This cannot be undone" + Cancel/Confirm - Batch operations on 10+ repos: no confirmation — progress is visible, user can cancel mid-operation - Privacy mode change: no confirmation needed — PrivacyBadge updates, user can revert in Settings **Window behavior:** - Closing window → minimizes to system tray (app continues running) - Cmd/Ctrl+Q or tray Quit → actually quits - Window position/size remembered across launches ## Responsive Design & Accessibility ### Responsive Strategy **Desktop-only — no mobile, no tablet.** GitPulse is a native desktop application (Tauri v2). Responsive design is limited to adapting the desktop window between minimum size (800x600) and large screens (2560x1440+). **No mobile/tablet strategy:** - No touch interactions - No bottom navigation - No hamburger menu - No mobile breakpoints - System tray handles the "minimal" context when dashboard is closed **Window resize adaptation:** | Window Width | Card Grid Behavior | Stats Bar | Top Bar | |-------------|-------------------|-----------|---------| | < 900px | 2 cards per row | Collapsed (icon counts only) | Filters hidden in dropdown | | 900-1200px | 3 cards per row | Expanded (5 stat cards) | Full top bar | | 1200-1600px | 4 cards per row | Expanded | Full top bar | | > 1600px | 5+ cards per row | Expanded | Full top bar, more breathing room | **Window height adaptation:** - < 600px (minimum): stats bar auto-collapsed, grid scrollable - 600-800px: stats bar visible, grid fits ~3 rows of cards - > 800px: full experience, 4+ rows visible without scroll **Resize behavior:** - Card grid reflows immediately (CSS Grid auto-fill) - Stats bar collapse/expand is smooth, no content jump - Window position and size persisted via `tauri-plugin-store` - Min window size enforced: 800x600 ### Breakpoint Strategy **Desktop breakpoints only (CSS media queries within Tauri webview):** | Breakpoint | Width | Layout Change | |-----------|-------|---------------| | `sm` | < 900px | 2-col grid, collapsed stats, compact top bar | | `md` | 900-1199px | 3-col grid, full stats, full top bar | | `lg` | 1200-1599px | 4-col grid (default) | | `xl` | >= 1600px | 5+ col grid, max-width container optional | **Implementation:** Tailwind breakpoints (`sm:`, `md:`, `lg:`, `xl:`) applied directly in component classes. No CSS-in-JS, no runtime theme switching. ### Accessibility Strategy **Target: WCAG 2.1 Level AA** (industry standard, addresses NFR25-27) **1. Color & Contrast (NFR26):** - All text meets 4.5:1 contrast ratio (normal text), 3:1 (large text/UI components) - Status indicators never rely on color alone — always color + icon + text label - StatusBadge tested against: protanopia, deuteranopia, tritanopia, achromatopsia - High contrast mode: OS setting triggers fallback to system colors + enhanced borders **2. Keyboard Navigation (NFR25):** - All interactive elements reachable via Tab - Arrow keys navigate within card grid (2D grid navigation pattern) - Enter/Space activates focused element - Escape closes popovers/command palette - Focus trap in Dialog (settings) — Tab cycles within dialog - Visible focus indicators: 2px ring, offset 2px, blue-500 color - Skip-to-content: Cmd/Ctrl+K serves as universal keyboard entry point **3. Screen Reader Compatibility (NFR27):** - ARIA landmarks: main (dashboard), navigation (top bar), toolbar (batch) - ARIA labels on all status badges: "Repository auth-service: Dirty, 7 commits ahead" - aria-live="polite" for dynamic content: batch results, privacy mode changes, scan progress - RepoCard: role="article" with descriptive aria-label - StatsBar: each stat card has role="button" with aria-label - SmartStatusLine: aria-label="AI summary: {text}" - Error states: aria-live="assertive" for critical errors **4. Motion & Animation:** - `prefers-reduced-motion` media query respected - All transitions use `motion-safe:` Tailwind prefix - No auto-playing animations - Skeleton loading: static when reduced-motion preferred **5. Focus Management:** - Dialog opens → focus trapped in dialog, first interactive element focused - Dialog closes → focus returns to trigger element - Command palette → focus trapped in palette list - Card expansion → focus moves to expanded content - Tab order: top bar → stats bar → card grid → batch toolbar ### Testing Strategy **Automated testing:** - Playwright e2e tests with `@axe-core/playwright` for automated WCAG checks - Run on every PR via CI - Key scenarios: dashboard load, card grid rendering, batch operations, settings dialog **Manual testing (per release):** - Keyboard-only navigation: complete all core journeys without mouse - Screen reader testing: macOS VoiceOver (primary), Windows NVDA - Color blindness simulation: Chrome DevTools color vision deficiency - High contrast mode: Windows High Contrast, macOS Increase Contrast **Test matrix:** | Platform | Screen Reader | Test Focus | |----------|--------------|------------| | macOS | VoiceOver | Card grid nav, batch ops, settings | | Windows | NVDA | Full journey: scan → dashboard → batch | | Linux | Orca | Basic dashboard navigation | ### Implementation Guidelines **For AI agents implementing components:** 1. All status indicators must use StatusBadge component — never ad-hoc colored elements 2. All interactive elements must have focus-visible styles and keyboard handlers 3. All dynamic content must have aria-live region for announcements 4. All dialogs must use Radix Dialog (handles focus trap and aria automatically) 5. All icons must have accompanying text or aria-label — never icon-only meaning 6. All batch operations must emit per-repo events with accessible status updates 7. Window resize must use Tailwind responsive classes, never JavaScript resize listeners 8. Reduced motion must use Tailwind `motion-safe:` prefix for all transitions/animations