diff --git a/src/renderer/src/components/sidebar/WorktreeCard.tsx b/src/renderer/src/components/sidebar/WorktreeCard.tsx index 313f4157223..9ec6e8b1a95 100644 --- a/src/renderer/src/components/sidebar/WorktreeCard.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCard.tsx @@ -61,6 +61,7 @@ import { } from './workspace-delete-quick-action' import { DetachedHeadBadge } from '@/components/DetachedHeadBadge' import { getWorktreeGitIdentityDisplay } from '@/lib/worktree-git-identity-display' +import { getFlushWorktreeCardPaddingLeft } from './worktree-list-indentation' import { translate } from '@/i18n/i18n' import { folderWorkspaceKey, parseWorkspaceKey } from '../../../../shared/workspace-scope' @@ -793,8 +794,7 @@ const WorktreeCard = React.memo(function WorktreeCard({ // aligned with the pre-inset layout and the repo header hierarchy. const cardStyle = flushSurface ? { - paddingLeft: - contentIndent > 0 ? `max(0.125rem, calc(${contentIndent}px - 0.625rem))` : '0.125rem' + paddingLeft: getFlushWorktreeCardPaddingLeft(contentIndent) } : contentIndent > 0 ? { paddingLeft: `calc(0.125rem + ${contentIndent}px)` } diff --git a/src/renderer/src/components/sidebar/worktree-list-indentation.test.ts b/src/renderer/src/components/sidebar/worktree-list-indentation.test.ts index 8ce4f34dc7d..a7ba3b1f80f 100644 --- a/src/renderer/src/components/sidebar/worktree-list-indentation.test.ts +++ b/src/renderer/src/components/sidebar/worktree-list-indentation.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest' import { WORKTREE_SECTION_HEADER_PADDING_LEFT, + getFlushWorktreeCardPaddingLeft, getProjectGroupHeaderPaddingLeft, getWorktreeCardContentIndent, getWorktreeCardSurfaceInset @@ -50,4 +51,12 @@ describe('worktree list indentation', () => { it('does not inset card surfaces outside grouped views', () => { expect(getWorktreeCardSurfaceInset({ isGrouped: false, groupDepth: 4 })).toBe(0) }) + + it('pulls flush card content back by the tuned inset gap', () => { + expect(getFlushWorktreeCardPaddingLeft(20)).toBe('max(2px, calc(20px - 4px))') + }) + + it('keeps flush card content off the sidebar edge without indentation', () => { + expect(getFlushWorktreeCardPaddingLeft(0)).toBe('2px') + }) }) diff --git a/src/renderer/src/components/sidebar/worktree-list-indentation.ts b/src/renderer/src/components/sidebar/worktree-list-indentation.ts index e327e197f83..04af39ef64b 100644 --- a/src/renderer/src/components/sidebar/worktree-list-indentation.ts +++ b/src/renderer/src/components/sidebar/worktree-list-indentation.ts @@ -2,6 +2,13 @@ export const SIDEBAR_TREE_INDENT = 18 // Why: project-grouped cards need to read as children even after the card // surface inset is subtracted, while lineage rows keep the base tree step. const PROJECT_WORKTREE_CARD_EXTRA_INDENT = 2 +// Why: flush cards span the full row, so their content is pulled back from the +// raw tree indent to sit under the group header. A smaller pullback nudges +// content rightward for clearer nesting; this is the knob to tune that gap. +export const FLUSH_CARD_CONTENT_PULLBACK = 4 +// Why: even at zero indent a flush card keeps this minimal left inset so its +// surface never sits hard against the sidebar edge. +export const FLUSH_CARD_MIN_CONTENT_INSET = 2 // Why: grouped workspace cards should move their surface inward without using // the full tree step, preserving the existing compact child-card rhythm. const GROUPED_WORKTREE_CARD_SURFACE_INDENT = 14 @@ -39,3 +46,9 @@ export function getWorktreeCardSurfaceInset(args: { }): number { return args.isGrouped ? clampDepth(args.groupDepth) * GROUPED_WORKTREE_CARD_SURFACE_INDENT : 0 } + +export function getFlushWorktreeCardPaddingLeft(contentIndent: number): string { + return contentIndent > 0 + ? `max(${FLUSH_CARD_MIN_CONTENT_INSET}px, calc(${contentIndent}px - ${FLUSH_CARD_CONTENT_PULLBACK}px))` + : `${FLUSH_CARD_MIN_CONTENT_INSET}px` +}