Skip to content

Commit 79e9978

Browse files
committed
style(plugin-git): cohesive violet theme and devtool polish
Give the dashboard an identity tied to the commit graph: the neutral grayscale primary/ring tokens become a violet accent (light and dark), surfacing in the logo chip, focus rings, selected commit, and patch hunk headers. Add a sticky app-shell top bar, slim theme-aware scrollbars for native overflow regions, and a selection color. Apply data-presentation rules across the panels: tabular-nums for every technical value (counts, ahead/behind, SHAs, +/- stats, relative times) so they stop jittering, and title attributes on truncated subjects, refs, paths, and branch names so the full value is recoverable on hover. Also drops an em dash from a status string.
1 parent 87c96b4 commit 79e9978

7 files changed

Lines changed: 74 additions & 46 deletions

File tree

‎plugins/git/src/client/app/globals.css‎

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@
1414
--card-foreground: oklch(0.145 0 0);
1515
--popover: oklch(1 0 0);
1616
--popover-foreground: oklch(0.145 0 0);
17-
--primary: oklch(0.205 0 0);
17+
--primary: oklch(0.54 0.2 283);
1818
--primary-foreground: oklch(0.985 0 0);
1919
--secondary: oklch(0.97 0 0);
2020
--secondary-foreground: oklch(0.205 0 0);
2121
--muted: oklch(0.97 0 0);
2222
--muted-foreground: oklch(0.556 0 0);
23-
--accent: oklch(0.97 0 0);
23+
--accent: oklch(0.96 0.012 283);
2424
--accent-foreground: oklch(0.205 0 0);
2525
--destructive: oklch(0.577 0.245 27.325);
2626
--border: oklch(0.922 0 0);
2727
--input: oklch(0.922 0 0);
28-
--ring: oklch(0.708 0 0);
28+
--ring: oklch(0.54 0.2 283);
2929
--success: oklch(0.6 0.13 160);
3030
--warning: oklch(0.75 0.15 80);
3131
}
@@ -37,18 +37,18 @@
3737
--card-foreground: oklch(0.985 0 0);
3838
--popover: oklch(0.205 0 0);
3939
--popover-foreground: oklch(0.985 0 0);
40-
--primary: oklch(0.922 0 0);
41-
--primary-foreground: oklch(0.205 0 0);
40+
--primary: oklch(0.72 0.16 285);
41+
--primary-foreground: oklch(0.18 0.03 285);
4242
--secondary: oklch(0.269 0 0);
4343
--secondary-foreground: oklch(0.985 0 0);
4444
--muted: oklch(0.269 0 0);
4545
--muted-foreground: oklch(0.708 0 0);
46-
--accent: oklch(0.269 0 0);
46+
--accent: oklch(0.27 0.018 285);
4747
--accent-foreground: oklch(0.985 0 0);
4848
--destructive: oklch(0.704 0.191 22.216);
4949
--border: oklch(1 0 0 / 10%);
5050
--input: oklch(1 0 0 / 15%);
51-
--ring: oklch(0.556 0 0);
51+
--ring: oklch(0.62 0.17 285);
5252
--success: oklch(0.7 0.14 160);
5353
--warning: oklch(0.8 0.15 80);
5454
}
@@ -93,4 +93,29 @@
9393
font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
9494
-webkit-font-smoothing: antialiased;
9595
}
96+
97+
::selection {
98+
background-color: color-mix(in oklab, var(--color-primary) 30%, transparent);
99+
}
100+
}
101+
102+
/* Slim, theme-aware scrollbars for native overflow regions (the commit log,
103+
commit-details patch, etc.) so dense panels read like a real devtool. */
104+
@utility scrollbar-slim {
105+
scrollbar-width: thin;
106+
scrollbar-color: color-mix(in oklab, var(--color-foreground) 22%, transparent) transparent;
107+
108+
&::-webkit-scrollbar {
109+
width: 8px;
110+
height: 8px;
111+
}
112+
113+
&::-webkit-scrollbar-thumb {
114+
border-radius: 9999px;
115+
background-color: color-mix(in oklab, var(--color-foreground) 22%, transparent);
116+
}
117+
118+
&::-webkit-scrollbar-thumb:hover {
119+
background-color: color-mix(in oklab, var(--color-foreground) 36%, transparent);
120+
}
96121
}

‎plugins/git/src/client/components/dashboard.tsx‎

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ function BranchRow({
7676
>
7777
<div className="flex items-center gap-2">
7878
<GitBranch className={cn('size-3.5 shrink-0', branch.current ? 'text-primary' : 'text-muted-foreground')} />
79-
<span className="truncate font-mono text-xs">{branch.name}</span>
79+
<span className="truncate font-mono text-xs" title={branch.name}>{branch.name}</span>
8080
{branch.current && <Badge variant="success" className="px-1 py-0 text-[10px]">current</Badge>}
8181
</div>
8282
{(branch.ahead > 0 || branch.behind > 0) && (
83-
<p className="text-muted-foreground mt-0.5 text-[11px]">
83+
<p className="text-muted-foreground mt-0.5 text-[11px] tabular-nums">
8484
{branch.ahead > 0 && `ahead ${branch.ahead}`}
8585
{branch.ahead > 0 && branch.behind > 0 && ' · '}
8686
{branch.behind > 0 && `behind ${branch.behind}`}
@@ -126,14 +126,16 @@ function DashboardBody() {
126126
const showCommitDetails = pane === 'commits' && selectedCommit !== null
127127

128128
return (
129-
<main className="flex min-h-svh w-full flex-col gap-4 px-4 py-5 md:px-6">
130-
<header className="flex items-center justify-between gap-3">
131-
<div className="flex items-center gap-2">
132-
<GitGraph className="text-primary size-6" />
129+
<main className="flex min-h-svh w-full flex-col">
130+
<header className="bg-background/80 supports-[backdrop-filter]:bg-background/60 sticky top-0 z-20 flex items-center justify-between gap-3 border-b px-4 py-3 backdrop-blur md:px-6">
131+
<div className="flex items-center gap-2.5">
132+
<div className="bg-primary/10 text-primary flex size-8 items-center justify-center rounded-lg">
133+
<GitGraph className="size-5" />
134+
</div>
133135
<div>
134-
<h1 className="text-base leading-none font-semibold">Git Dashboard</h1>
135-
<p className="text-muted-foreground text-[11px]">
136-
devframe + Next.js · type-safe RPC into the host repository
136+
<h1 className="text-sm leading-none font-semibold">Git Dashboard</h1>
137+
<p className="text-muted-foreground mt-1 text-[11px] leading-none">
138+
devframe · type-safe RPC into the host repository
137139
</p>
138140
</div>
139141
</div>
@@ -143,7 +145,7 @@ function DashboardBody() {
143145
</div>
144146
</header>
145147

146-
<div className="grid min-h-0 flex-1 gap-4 xl:grid-cols-[250px_minmax(0,1fr)_320px]">
148+
<div className="grid min-h-0 flex-1 gap-4 px-4 py-4 md:px-6 xl:grid-cols-[250px_minmax(0,1fr)_320px]">
147149
<aside className="space-y-4">
148150
<Card>
149151
<CardHeader className="pb-2">

‎plugins/git/src/client/components/views/branches-panel-view.tsx‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function BranchRow({ branch }: { branch: Branch }) {
1919
<GitBranch className={`size-4 shrink-0 ${branch.current ? 'text-primary' : 'text-muted-foreground'}`} />
2020
<div className="min-w-0 flex-1">
2121
<div className="flex items-center gap-2">
22-
<span className={`truncate font-mono text-xs ${branch.current ? 'font-semibold' : ''}`}>
22+
<span className={`truncate font-mono text-xs ${branch.current ? 'font-semibold' : ''}`} title={branch.name}>
2323
{branch.name}
2424
</span>
2525
{branch.current && (
@@ -30,22 +30,22 @@ function BranchRow({ branch }: { branch: Branch }) {
3030
)}
3131
{branch.gone && <Badge variant="destructive" className="px-1.5 py-0 text-[10px]">upstream gone</Badge>}
3232
</div>
33-
{branch.subject && <p className="text-muted-foreground truncate text-xs">{branch.subject}</p>}
33+
{branch.subject && <p className="text-muted-foreground truncate text-xs" title={branch.subject}>{branch.subject}</p>}
3434
</div>
3535
<div className="flex shrink-0 items-center gap-2">
3636
{branch.ahead > 0 && (
37-
<span className="text-success inline-flex items-center text-xs">
37+
<span className="text-success inline-flex items-center text-xs tabular-nums">
3838
<ArrowUp className="size-3" />
3939
{branch.ahead}
4040
</span>
4141
)}
4242
{branch.behind > 0 && (
43-
<span className="text-warning inline-flex items-center text-xs">
43+
<span className="text-warning inline-flex items-center text-xs tabular-nums">
4444
<ArrowDown className="size-3" />
4545
{branch.behind}
4646
</span>
4747
)}
48-
<code className="text-muted-foreground text-xs">{branch.sha}</code>
48+
<code className="text-muted-foreground text-xs tabular-nums">{branch.sha}</code>
4949
</div>
5050
</li>
5151
)
@@ -55,7 +55,7 @@ export function BranchesPanelView({ data, loading, onRefresh }: BranchesPanelVie
5555
return (
5656
<div className="space-y-3">
5757
<div className="flex items-center justify-between">
58-
<span className="text-muted-foreground text-xs">
58+
<span className="text-muted-foreground text-xs tabular-nums">
5959
{data?.isRepo ? `${data.branches.length} branches` : ' '}
6060
</span>
6161
<Button variant="ghost" size="icon" className="size-7" onClick={onRefresh} disabled={loading} aria-label="Refresh branches">

‎plugins/git/src/client/components/views/commit-details-view.tsx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export function CommitDetailsView({ data, loading, error, onClose }: CommitDetai
7676

7777
<dl className="grid grid-cols-[auto_minmax(0,1fr)] gap-x-3 gap-y-1 text-xs">
7878
<dt className="text-muted-foreground">Commit</dt>
79-
<dd className="truncate font-mono" title={data.hash}>{data.shortHash}</dd>
79+
<dd className="truncate font-mono tabular-nums" title={data.hash}>{data.shortHash}</dd>
8080

8181
<dt className="text-muted-foreground">Author</dt>
8282
<dd className="truncate">
@@ -99,15 +99,15 @@ export function CommitDetailsView({ data, loading, error, onClose }: CommitDetai
9999
<dt className="text-muted-foreground">
100100
{data.parents.length > 1 ? 'Parents' : 'Parent'}
101101
</dt>
102-
<dd className="truncate font-mono">
102+
<dd className="truncate font-mono tabular-nums">
103103
{data.parents.map(p => p.slice(0, 7)).join(', ')}
104104
</dd>
105105
</>
106106
)}
107107
</dl>
108108

109109
{data.body && (
110-
<pre className="bg-muted/40 max-h-48 overflow-auto rounded-md p-3 font-mono text-xs whitespace-pre-wrap">
110+
<pre className="bg-muted/40 scrollbar-slim max-h-48 overflow-auto rounded-md p-3 font-mono text-xs whitespace-pre-wrap">
111111
{data.body}
112112
</pre>
113113
)}
@@ -117,7 +117,7 @@ export function CommitDetailsView({ data, loading, error, onClose }: CommitDetai
117117
<span className="text-muted-foreground text-xs font-medium tracking-wide uppercase">
118118
{`${data.files.length} ${data.files.length === 1 ? 'file' : 'files'} changed`}
119119
</span>
120-
<span className="text-xs">
120+
<span className="text-xs tabular-nums">
121121
<span className="text-success">{`+${data.totalAdditions}`}</span>
122122
{' '}
123123
<span className="text-destructive">{`−${data.totalDeletions}`}</span>
@@ -130,7 +130,7 @@ export function CommitDetailsView({ data, loading, error, onClose }: CommitDetai
130130
{file.binary
131131
? <Badge variant="secondary" className="px-1.5 py-0 text-[10px]">bin</Badge>
132132
: (
133-
<span className="shrink-0">
133+
<span className="shrink-0 tabular-nums">
134134
<span className="text-success">{`+${file.additions}`}</span>
135135
{' '}
136136
<span className="text-destructive">{`−${file.deletions}`}</span>

‎plugins/git/src/client/components/views/diff-panel-view.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export function DiffPanelView(props: DiffPanelViewProps) {
7373
</div>
7474
<div className="flex items-center gap-2">
7575
{data?.isRepo && (
76-
<span className="text-xs">
76+
<span className="text-xs tabular-nums">
7777
<span className="text-success">
7878
+
7979
{data.totalAdditions}
@@ -124,11 +124,11 @@ export function DiffPanelView(props: DiffPanelViewProps) {
124124
selected === file.path ? 'bg-accent' : 'hover:bg-accent/50',
125125
)}
126126
>
127-
<span className="flex-1 truncate">{file.path}</span>
127+
<span className="flex-1 truncate" title={file.path}>{file.path}</span>
128128
{file.binary
129129
? <Badge variant="secondary" className="px-1.5 py-0 text-[10px]">bin</Badge>
130130
: (
131-
<span className="shrink-0">
131+
<span className="shrink-0 tabular-nums">
132132
<span className="text-success">
133133
+
134134
{file.additions}

‎plugins/git/src/client/components/views/log-panel-view.tsx‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ function RefLabel({ refToken, color }: { refToken: GitRef, color: string }) {
132132
style={{ color, borderColor: withAlpha(color, 0.5), backgroundColor: withAlpha(color, 0.12) }}
133133
>
134134
<Tag className="size-3 shrink-0" />
135-
<span className="truncate">{refToken.name}</span>
135+
<span className="truncate" title={refToken.name}>{refToken.name}</span>
136136
</span>
137137
)
138138
}
@@ -160,7 +160,7 @@ function RefLabel({ refToken, color }: { refToken: GitRef, color: string }) {
160160
{current
161161
? <Check className="size-3 shrink-0" />
162162
: <GitBranch className="size-3 shrink-0 opacity-70" />}
163-
<span className="truncate">{name}</span>
163+
<span className="truncate" title={name}>{name}</span>
164164
</span>
165165
)
166166
}
@@ -211,12 +211,12 @@ function CommitRow({ commit, row, gutter, currentBranch, isHead, topStub, select
211211
</div>
212212

213213
<div className="relative z-10 flex min-w-0 flex-1 flex-col justify-center gap-0.5 pl-4">
214-
<span className="truncate text-sm font-medium">{commit.subject}</span>
214+
<span className="truncate text-sm font-medium" title={commit.subject}>{commit.subject}</span>
215215
<div className="text-muted-foreground flex items-center gap-2 text-xs">
216-
<code className="shrink-0">{commit.shortHash}</code>
216+
<code className="shrink-0 tabular-nums">{commit.shortHash}</code>
217217
<span className="truncate">{commit.author}</span>
218218
<span aria-hidden>·</span>
219-
<span className="shrink-0" title={new Date(commit.date).toLocaleString()}>{relativeTime(commit.date)}</span>
219+
<span className="shrink-0 tabular-nums" title={new Date(commit.date).toLocaleString()}>{relativeTime(commit.date)}</span>
220220
</div>
221221
</div>
222222
</button>
@@ -328,7 +328,7 @@ export function LogPanelView(props: LogPanelViewProps) {
328328
return (
329329
<div className="flex h-full min-h-0 flex-col gap-3">
330330
<div className="flex items-center justify-between">
331-
<span className="text-muted-foreground text-xs">
331+
<span className="text-muted-foreground text-xs tabular-nums">
332332
{isRepo
333333
? `${commits.length}${hasMore ? '+' : ''} commits${selectedRef ? ` · ${selectedRef}` : ''}`
334334
: ' '}
@@ -357,7 +357,7 @@ export function LogPanelView(props: LogPanelViewProps) {
357357
)}
358358

359359
{isRepo === true && commits.length > 0 && (
360-
<div ref={scrollRef} className="min-h-0 flex-1 overflow-y-auto pr-2">
360+
<div ref={scrollRef} className="scrollbar-slim min-h-0 flex-1 overflow-y-auto pr-2">
361361
<ul>
362362
{showWip && headRow && (
363363
<WipRow col={headRow.col} color={headRow.color} gutter={gutter} changes={workingChanges ?? 0} />

‎plugins/git/src/client/components/views/status-panel-view.tsx‎

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,14 @@ function statusColor(code: FileStatusCode): string {
4545
}
4646

4747
function FileRow({ entry, action }: { entry: StatusFileEntry, action?: ReactNode }) {
48+
const label = entry.from ? `${entry.from} → ${entry.path}` : entry.path
4849
return (
49-
<li className="flex items-center gap-2 py-0.5 font-mono text-xs">
50+
<li className="hover:bg-accent/40 flex items-center gap-2 rounded py-0.5 pl-1 font-mono text-xs transition-colors">
5051
<span className={`w-3 shrink-0 text-center font-semibold ${statusColor(entry.status)}`}>
5152
{STATUS_LABEL[entry.status]}
5253
</span>
53-
<span className="flex-1 truncate">
54-
{entry.from ? `${entry.from} → ${entry.path}` : entry.path}
54+
<span className="flex-1 truncate" title={label}>
55+
{label}
5556
</span>
5657
{action}
5758
</li>
@@ -76,7 +77,7 @@ function Section({
7677
<div className="flex items-center justify-between">
7778
<div className="text-muted-foreground flex items-center gap-2 text-xs font-medium tracking-wide uppercase">
7879
{title}
79-
<Badge variant="secondary" className="px-1.5 py-0 text-[10px]">{count}</Badge>
80+
<Badge variant="secondary" className="px-1.5 py-0 text-[10px] tabular-nums">{count}</Badge>
8081
</div>
8182
{headerAction}
8283
</div>
@@ -114,13 +115,13 @@ export function StatusPanelView(props: StatusPanelViewProps) {
114115
<Badge variant="secondary" className="gap-1 font-mono">
115116
{data.upstream}
116117
{data.ahead > 0 && (
117-
<span className="text-success inline-flex items-center">
118+
<span className="text-success inline-flex items-center tabular-nums">
118119
<ArrowUp className="size-3" />
119120
{data.ahead}
120121
</span>
121122
)}
122123
{data.behind > 0 && (
123-
<span className="text-warning inline-flex items-center">
124+
<span className="text-warning inline-flex items-center tabular-nums">
124125
<ArrowDown className="size-3" />
125126
{data.behind}
126127
</span>
@@ -149,7 +150,7 @@ export function StatusPanelView(props: StatusPanelViewProps) {
149150
)}
150151

151152
{data?.isRepo && data.clean && (
152-
<p className="text-muted-foreground text-sm">Nothing to commit — the working tree is clean.</p>
153+
<p className="text-muted-foreground text-sm">Nothing to commit. The working tree is clean.</p>
153154
)}
154155

155156
{data?.isRepo && !data.clean && (
@@ -217,7 +218,7 @@ export function StatusPanelView(props: StatusPanelViewProps) {
217218
aria-label="Commit message"
218219
/>
219220
{note && <p className="text-destructive text-xs">{note}</p>}
220-
<Button size="sm" onClick={onCommit} disabled={busy || message.trim().length === 0}>
221+
<Button size="sm" className="tabular-nums" onClick={onCommit} disabled={busy || message.trim().length === 0}>
221222
{`Commit ${data.staged.length} file${data.staged.length === 1 ? '' : 's'}`}
222223
</Button>
223224
</div>

0 commit comments

Comments
 (0)