Files
GitPulse/_bmad-output/planning-artifacts/ux-design-specification.md
sepehr 4f7e808855 Initial commit: GitPulse project scaffold
Next.js dashboard with git statistics, AI-powered summaries via Ollama,
and research documents for project planning.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-25 16:53:39 +02:00

1277 lines
59 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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
---
<!-- UX design content will be appended sequentially through collaborative workflow steps -->
## 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