From 7a67fa2b5fe3fa05ee8533c2ebc25103faedb6ff Mon Sep 17 00:00:00 2001 From: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Date: Sun, 7 Jun 2026 16:41:57 -0700 Subject: [PATCH] Lighten worktree sidebar and scope its color tokens under `--worktree-si - Dark mode panel lifted from `#212121` to `#2a2a2a` so it reads clearly above the `#0a0a0a` canvas. - Added `--worktree-sidebar-accent`, `--worktree-sidebar-border`, and `--worktree-sidebar-ring` tokens in both color schemes. - Migrated all sidebar components from shared `sidebar-*` tokens to the scoped `worktree-sidebar-*` tokens, preventing bleed when the two layers diverge. --- src/renderer/src/assets/main.css | 16 +++++++- .../ImportedWorktreesVisibilityLine.tsx | 18 ++++----- .../sidebar/SetupGuideSidebarEntry.tsx | 4 +- .../sidebar/SetupScriptPromptCard.tsx | 2 +- .../sidebar/SetupScriptPromptCardViews.tsx | 4 +- .../src/components/sidebar/SidebarNav.tsx | 40 ++++++++++++------- .../src/components/sidebar/SidebarToolbar.tsx | 2 +- .../WorkspaceKanbanAreaSelectionOverlay.tsx | 2 +- .../sidebar/WorkspaceKanbanCard.tsx | 2 +- .../sidebar/WorkspaceKanbanDrawer.tsx | 2 +- .../sidebar/WorkspaceKanbanDrawerHeader.tsx | 4 +- .../sidebar/WorkspaceKanbanPinDropTarget.tsx | 6 +-- .../sidebar/WorkspaceKanbanStatusLane.tsx | 12 +++--- .../src/components/sidebar/WorktreeCard.tsx | 14 ++++--- .../components/sidebar/WorktreeCardPorts.tsx | 2 +- .../src/components/sidebar/WorktreeList.tsx | 18 +++++---- .../sidebar/WorktreeTitleInlineRename.tsx | 2 +- src/renderer/src/components/sidebar/index.tsx | 6 ++- .../sidebar/worktree-card-compact-agents.tsx | 16 ++++---- 19 files changed, 102 insertions(+), 70 deletions(-) diff --git a/src/renderer/src/assets/main.css b/src/renderer/src/assets/main.css index 5caa4992cb4..8e389248460 100644 --- a/src/renderer/src/assets/main.css +++ b/src/renderer/src/assets/main.css @@ -54,6 +54,10 @@ --color-sidebar-foreground: var(--sidebar-foreground); --color-worktree-sidebar: var(--worktree-sidebar); --color-worktree-sidebar-foreground: var(--worktree-sidebar-foreground); + --color-worktree-sidebar-accent: var(--worktree-sidebar-accent); + --color-worktree-sidebar-accent-foreground: var(--worktree-sidebar-accent-foreground); + --color-worktree-sidebar-border: var(--worktree-sidebar-border); + --color-worktree-sidebar-ring: var(--worktree-sidebar-ring); --color-sidebar-primary: var(--sidebar-primary); --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); --color-sidebar-accent: var(--sidebar-accent); @@ -141,6 +145,10 @@ --chart-5: var(--color-blue-800); --worktree-sidebar: #f5f5f5; --worktree-sidebar-foreground: #0a0a0a; + --worktree-sidebar-accent: #eaeaea; + --worktree-sidebar-accent-foreground: #171717; + --worktree-sidebar-border: #e5e5e5; + --worktree-sidebar-ring: #a1a1a1; --sidebar: #fafafa; --sidebar-foreground: #0a0a0a; --sidebar-primary: #171717; @@ -214,8 +222,14 @@ --chart-3: var(--color-blue-600); --chart-4: var(--color-blue-700); --chart-5: var(--color-blue-800); - --worktree-sidebar: #212121; + /* Why: light mode sets worktree-sidebar to secondary (#f5f5f5); mirror that + lift in dark mode so the panel reads clearly above #0a0a0a canvas. */ + --worktree-sidebar: #2a2a2a; --worktree-sidebar-foreground: #fafafa; + --worktree-sidebar-accent: #353535; + --worktree-sidebar-accent-foreground: #fafafa; + --worktree-sidebar-border: rgb(255 255 255 / 0.1); + --worktree-sidebar-ring: #737373; --sidebar: #171717; --sidebar-foreground: #fafafa; --sidebar-primary: #1447e6; diff --git a/src/renderer/src/components/sidebar/ImportedWorktreesVisibilityLine.tsx b/src/renderer/src/components/sidebar/ImportedWorktreesVisibilityLine.tsx index 069669e26b1..ed6b2ac64a2 100644 --- a/src/renderer/src/components/sidebar/ImportedWorktreesVisibilityLine.tsx +++ b/src/renderer/src/components/sidebar/ImportedWorktreesVisibilityLine.tsx @@ -115,12 +115,12 @@ export default function ImportedWorktreesVisibilityLine({ return (
@@ -164,7 +164,7 @@ export default function ImportedWorktreesVisibilityLine({ {isExpanded ? (
{visibleWorktreeGroups.map((group) => ( @@ -174,7 +174,7 @@ export default function ImportedWorktreesVisibilityLine({ {group.path} @@ -183,7 +183,7 @@ export default function ImportedWorktreesVisibilityLine({ {group.path} - + {group.worktrees.length}
@@ -216,7 +216,7 @@ export default function ImportedWorktreesVisibilityLine({ size="xs" disabled={pending} onClick={() => toggleGroupExpanded(group.path)} - className="h-6 justify-start px-0 text-[11px] font-normal text-muted-foreground hover:text-sidebar-accent-foreground" + className="h-6 justify-start px-0 text-[11px] font-normal text-muted-foreground hover:text-worktree-sidebar-accent-foreground" > {expandedGroupPathKeys.has(normalizeRuntimePathForComparison(group.path)) ? 'Show fewer' @@ -233,7 +233,7 @@ export default function ImportedWorktreesVisibilityLine({
) : null}
-

+

Change this later from the project menu.

diff --git a/src/renderer/src/components/sidebar/SetupGuideSidebarEntry.tsx b/src/renderer/src/components/sidebar/SetupGuideSidebarEntry.tsx index 6cdb70d4367..ebc613bdd1a 100644 --- a/src/renderer/src/components/sidebar/SetupGuideSidebarEntry.tsx +++ b/src/renderer/src/components/sidebar/SetupGuideSidebarEntry.tsx @@ -77,8 +77,8 @@ export function SetupGuideSidebarEntry(): React.JSX.Element | null { className={cn( 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-[13px] font-medium tracking-tight transition-colors', setupActive - ? 'bg-sidebar-accent text-sidebar-accent-foreground' - : 'text-sidebar-foreground/60 hover:bg-sidebar-foreground/8' + ? 'bg-worktree-sidebar-accent text-worktree-sidebar-accent-foreground' + : 'text-worktree-sidebar-foreground/60 hover:bg-worktree-sidebar-foreground/8' )} > -
+

Add a setup script

diff --git a/src/renderer/src/components/sidebar/SetupScriptPromptCardViews.tsx b/src/renderer/src/components/sidebar/SetupScriptPromptCardViews.tsx index f093efa8fad..08467d4a96f 100644 --- a/src/renderer/src/components/sidebar/SetupScriptPromptCardViews.tsx +++ b/src/renderer/src/components/sidebar/SetupScriptPromptCardViews.tsx @@ -44,7 +44,7 @@ export function DetectedSetupPreview({ provenance }: DetectedSetupPreviewProps): React.JSX.Element { return ( -
+
Detected setup @@ -55,7 +55,7 @@ export function DetectedSetupPreview({ onChange={(event) => onSetupChange(event.target.value)} spellCheck={false} rows={Math.min(Math.max(setup.split('\n').length, 2), 6)} - className="setup-script-prompt-command max-h-28 w-full resize-y overflow-auto scrollbar-sleek rounded-md border border-sidebar-border px-2 py-1.5 font-mono text-[11px] leading-5 text-foreground shadow-xs outline-none focus-visible:ring-1 focus-visible:ring-ring" + className="setup-script-prompt-command max-h-28 w-full resize-y overflow-auto scrollbar-sleek rounded-md border border-worktree-sidebar-border px-2 py-1.5 font-mono text-[11px] leading-5 text-foreground shadow-xs outline-none focus-visible:ring-1 focus-visible:ring-ring" /> {provenance ? (

diff --git a/src/renderer/src/components/sidebar/SidebarNav.tsx b/src/renderer/src/components/sidebar/SidebarNav.tsx index 297fcc8aed9..03f22f76e8d 100644 --- a/src/renderer/src/components/sidebar/SidebarNav.tsx +++ b/src/renderer/src/components/sidebar/SidebarNav.tsx @@ -226,13 +226,16 @@ const SidebarNav = React.memo(function SidebarNav() { className={cn( 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-[13px] font-medium tracking-tight transition-colors', tasksActive - ? 'bg-sidebar-accent text-sidebar-accent-foreground' - : 'text-sidebar-foreground/60 hover:bg-sidebar-foreground/8', + ? 'bg-worktree-sidebar-accent text-worktree-sidebar-accent-foreground' + : 'text-worktree-sidebar-foreground/60 hover:bg-worktree-sidebar-foreground/8', !canBrowseTasks && 'cursor-not-allowed opacity-50 hover:bg-transparent' )} > Tasks @@ -297,14 +300,14 @@ const SidebarNav = React.memo(function SidebarNav() { className={cn( 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-[13px] font-medium tracking-tight transition-colors', automationsActive - ? 'bg-sidebar-accent text-sidebar-accent-foreground' - : 'text-sidebar-foreground/60 hover:bg-sidebar-foreground/8' + ? 'bg-worktree-sidebar-accent text-worktree-sidebar-accent-foreground' + : 'text-worktree-sidebar-foreground/60 hover:bg-worktree-sidebar-foreground/8' )} > @@ -322,12 +325,15 @@ const SidebarNav = React.memo(function SidebarNav() { className={cn( 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-[13px] font-medium tracking-tight transition-colors', activityActive - ? 'bg-sidebar-accent text-sidebar-accent-foreground' - : 'text-sidebar-foreground/60 hover:bg-sidebar-foreground/8' + ? 'bg-worktree-sidebar-accent text-worktree-sidebar-accent-foreground' + : 'text-worktree-sidebar-foreground/60 hover:bg-worktree-sidebar-foreground/8' )} > Agents @@ -351,12 +357,15 @@ const SidebarNav = React.memo(function SidebarNav() { className={cn( 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-[13px] font-medium tracking-tight transition-colors', mobileActive - ? 'bg-sidebar-accent text-sidebar-accent-foreground' - : 'text-sidebar-foreground/60 hover:bg-sidebar-foreground/8' + ? 'bg-worktree-sidebar-accent text-worktree-sidebar-accent-foreground' + : 'text-worktree-sidebar-foreground/60 hover:bg-worktree-sidebar-foreground/8' )} > Orca Mobile @@ -374,9 +383,12 @@ const SidebarNav = React.memo(function SidebarNav() { type="button" onClick={() => openModal('worktree-palette')} aria-label="Search worktrees and browser tabs" - className="group flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-[13px] font-medium tracking-tight text-sidebar-foreground/60 transition-colors hover:bg-sidebar-foreground/8" + className="group flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-[13px] font-medium tracking-tight text-worktree-sidebar-foreground/60 transition-colors hover:bg-worktree-sidebar-foreground/8" > - + Search {worktreePaletteShortcut} diff --git a/src/renderer/src/components/sidebar/SidebarToolbar.tsx b/src/renderer/src/components/sidebar/SidebarToolbar.tsx index 07afef74f47..b4df5192f29 100644 --- a/src/renderer/src/components/sidebar/SidebarToolbar.tsx +++ b/src/renderer/src/components/sidebar/SidebarToolbar.tsx @@ -82,7 +82,7 @@ const SidebarToolbar = React.memo(function SidebarToolbar() { return (

-
+
) : null} {virtualItems.map((vItem) => { @@ -2846,7 +2846,9 @@ const VirtualizedWorktreeViewport = React.memo(function VirtualizedWorktreeViewp // reaches the top (see getActiveStickyHeaderIndexForScroll), // so the previous repo no longer stays pinned over it. hasHeaderTopSpacing && !isActiveStickyHeader && 'pt-1', - isActiveStickyHeader ? 'sticky -top-px z-20 bg-sidebar' : 'absolute top-0' + isActiveStickyHeader + ? 'sticky -top-px z-20 bg-worktree-sidebar' + : 'absolute top-0' )} style={ isActiveStickyHeader @@ -2868,10 +2870,10 @@ const VirtualizedWorktreeViewport = React.memo(function VirtualizedWorktreeViewp 'bg-accent/80 ring-1 ring-ring/40 shadow-md rounded-md scale-[1.01]', headerWorkspaceStatus && dragOverStatus === headerWorkspaceStatus && - 'rounded-md bg-sidebar-accent ring-1 ring-sidebar-ring/40', + 'rounded-md bg-worktree-sidebar-accent ring-1 ring-worktree-sidebar-ring/40', isPinnedHeader && pinDragOver && - 'rounded-md bg-sidebar-accent ring-1 ring-sidebar-ring/40', + 'rounded-md bg-worktree-sidebar-accent ring-1 ring-worktree-sidebar-ring/40', row.repo && 'overflow-hidden' )} style={{ paddingLeft: headerPaddingLeft }} @@ -3426,7 +3428,7 @@ const VirtualizedWorktreeViewport = React.memo(function VirtualizedWorktreeViewp type="button" variant="ghost" size="xs" - className="h-[18px] max-w-[8rem] gap-1 rounded-md border border-sidebar-border bg-sidebar px-1.5 text-[10px] font-medium leading-none text-muted-foreground shadow-none hover:bg-sidebar-accent hover:text-foreground focus-visible:ring-1 focus-visible:ring-sidebar-ring" + className="h-[18px] max-w-[8rem] gap-1 rounded-md border border-worktree-sidebar-border bg-worktree-sidebar px-1.5 text-[10px] font-medium leading-none text-muted-foreground shadow-none hover:bg-worktree-sidebar-accent hover:text-foreground focus-visible:ring-1 focus-visible:ring-worktree-sidebar-ring" aria-label={`${child.lineageCollapsed ? 'Show' : 'Hide'} ${ child.lineageChildCount } child ${ diff --git a/src/renderer/src/components/sidebar/WorktreeTitleInlineRename.tsx b/src/renderer/src/components/sidebar/WorktreeTitleInlineRename.tsx index 2f3cbcad687..d0c1dffcc66 100644 --- a/src/renderer/src/components/sidebar/WorktreeTitleInlineRename.tsx +++ b/src/renderer/src/components/sidebar/WorktreeTitleInlineRename.tsx @@ -263,7 +263,7 @@ export function WorktreeTitleInlineRename({ key={`title:${titleElementKey}`} ref={handleRootRef} className={cn( - 'block min-w-0 truncate leading-tight text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-sidebar-ring', + 'block min-w-0 truncate leading-tight text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-worktree-sidebar-ring', showUnreadEmphasis ? 'font-semibold' : 'font-normal', className )} diff --git a/src/renderer/src/components/sidebar/index.tsx b/src/renderer/src/components/sidebar/index.tsx index 712fb5dfa44..d4804f04d58 100644 --- a/src/renderer/src/components/sidebar/index.tsx +++ b/src/renderer/src/components/sidebar/index.tsx @@ -93,8 +93,10 @@ function Sidebar({ {sidebarOpen && affordance.visible ? (
{affordance.tone === 'busy' ? ( diff --git a/src/renderer/src/components/sidebar/worktree-card-compact-agents.tsx b/src/renderer/src/components/sidebar/worktree-card-compact-agents.tsx index f1690927749..4533fee8360 100644 --- a/src/renderer/src/components/sidebar/worktree-card-compact-agents.tsx +++ b/src/renderer/src/components/sidebar/worktree-card-compact-agents.tsx @@ -166,15 +166,15 @@ export function CompactAgentSummaryButton({ className={cn( 'compact-agent-summary-button group/agent-summary flex h-6 w-full min-w-0 items-center gap-1 rounded-sm', 'px-1 text-left text-[11px] leading-none text-muted-foreground', - 'focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-sidebar-ring', - // Why: sidebar-accent is near-white in light mode and dark in dark + 'focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-worktree-sidebar-ring', + // Why: worktree-sidebar-accent is near-white in light mode and dark in dark // mode, so hover lightening needs a theme-specific token mix. - 'hover:bg-sidebar-accent/55 dark:hover:bg-sidebar-foreground/[0.035]', + 'hover:bg-worktree-sidebar-accent/55 dark:hover:bg-worktree-sidebar-foreground/[0.035]', // Why: expanded is a tree header inside the card, so only the // standalone collapsed pill gets a resting surface and border. expanded ? 'compact-agent-summary-button-expanded' - : 'border border-sidebar-border/70 bg-sidebar-accent/35' + : 'border border-worktree-sidebar-border/70 bg-worktree-sidebar-accent/35' )} aria-label={ expanded ? `Collapse ${subjectLabel}` : `Expand ${summary}. ${agentIdentitySummary}` @@ -199,7 +199,7 @@ export function CompactAgentSummaryButton({ return ( {/* Why: same-state agent identities read as one status cluster; @@ -208,7 +208,7 @@ export function CompactAgentSummaryButton({ {iconAgents.map((agent) => ( @@ -296,7 +296,7 @@ export const CompactAgentRow = React.memo(function CompactAgentRow({ {hasChildDisclosure ? (