diff --git a/AGENTS.md b/AGENTS.md index 7ccf4e2..c722119 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -12,6 +12,10 @@ Use `pnpm install` to install frontend dependencies. Run `pnpm tauri:dev` for th Follow the existing style rather than introducing new patterns. TypeScript uses 2-space indentation, semicolons, PascalCase for components and types, and camelCase for functions, state, and Tauri payload fields. Keep frontend IPC definitions in `src/lib/api.ts` and shared TS shapes in `src/lib/types.ts`. Rust follows standard `rustfmt` formatting, `snake_case` names, and `#[serde(rename_all = "camelCase")]` for structs crossing the JS bridge. +## Design System Preview + +When adjusting colors, tokens, or component styles, use `design-system.html` (project root) to visually verify changes. It imports `src/styles.css` directly via Vite. Run `pnpm tauri:dev` (port 1420), then open `http://localhost:1420/design-system.html` via Chrome DevTools MCP to preview all tokens and components live. Toggle `[data-theme="dark"]` on `` to check dark mode. + ## Testing Guidelines Backend tests are inline Rust unit tests placed in `mod tests` blocks inside the relevant module files such as `src-tauri/src/git.rs`, `config.rs`, and `actions.rs`. Add tests next to the behavior you change. There is currently no dedicated frontend test harness, so at minimum run `pnpm build` after UI or API changes and `cargo test` after backend edits. diff --git a/CLAUDE.md b/CLAUDE.md index 0c34c94..e5cebc6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -54,6 +54,7 @@ All UI work **must** follow `DESIGN_SYSTEM.md`. Key rules: - **Spacing**: 2px base grid. Common stops: 6, 8, 10, 12, 14, 20, 24px. Follow existing patterns. - **Transitions**: Buttons `140ms ease`, list items `100ms ease`, slide-out `180ms ease-out`. - **Dark mode**: Supports Light / Dark / System. All colors use CSS custom properties (`var(--token)`). When adding new UI, always use existing tokens from `:root` — never hardcode colors. Verify new pages/components look correct in both light and dark mode. +- **Preview**: `design-system.html` at project root renders all tokens and components using the real `src/styles.css`. When adjusting colors or tokens, run `pnpm tauri:dev` (Vite dev server on port 1420), then use Chrome DevTools MCP to open `http://localhost:1420/design-system.html` to visually verify changes in real time. Toggle `[data-theme="dark"]` on `` to check dark mode. ## Notes @@ -64,4 +65,4 @@ All UI work **must** follow `DESIGN_SYSTEM.md`. Key rules: ## UI Layout -Top navigation bar (38px, `titleBarStyle: overlay` with 78px left padding for macOS traffic lights) + full-width content area. Topbar: brand, 4 tabs (Repository, Worktrees, Hooks, Settings), "New Worktree" button on the right. Views: Repository (centered card with repo picker), Worktrees (master-detail grid: 280px worktree list | detail panel), Hooks (inline hooks editor), Settings (language, terminal, shell, tray icon, tooling, logs, config). Create worktree uses a right-side slide-out panel. +Topbar (38px, `titleBarStyle: overlay` with 78px left padding for macOS traffic lights) shows brand + centered repo path. Left sidebar (48px, icon-only) has 4 tabs: Repository, Worktrees, Hooks, Settings. Main content fills the area right of the sidebar. Views: Repository (centered card with repo picker), Worktrees (master-detail grid: 280px worktree list | detail panel; "New Worktree" button in worktree toolbar), Hooks (inline hooks editor), Settings (language, terminal, shell, tray icon, tooling, logs, config). Create worktree uses a right-side slide-out panel. diff --git a/DESIGN_SYSTEM.md b/DESIGN_SYSTEM.md index de888ad..0a671c1 100644 --- a/DESIGN_SYSTEM.md +++ b/DESIGN_SYSTEM.md @@ -45,8 +45,8 @@ Standalone sizes outside the scale: `0.92rem` (sidebar branch name), `1.2rem` (d | Token | Stack | Usage | |---|---|---| -| (`:root`) | `"Avenir Next", "Segoe UI", sans-serif` | All UI text | -| `--font-mono` | `"SF Mono", "JetBrains Mono", monospace` | Code, paths, diffs | +| (`:root`) | `"Avenir Next", "Segoe UI", Roboto, "Noto Sans", Ubuntu, Cantarell, sans-serif` | All UI text | +| `--font-mono` | `"SF Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", Consolas, "Liberation Mono", monospace` | Code, paths, diffs | **No serif fonts.** All headings use the same sans-serif stack. @@ -114,6 +114,68 @@ Use teal **sparingly** — only for interactive states, active indicators, and f | `--border-default` | `rgba(28, 25, 23, 0.12)` | Card/panel borders, topbar, sidebar | | `--border-strong` | `rgba(28, 25, 23, 0.16)` | Input borders | +### Dark Mode Overrides + +Dark mode is activated via `[data-theme="dark"]`. All light-mode tokens above are overridden. Key differences: + +#### Ink (Dark) + +| Token | Value | +|---|---| +| `--ink` | `#dbd6d0` | +| `--ink-strong` | `rgba(219, 214, 208, 0.92)` | +| `--ink-secondary` | `rgba(219, 214, 208, 0.65)` | +| `--ink-tertiary` | `rgba(219, 214, 208, 0.48)` | +| `--ink-ghost` | `rgba(219, 214, 208, 0.3)` | +| `--ink-faint` | `rgba(219, 214, 208, 0.18)` | + +#### Accent (Dark) + +| Token | Value | +|---|---| +| `--teal` | `#52b0a4` | +| `--teal-bg` | `rgba(82, 176, 164, 0.1)` | +| `--teal-bg-strong` | `rgba(82, 176, 164, 0.18)` | +| `--teal-border` | `rgba(82, 176, 164, 0.25)` | +| `--teal-focus` | `rgba(82, 176, 164, 0.48)` | +| `--teal-muted` | `rgba(82, 176, 164, 0.58)` | +| `--teal-hover` | `rgba(82, 176, 164, 0.78)` | + +#### Surfaces (Dark) + +| Token | Value | +|---|---| +| Page background | `#151312` | +| `--surface-card` | `#1e1c19` | +| `--surface-topbar` | `#181614` | +| `--surface-sidebar` | `#1b1917` | +| `--surface-modal` | `#201e1b` | +| `--surface-input` | `#24221f` | +| `--surface-warm` | `#1b1917` | +| `--surface-raised` | `#24221f` | +| `--surface-hover` | `rgba(219, 214, 208, 0.07)` | +| `--surface-subtle` | `rgba(219, 214, 208, 0.04)` | +| `--surface-muted` | `rgba(219, 214, 208, 0.065)` | +| `--surface-strong` | `rgba(219, 214, 208, 0.095)` | +| `--surface-stronger` | `rgba(219, 214, 208, 0.13)` | + +#### Borders (Dark) + +| Token | Value | +|---|---| +| `--border-faint` | `rgba(219, 214, 208, 0.08)` | +| `--border-default` | `rgba(219, 214, 208, 0.12)` | +| `--border-strong` | `rgba(219, 214, 208, 0.17)` | + +#### Semantic Colors (Dark) + +| Token | Value | +|---|---| +| `--success` | `#68c49c` | +| `--danger` | `#e09080` | +| `--warning` | `#cca44a` | +| `--purple` | `#9c8acc` | + --- ## Shadows @@ -165,7 +227,7 @@ Always use ``, ` + + + + +
+
Cards & Panels
+
+
Card with Section Heading
+

Standard card container with warm white background, 12px radius, border only.

+
+
⚠️ Warning panel — uncommitted changes detected
+
✗ Error banner — failed to fetch remote branches
+
~/code/project/.worktrees/feat-dark-mode
+
+ + +
+
Launcher Icons
+
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ + +
+
+
+ + +
+
File Changes & Diff
+
+
+
Msrc/styles.css
+
Asrc/components/NewFeature.tsx
+
Dsrc/deprecated-module.ts
+
Rsrc/utils.ts → src/lib/utils.ts
+
?src/scratch.ts
+
+
@@ -42,7 +42,7 @@ export function App() {
const [theme, setTheme] = useState('light');
const [count, setCount] = useState(0);
- const color = '#1c1917';
+ const color = '#2e7a6e';
return <div>{color}</div>;
}
+
+
+ + +
+
Commit List
+
+
+
a64cd43fdocs: sync DESIGN_SYSTEM.md with late docs-agent changes@shawn2h ago
+
64f8c7c2fix: address code review feedback@shawn3h ago
+
7931085afix: prevent watcher restart loop when reloading same repo@shawn5h ago
+
d47bbb0eRevert "fix: replace stiff neutral grays with warm sand palette"@shawn6h ago
+
+
+
+ + +
+
Toast Notifications
+
+
✓ Worktree created successfully
+
✗ Failed to remove worktree
+
+
+ + +
+
Worktree List Items
+
+
+
+
main
+
clean2h ago
+
+
+
+
+
feat/dark-mode
+
3 filesPR #4215m ago
+
+
+
+
+
fix/watcher-loop
+
clean1d ago
+
+
+
+
+ + +
+
Action Logs
+
+
+
Commandgit worktree add ../feat-dark-mode feat/dark-mode
+
SuccessWorktree created at ../feat-dark-mode
+
Errorfatal: 'nonexistent' is not a valid branch name
+
InfoPreparing worktree (new branch 'feat/dark-mode')
+
+
+
+ + +
+
Typography
+
+
Heading — Avenir Next 700
+
Subheading — Avenir Next 600
+
Body text in secondary ink, used for descriptions and supporting copy.
+
Small text in tertiary ink for metadata, timestamps, hints.
+ Monospace: SF Mono — code, paths, SHA hashes +
+
+ + + + + + diff --git a/src/styles.css b/src/styles.css index 5243f29..ad49847 100644 --- a/src/styles.css +++ b/src/styles.css @@ -151,35 +151,35 @@ --teal-muted: rgba(82, 176, 164, 0.58); --teal-hover: rgba(82, 176, 164, 0.78); - --surface-card: #1c1a18; - --surface-topbar: #171614; - --surface-sidebar: #1a1816; - --surface-modal: #1e1c1a; - --surface-input: #201e1c; - --surface-warm: #1a1816; - --surface-raised: #201e1c; - --surface-hover: rgba(219, 214, 208, 0.055); - --surface-subtle: rgba(219, 214, 208, 0.03); - --surface-muted: rgba(219, 214, 208, 0.05); - --surface-strong: rgba(219, 214, 208, 0.07); - --surface-stronger: rgba(219, 214, 208, 0.1); - - --border-faint: rgba(219, 214, 208, 0.06); - --border-default: rgba(219, 214, 208, 0.1); - --border-strong: rgba(219, 214, 208, 0.14); + --surface-card: #1e1c19; + --surface-topbar: #181614; + --surface-sidebar: #1b1917; + --surface-modal: #201e1b; + --surface-input: #24221f; + --surface-warm: #1b1917; + --surface-raised: #24221f; + --surface-hover: rgba(219, 214, 208, 0.07); + --surface-subtle: rgba(219, 214, 208, 0.04); + --surface-muted: rgba(219, 214, 208, 0.065); + --surface-strong: rgba(219, 214, 208, 0.095); + --surface-stronger: rgba(219, 214, 208, 0.13); + + --border-faint: rgba(219, 214, 208, 0.08); + --border-default: rgba(219, 214, 208, 0.12); + --border-strong: rgba(219, 214, 208, 0.17); --shadow-card: none; - --shadow-modal: 0 8px 32px rgba(0, 0, 0, 0.4); - --shadow-menu: 0 4px 16px rgba(0, 0, 0, 0.35); - --shadow-panel: -2px 0 16px rgba(0, 0, 0, 0.3); + --shadow-modal: 0 8px 32px rgba(0, 0, 0, 0.5); + --shadow-menu: 0 4px 16px rgba(0, 0, 0, 0.45); + --shadow-panel: -2px 0 16px rgba(0, 0, 0, 0.4); - --backdrop: rgba(10, 9, 8, 0.6); + --backdrop: rgba(10, 9, 8, 0.65); --btn-primary-bg: #52b0a4; --btn-primary-text: #151312; - --btn-ghost-bg: rgba(219, 214, 208, 0.07); + --btn-ghost-bg: rgba(219, 214, 208, 0.09); --btn-ghost-text: var(--ink); - --btn-danger-bg: rgba(210, 100, 88, 0.15); + --btn-danger-bg: rgba(210, 100, 88, 0.16); --btn-danger-text: #e09080; --success: #68c49c;