feat(panel): dense tooltip pass — work surfaces (270 tips)

Task lifecycle actions get a 25-action tip map, every dialog field and
git panel control annotated; fixes two round-1 disabled-button tips
that could never fire and a double data-state stamp on tab-progress.
This commit is contained in:
Renn F
2026-07-15 18:04:00 +02:00
parent f9dbb30a4e
commit dcd2f84e69
56 changed files with 2554 additions and 1546 deletions
@@ -71,6 +71,9 @@ describe("CodeSnippet", () => {
// The active line's content is "b"; its row carries the highlight class.
const row = screen.getByText("b").parentElement;
expect(row?.className).toContain("bg-blue-500/15");
// The active line's number is now a real HelpTip trigger (Radix injects
// data-state via asChild), not a bare span.
expect(screen.getByText("2").getAttribute("data-state")).toBe("closed");
});
it("renders the fail-open hint on an error", () => {
+12 -7
View File
@@ -4,6 +4,7 @@ import { useGitFile } from "@/hooks/use-git";
import { Skeleton } from "@/components/ui/skeleton";
import { ScrollArea } from "@/components/ui/scroll-area";
import { cn } from "@/lib/utils";
import { HelpTip } from "@/components/ui/help-tip";
interface CodeSnippetProps {
branch: string | null | undefined;
@@ -64,9 +65,11 @@ export function CodeSnippet({
"bg-blue-500/15 ring-1 ring-inset ring-blue-500/30",
)}
>
<span className="select-none w-8 shrink-0 text-right text-muted-foreground/60">
{lineNo}
</span>
<HelpTip label={isActive ? "The line flagged in this finding" : ""}>
<span className="select-none w-8 shrink-0 text-right text-muted-foreground/60">
{lineNo}
</span>
</HelpTip>
<span className="whitespace-pre">{text || " "}</span>
</div>
);
@@ -74,10 +77,12 @@ export function CodeSnippet({
</pre>
</ScrollArea>
{data.truncated && (
<p className="border-t px-2 py-1 text-[10px] text-muted-foreground">
showing lines {data.start_line}{data.start_line + lines.length - 1}{" "}
of {data.total_lines}
</p>
<HelpTip label="Only a window around the flagged line is loaded, not the whole file — widen `context` to see more.">
<p className="border-t px-2 py-1 text-[10px] text-muted-foreground w-fit">
showing lines {data.start_line}
{data.start_line + lines.length - 1} of {data.total_lines}
</p>
</HelpTip>
)}
</div>
);
+181 -100
View File
@@ -150,28 +150,51 @@ export function GitActionsPanel({
open={showCommitDialog}
onOpenChange={handleCommitDialogOpenChange}
>
<DialogTrigger asChild>
<Button
className="w-full justify-start"
variant={hasStagedChanges ? "default" : "outline"}
disabled={!hasStagedChanges}
{/* HelpTip+span wraps the whole DialogTrigger, not the Button
itself — the Button stays DialogTrigger's asChild target so
Radix's Slot merge is undisturbed, and the outer span keeps the
tip hoverable even while disabled (disabled sets
pointer-events:none on the button, which would swallow hover on
anything nested inside it). */}
<HelpTip
label={
hasStagedChanges
? "Records the staged files as a local commit — doesn't push to the remote."
: "Nothing staged yet — stage files first before a commit can be made."
}
>
<span
className="block w-full"
tabIndex={!hasStagedChanges ? 0 : undefined}
>
<GitCommit className="h-4 w-4 mr-2" />
Commit Changes
{hasStagedChanges && (
<Badge variant="secondary" className="ml-auto">
{status?.staged_files.length} files
</Badge>
)}
</Button>
</DialogTrigger>
<DialogTrigger asChild>
<Button
className="w-full justify-start"
variant={hasStagedChanges ? "default" : "outline"}
disabled={!hasStagedChanges}
>
<GitCommit className="h-4 w-4 mr-2" />
Commit Changes
{hasStagedChanges && (
<Badge variant="secondary" className="ml-auto">
{status?.staged_files.length} files
</Badge>
)}
</Button>
</DialogTrigger>
</span>
</HelpTip>
<DialogContent>
<DialogHeader>
<DialogTitle>Commit Changes</DialogTitle>
</DialogHeader>
<div className="space-y-4 py-4">
<div className="space-y-2">
<label className="text-sm font-medium">Commit Message</label>
<HelpTip label="Becomes the commit's message — shows up in the log panel and the PR's commit history.">
<label className="text-sm font-medium w-fit">
Commit Message
</label>
</HelpTip>
<Textarea
placeholder="Describe your changes..."
value={commitMessage}
@@ -216,52 +239,82 @@ export function GitActionsPanel({
</Dialog>
{/* Push Action */}
<Button
className="w-full justify-start"
variant={canPush ? "default" : "outline"}
disabled={!canPush || isPushing}
onClick={() => onPush(false)}
<HelpTip
label={
canPush
? "git push -u origin <branch>. Uploads your local commits to GitHub — never force, safe to repeat."
: "Nothing to push — no local commits sit ahead of the remote branch yet."
}
>
{isPushing ? (
<RefreshCw className="h-4 w-4 mr-2 animate-spin" />
) : (
<Upload className="h-4 w-4 mr-2" />
)}
Push to Remote
{status?.ahead !== undefined && status.ahead > 0 && (
<HelpTip label="Commits not yet pushed to the remote repository">
<Badge variant="secondary" className="ml-auto">
<ArrowUp className="h-3 w-3 mr-1" />
{status.ahead}
</Badge>
</HelpTip>
)}
</Button>
<span
className="block w-full"
tabIndex={!canPush ? 0 : undefined}
>
<Button
className="w-full justify-start"
variant={canPush ? "default" : "outline"}
disabled={!canPush || isPushing}
onClick={() => onPush(false)}
>
{isPushing ? (
<RefreshCw className="h-4 w-4 mr-2 animate-spin" />
) : (
<Upload className="h-4 w-4 mr-2" />
)}
Push to Remote
{status?.ahead !== undefined && status.ahead > 0 && (
<HelpTip label="Commits not yet pushed to the remote repository">
<Badge variant="secondary" className="ml-auto">
<ArrowUp className="h-3 w-3 mr-1" />
{status.ahead}
</Badge>
</HelpTip>
)}
</Button>
</span>
</HelpTip>
{/* Create PR Action */}
<Dialog open={showPRDialog} onOpenChange={handlePRDialogOpenChange}>
<DialogTrigger asChild>
<Button
className="w-full justify-start"
variant="outline"
disabled={!canCreatePR}
<HelpTip
label={
canCreatePR
? "Opens GitHub's PR creation flow for this branch against main."
: "Already on main with nothing ahead of it — there's no branch content to open a PR for."
}
>
<span
className="block w-full"
tabIndex={!canCreatePR ? 0 : undefined}
>
<GitPullRequest className="h-4 w-4 mr-2" />
Create Pull Request
</Button>
</DialogTrigger>
<DialogTrigger asChild>
<Button
className="w-full justify-start"
variant="outline"
disabled={!canCreatePR}
>
<GitPullRequest className="h-4 w-4 mr-2" />
Create Pull Request
</Button>
</DialogTrigger>
</span>
</HelpTip>
<DialogContent className="max-w-lg">
<DialogHeader>
<DialogTitle>Create Pull Request</DialogTitle>
</DialogHeader>
<div className="space-y-4 py-4">
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<Badge variant="outline">{status?.current_branch}</Badge>
<span></span>
<Badge variant="outline">main</Badge>
</div>
<HelpTip label="Source branch on the left merges into the target branch on the right.">
<div className="flex items-center gap-2 text-sm text-muted-foreground w-fit">
<Badge variant="outline">{status?.current_branch}</Badge>
<span></span>
<Badge variant="outline">main</Badge>
</div>
</HelpTip>
<div className="space-y-2">
<label className="text-sm font-medium">Title</label>
<HelpTip label="Becomes the pull request's title on GitHub.">
<label className="text-sm font-medium w-fit">Title</label>
</HelpTip>
<Input
placeholder="PR title..."
value={prTitle}
@@ -269,7 +322,11 @@ export function GitActionsPanel({
/>
</div>
<div className="space-y-2">
<label className="text-sm font-medium">Description</label>
<HelpTip label="The PR's body on GitHub — markdown supported, shown to reviewers.">
<label className="text-sm font-medium w-fit">
Description
</label>
</HelpTip>
<Textarea
placeholder="Describe your changes..."
value={prBody}
@@ -300,23 +357,31 @@ export function GitActionsPanel({
open={showMergeDialog}
onOpenChange={handleMergeDialogOpenChange}
>
<DialogTrigger asChild>
<Button className="w-full justify-start" variant="outline">
{isMerging ? (
<RefreshCw className="h-4 w-4 mr-2 animate-spin" />
) : (
<GitMerge className="h-4 w-4 mr-2" />
)}
Merge PR
</Button>
</DialogTrigger>
<HelpTip label="Merges an open PR via GitHub's API — squash by default, falls back to merge/rebase if blocked by branch protection.">
<span className="block w-full">
<DialogTrigger asChild>
<Button className="w-full justify-start" variant="outline">
{isMerging ? (
<RefreshCw className="h-4 w-4 mr-2 animate-spin" />
) : (
<GitMerge className="h-4 w-4 mr-2" />
)}
Merge PR
</Button>
</DialogTrigger>
</span>
</HelpTip>
<DialogContent className="max-w-sm">
<DialogHeader>
<DialogTitle>Merge Pull Request</DialogTitle>
</DialogHeader>
<div className="space-y-4 py-4">
<div className="space-y-2">
<label className="text-sm font-medium">PR Number</label>
<HelpTip label="The GitHub PR number to merge, e.g. the 42 in .../pull/42.">
<label className="text-sm font-medium w-fit">
PR Number
</label>
</HelpTip>
<Input
type="number"
placeholder="e.g. 42"
@@ -351,51 +416,63 @@ export function GitActionsPanel({
</Dialog>
{/* Pull Action */}
<Button
className="w-full justify-start"
variant="outline"
disabled={isPulling}
onClick={onPull}
>
{isPulling ? (
<RefreshCw className="h-4 w-4 mr-2 animate-spin" />
) : (
<Download className="h-4 w-4 mr-2" />
)}
Pull from Remote
</Button>
{/* Fetch Action */}
<Button
className="w-full justify-start"
variant="outline"
disabled={isFetching}
onClick={onFetch}
>
{isFetching ? (
<RefreshCw className="h-4 w-4 mr-2 animate-spin" />
) : (
<RefreshCcw className="h-4 w-4 mr-2" />
)}
Fetch Remote
</Button>
{/* Rebase Action — destructive, requires confirmation */}
<AlertDialog>
<AlertDialogTrigger asChild>
<HelpTip label="Fetches origin, then fast-forwards your branch onto it. Refuses (no merge commit) if history has diverged.">
<span className="block w-full">
<Button
className="w-full justify-start"
variant="outline"
disabled={isRebasing}
disabled={isPulling}
onClick={onPull}
>
{isRebasing ? (
{isPulling ? (
<RefreshCw className="h-4 w-4 mr-2 animate-spin" />
) : (
<GitGraph className="h-4 w-4 mr-2" />
<Download className="h-4 w-4 mr-2" />
)}
Rebase onto Remote
Pull from Remote
</Button>
</AlertDialogTrigger>
</span>
</HelpTip>
{/* Fetch Action */}
<HelpTip label="Updates remote-tracking refs from origin only — never touches your working directory or local branch.">
<span className="block w-full">
<Button
className="w-full justify-start"
variant="outline"
disabled={isFetching}
onClick={onFetch}
>
{isFetching ? (
<RefreshCw className="h-4 w-4 mr-2 animate-spin" />
) : (
<RefreshCcw className="h-4 w-4 mr-2" />
)}
Fetch Remote
</Button>
</span>
</HelpTip>
{/* Rebase Action — destructive, requires confirmation */}
<AlertDialog>
<HelpTip label="Rewrites this branch's commit history on top of another branch. Requires a force-push afterward — use with care.">
<span className="block w-full">
<AlertDialogTrigger asChild>
<Button
className="w-full justify-start"
variant="outline"
disabled={isRebasing}
>
{isRebasing ? (
<RefreshCw className="h-4 w-4 mr-2 animate-spin" />
) : (
<GitGraph className="h-4 w-4 mr-2" />
)}
Rebase onto Remote
</Button>
</AlertDialogTrigger>
</span>
</HelpTip>
<AlertDialogContent className="border-destructive bg-destructive/5">
<AlertDialogHeader>
<AlertDialogTitle>Rebase onto target branch?</AlertDialogTitle>
@@ -407,7 +484,11 @@ export function GitActionsPanel({
</AlertDialogDescription>
</AlertDialogHeader>
<div className="px-6 py-2 space-y-2">
<label className="text-sm font-medium">Target branch</label>
<HelpTip label="Branch/ref to replay commits onto, e.g. origin/main. On conflict, rebase auto-aborts — your tree stays untouched.">
<label className="text-sm font-medium w-fit">
Target branch
</label>
</HelpTip>
<Input
placeholder="Remote ref (e.g. origin/HEAD)"
value={rebaseTargetBranch}
+85 -50
View File
@@ -92,19 +92,27 @@ export function GitBranchPanel({
Branches
</span>
<Dialog open={showCreateDialog} onOpenChange={setShowCreateDialog}>
<DialogTrigger asChild>
<Button size="sm" variant="outline">
<Plus className="h-3 w-3 mr-1" />
New
</Button>
</DialogTrigger>
<HelpTip label="Creates a new branch named {type}/{team}/{task-id}, branched from the task's parent branch (or the project default).">
<span className="inline-block">
<DialogTrigger asChild>
<Button size="sm" variant="outline">
<Plus className="h-3 w-3 mr-1" />
New
</Button>
</DialogTrigger>
</span>
</HelpTip>
<DialogContent>
<DialogHeader>
<DialogTitle>Create Task Branch</DialogTitle>
</DialogHeader>
<div className="space-y-4 py-4">
<div className="space-y-2">
<label className="text-sm font-medium">Branch Type</label>
<HelpTip label="Sets the branch-name prefix (feature/bug/chore/docs/hotfix) — doesn't otherwise change behavior.">
<label className="text-sm font-medium w-fit">
Branch Type
</label>
</HelpTip>
<Select
value={newBranchType}
onValueChange={(v) => setNewBranchType(v as BranchType)}
@@ -122,7 +130,11 @@ export function GitBranchPanel({
</Select>
</div>
<div className="space-y-2">
<label className="text-sm font-medium">Task ID</label>
<HelpTip label="Identifies the task this branch is for — gets embedded in the branch name (shortened to 8 chars).">
<label className="text-sm font-medium w-fit">
Task ID
</label>
</HelpTip>
<Input
placeholder="Enter task ID..."
value={taskId}
@@ -156,41 +168,56 @@ export function GitBranchPanel({
<div className="space-y-3">
{/* Local Branches */}
<div>
<h4 className="text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-1">
Local ({localBranches.length})
</h4>
<HelpTip label="Branches that exist in your local clone's .git — checking one out is instant, no fetch needed.">
<h4 className="text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-1 w-fit">
Local ({localBranches.length})
</h4>
</HelpTip>
<div className="space-y-0.5">
{localBranches.map((branch) => (
<Button
<HelpTip
key={branch.name}
onClick={() =>
!branch.is_current && onCheckout(branch.name)
}
disabled={branch.is_current || isCheckingOut}
variant="ghost"
className={
"w-full h-auto justify-between px-2 py-1.5 text-sm font-normal whitespace-normal " +
(branch.is_current
? "bg-primary/10 text-primary hover:bg-primary/10 hover:text-primary"
: "hover:bg-muted")
label={
branch.is_current
? "This is the branch you're already on."
: "Switches your workspace to this branch (git checkout). Non-conflicting uncommitted changes carry over."
}
>
<div className="flex items-center gap-2 min-w-0">
{branch.is_current && (
<Check className="h-3 w-3 text-primary shrink-0" />
)}
<span className="truncate font-mono text-xs">
{branch.name}
</span>
</div>
{branch.last_commit && (
<HelpTip label="Short commit hash on this branch">
<span className="text-xs text-muted-foreground font-mono shrink-0">
{branch.last_commit.slice(0, 7)}
</span>
</HelpTip>
)}
</Button>
<span
className="block"
tabIndex={branch.is_current ? 0 : undefined}
>
<Button
onClick={() =>
!branch.is_current && onCheckout(branch.name)
}
disabled={branch.is_current || isCheckingOut}
variant="ghost"
className={
"w-full h-auto justify-between px-2 py-1.5 text-sm font-normal whitespace-normal " +
(branch.is_current
? "bg-primary/10 text-primary hover:bg-primary/10 hover:text-primary"
: "hover:bg-muted")
}
>
<div className="flex items-center gap-2 min-w-0">
{branch.is_current && (
<Check className="h-3 w-3 text-primary shrink-0" />
)}
<span className="truncate font-mono text-xs">
{branch.name}
</span>
</div>
{branch.last_commit && (
<HelpTip label="Short commit hash on this branch">
<span className="text-xs text-muted-foreground font-mono shrink-0">
{branch.last_commit.slice(0, 7)}
</span>
</HelpTip>
)}
</Button>
</span>
</HelpTip>
))}
</div>
</div>
@@ -198,23 +225,31 @@ export function GitBranchPanel({
{/* Remote Branches */}
{remoteBranches.length > 0 && (
<div>
<h4 className="text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-1 flex items-center gap-1">
<Cloud className="h-3 w-3" />
Remote ({remoteBranches.length})
</h4>
<HelpTip label="Branches on origin without a local counterpart yet — checking one out creates a local tracking branch.">
<h4 className="text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-1 flex items-center gap-1 w-fit">
<Cloud className="h-3 w-3" />
Remote ({remoteBranches.length})
</h4>
</HelpTip>
<div className="space-y-0.5">
{remoteBranches.map((branch) => (
<Button
<HelpTip
key={branch.name}
onClick={() => onCheckout(branch.name)}
disabled={isCheckingOut}
variant="ghost"
className="w-full h-auto justify-start px-2 py-1.5 text-sm font-normal whitespace-normal hover:bg-muted"
label="Creates a local branch tracking this remote ref and switches to it."
>
<span className="truncate font-mono text-xs text-muted-foreground">
{branch.name}
<span className="block">
<Button
onClick={() => onCheckout(branch.name)}
disabled={isCheckingOut}
variant="ghost"
className="w-full h-auto justify-start px-2 py-1.5 text-sm font-normal whitespace-normal hover:bg-muted"
>
<span className="truncate font-mono text-xs text-muted-foreground">
{branch.name}
</span>
</Button>
</span>
</Button>
</HelpTip>
))}
</div>
</div>
+24 -19
View File
@@ -18,6 +18,7 @@ import { GitDiffViewer } from "./git-diff-viewer";
import { GitActionsPanel } from "./git-actions-panel";
import { GitBranch, FolderGit2 } from "lucide-react";
import { useGitBrowser } from "@/hooks/use-git-browser";
import { HelpTip } from "@/components/ui/help-tip";
function GitBrowserContent() {
const {
@@ -80,25 +81,29 @@ function GitBrowserContent() {
</div>
<div className="flex items-center gap-2">
{/* Project Selector */}
<Select value={projectSlug} onValueChange={handleProjectChange}>
<SelectTrigger className="w-full sm:w-64">
<FolderGit2 className="h-4 w-4 mr-2" />
<SelectValue placeholder="Select a project..." />
</SelectTrigger>
<SelectContent>
{loadingProjects ? (
<div className="p-2">
<Skeleton className="h-8 w-full" />
</div>
) : (
projects?.map((p) => (
<SelectItem key={p.id} value={p.slug}>
{p.name}
</SelectItem>
))
)}
</SelectContent>
</Select>
<HelpTip label="Switches every panel below (status, branches, log, diff) to this project's clone on disk.">
<span className="w-full sm:w-64">
<Select value={projectSlug} onValueChange={handleProjectChange}>
<SelectTrigger className="w-full sm:w-64">
<FolderGit2 className="h-4 w-4 mr-2" />
<SelectValue placeholder="Select a project..." />
</SelectTrigger>
<SelectContent>
{loadingProjects ? (
<div className="p-2">
<Skeleton className="h-8 w-full" />
</div>
) : (
projects?.map((p) => (
<SelectItem key={p.id} value={p.slug}>
{p.name}
</SelectItem>
))
)}
</SelectContent>
</Select>
</span>
</HelpTip>
</div>
</div>
+23 -14
View File
@@ -104,21 +104,30 @@ export function GitDiffViewer({
<Card>
<CardHeader className="pb-2">
<div className="flex items-center justify-between gap-2">
<CardTitle className="text-sm flex items-center gap-2">
<FileCode className="h-4 w-4" />
Changes
</CardTitle>
<Button
variant={wrap ? "secondary" : "ghost"}
size="sm"
className="h-7 px-2 text-xs"
aria-pressed={wrap}
onClick={() => setWrap((w) => !w)}
title="Toggle line wrap"
<HelpTip label="Green = added lines, red = removed, blue = hunk header (@@ ... @@ shows the surrounding line range).">
<CardTitle className="text-sm flex items-center gap-2 w-fit">
<FileCode className="h-4 w-4" />
Changes
</CardTitle>
</HelpTip>
<HelpTip
label={
wrap
? "Long lines wrap to fit the panel — click to scroll horizontally instead."
: "Long lines overflow with horizontal scroll — click to wrap them instead."
}
>
<WrapText className="h-3.5 w-3.5 mr-1" />
Wrap
</Button>
<Button
variant={wrap ? "secondary" : "ghost"}
size="sm"
className="h-7 px-2 text-xs"
aria-pressed={wrap}
onClick={() => setWrap((w) => !w)}
>
<WrapText className="h-3.5 w-3.5 mr-1" />
Wrap
</Button>
</HelpTip>
</div>
</CardHeader>
<CardContent className="p-0">
+18 -10
View File
@@ -62,17 +62,22 @@ export function GitLogPanel({
<CardTitle className="text-sm flex items-center gap-2">
<GitCommit className="h-4 w-4" />
Commit History
<Badge variant="secondary" className="ml-auto text-xs">
{log.branch}
</Badge>
<HelpTip label="Commits reachable from this branch, newest first.">
<Badge variant="secondary" className="ml-auto text-xs">
{log.branch}
</Badge>
</HelpTip>
</CardTitle>
</CardHeader>
<CardContent className="p-0">
<ScrollArea className="h-80">
<div className="p-4 space-y-0">
{log.commits.map((commit, index) => (
<Button
<HelpTip
key={commit.hash}
label={onSelectCommit ? "Select this commit" : ""}
>
<Button
onClick={() => onSelectCommit?.(commit)}
variant="ghost"
className={cn(
@@ -120,16 +125,19 @@ export function GitLogPanel({
<User className="h-3 w-3" />
{commit.author}
</span>
<span className="flex items-center gap-1">
<Calendar className="h-3 w-3" />
{formatDistanceToNow(new Date(commit.date), {
addSuffix: true,
})}
</span>
<HelpTip label={new Date(commit.date).toLocaleString()}>
<span className="flex items-center gap-1 w-fit">
<Calendar className="h-3 w-3" />
{formatDistanceToNow(new Date(commit.date), {
addSuffix: true,
})}
</span>
</HelpTip>
</div>
</div>
</div>
</Button>
</HelpTip>
))}
</div>
</ScrollArea>
+12 -8
View File
@@ -70,20 +70,24 @@ export function GitStatusPanel({ status, isLoading }: GitStatusPanelProps) {
Repository Status
</span>
{!hasChanges && (
<Badge variant="outline" className="text-green-600">
<CheckCircle className="h-3 w-3 mr-1" />
Clean
</Badge>
<HelpTip label="No staged, modified, or untracked files — the working tree matches HEAD.">
<Badge variant="outline" className="text-green-600">
<CheckCircle className="h-3 w-3 mr-1" />
Clean
</Badge>
</HelpTip>
)}
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
{/* Branch Info */}
<div className="flex items-center gap-4 text-sm">
<div className="flex items-center gap-2">
<GitBranch className="h-4 w-4 text-muted-foreground" />
<span className="font-medium">{status.current_branch}</span>
</div>
<HelpTip label="The branch currently checked out in this project's workspace.">
<div className="flex items-center gap-2 w-fit">
<GitBranch className="h-4 w-4 text-muted-foreground" />
<span className="font-medium">{status.current_branch}</span>
</div>
</HelpTip>
{(status.ahead > 0 || status.behind > 0) && (
<div className="flex items-center gap-2">
{status.ahead > 0 && (