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

59 KiB
Raw Permalink Blame History

stepsCompleted, inputDocuments, workflowType, project_name, user_name, date, lastStep, status, completedAt
stepsCompleted inputDocuments workflowType project_name user_name date lastStep status completedAt
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
prd.md
product-brief-gitpulse.md
product-brief-gitpulse-distillate.md
architecture.md
research/market-git-dashboard-ia-research-2026-04-24.md
ux-design GitPulse Ramez 2025-04-25 14 complete 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:

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):

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.

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.

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.

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.

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