feat(fork): restyle Sidebar V2 cards to the Figma card-v2 layout - #36
Conversation
Align chrome, group headers, and thread cards to the Figma card-v2 metrics so status, folder, and search icons share one left axis. Co-authored-by: Cursor <cursoragent@cursor.com>
Cards now measure exactly what the design draws: 16px rows in a 52px card, 2px between cards, 16px between groups, 16px of list headroom. Titles are regular weight with Done and Idle receding instead of Working; group headers use an open folder with a foreground label; the model label is caption-sized on either line. The trailing column's offsets are re-derived from the real row edges — chrome ends 12px in where the list ends 8 — which puts the header plus, card actions, slim actions and shelf chevrons on the same axis as the chrome icons and runtime glyphs. Chrome control rows sit at 28px with a left-aligned scope label. Also repairs the stale row-count helper in SidebarV2ThreadCardMeta.test.tsx. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
There was a problem hiding this comment.
Thermo-nuclear code quality review — not approving.
This PR does real structural good: moving status out of the trailing actions cell deletes the opacity/stacking hit-path bug, and the trailing-axis re-derivation is the right kind of fix. That is not enough for the approval bar.
The remaining problems are about ownership of the layout model. The whole PR is geometry, and the geometry is still a comment protocol scattered across SidebarV2.tsx, meta, status, and the trailing-offset table — already contradicting itself (52 vs 54). Until that model is one module the call sites consume, this will keep drifting the next time someone tunes a gap.
Ordered by priority:
- Card geometry has no owner; intentional Figma drift is unexplained
- Leading status dispatcher left in the 3k-line megacomponent
- Empty-string trailing offsets are identity slots pinned by guards
No approval until the geometry is a single derived model (and preferably the status mark composition leaves SidebarV2.tsx).
Sent by Cursor Automation: Thermo-nuclear PR review
Review — aggressive passThe geometry work is genuinely good. I re-derived the whole trailing axis independently and it holds: chrome So the layout is right. What follows is everything else. 1. The palette change is undisclosed, wider than its own rationale, and it eats the feature this PR ships
The stated reason is "Search / All projects / project headers". Every one of those reads
One line of this PR asserts colour is now the sole carrier of the signal; another line in the same PR reduces that signal to ~1.19:1, which is not visible. Done and Idle titles are, in practice, no longer receded at all. Same compression hits the meta lines: The guard added at expect(relativeLuminance(muted)).toBeGreaterThan(relativeLuminance("#a3a3a3"));Open-ended in the direction that causes the damage — Ask: drop the 2. Two contradictory recede policies now live in one component
Net result per card: a Working row's surface recedes ( Worse, the comment at
That is a verbatim statement of the policy this PR reverses, sitting directly above the variable that still implements it. Either 3. Focus-ring clearance on the settle/snooze buttons went from 4px to 0
4. Chrome trailing buttons shrank 32px → 24px on fine pointers
These chrome buttons are always-on — not hover-gated like the row actions. If Figma says 24, fine, but this PR should either say why the module's own rule doesn't apply here or amend the rule. Silently landing on the far side of an argument the codebase already wrote down is the thing that makes it un-relitigable later. 5. The false premise this PR fixes survives verbatim, five lines from the corrected value
The button is 24px now, 6. Cards drop unread emphasis; slim rows keep it
7. ~35 lines of load-bearing rationale deleted with no code change
Nits
Bottom line: the metrics and the axis re-derivation are solid and I'd take them as-is. Findings 1 and 2 are blocking — between them, the receded-title behaviour this PR re-specifies doesn't actually render, and the component holds two opposite definitions of "receded". 3 needs a browser check. 5 and 7 are documentation debt the PR created and should pay before merge. Generated by Claude Code |
The palette line that lifted --muted-foreground to #e0e0e0 is gone — only the sidebar-scoped chrome token is lifted now, so receded card titles and the title→branch hierarchy render again; the guard pins the exact hex and the absence of the panel override. Cards read one recede rule for surface and title (Done/Idle, via cardRecedes) while the slim shelves keep upstream's, and both the code comment and manifest say so. Row-action focus rings drop to ring-offset-1 so they clear the row's overflow-hidden instead of landing exactly on it. The stale chrome comments (32px buttons, "both columns end at the same place") are rewritten to the corrected axis model, the 24px always-on floor is documented as the design-wide stance, and the meta component gets back the worktree/dev-pulse/semantic-token rationale that was deleted with no code change. Nits: redundant mark conjunct dropped, the elapsed timer only fades when hover actions will replace it, meta rows carry a testid the row-count test uses instead of class sniffing, slim rows' intrinsic-size hint matches their real 36px, and the offset table says its empty entries are load-bearing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The rain module's comment restated the card's drawn height and went stale when the row gap was retuned (52 → 54); the card comment in SidebarV2 owns the number now and the rain note just points there. The gap-1.5 divergence from Figma's 4px carries its reason: with the prompt moved to the header label's 36px axis, the literal 4px read cramped between two 16px text rows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
All findings landed in 1 (blocking) — palette: You're right on every count, including the guard critique. The 2 (blocking) — two recede policies: Cards now compute one 3 — focus ring: Confirmed by derivation: button edge 4px inside the row's 4 — 24px chrome buttons: Amended the rule rather than silently contradicting it: the module's 2.5.8 note now says the 24px floor is the design-wide stance (Figma draws every icon-only control at it, always-on chrome included) with margin coming from the coarse-pointer child, and 5 — stale premise: The 6 — unread emphasis: Kept as deliberate divergence, now written down in the rowPolicy note and the manifest: the card delegates unread to the Done dot per the component set; slim rows keep upstream's brightness encoding. With finding 1 fixed the card's dimming is visible again, so the dot + dim combination reads. Nits: redundant Also from the Cursor threads: the rain module's stale "52px" claim is deduplicated into the card comment (single owner for the number), the PR body now states the retuned 54/75, and the 195 guard/custom tests pass, typecheck clean, CI green on 🤖 Generated with Claude Code |


Problem
The Sidebar V2 thread cards didn't match the Figma card-v2 design (t3-fork, node 113-3999). The headline change — the status indicator leading the card's title line instead of trailing it — landed in the first commit, but the metrics around it drifted: cards were 2px too tall, sat 5px apart instead of 2, groups sat 19px apart instead of 16, titles were medium-weight where the design draws Regular, the wrong statuses receded (Working instead of Done), and the fork-added trailing controls (group-header plus, card check/snooze, shelf chevrons) sat off the vertical axis the chrome icons and runtime glyphs share.
Fix
px-1 py-2,gap-1.5), 2px between cards via the listul's gap (rows carry no padding), 16px between groups, 16px of headroom above the list.contain-intrinsic-sizehints follow (54/75). The row gap and the 8px title gap are a deliberate live retune of Figma's literal 4px: the prompt sits on the header label's 36px axis, with the repo/meta indent (pl-6) following. The working rain keeps its 18px grid by overflowing 1px into the card padding rather than growing the row.sidebarV2TrailingColumn.tswas derived from a false premise — that the chrome rows and list rows end at the same edge (they're 4px apart). Every offset is now re-derived from the real insets against one axis 24px in from the panel edge, which lines up the header plus, card actions, slim-row actions, and shelf chevrons with the chrome buttons and runtime glyphs.SidebarV2ThreadCardMeta.test.tsxthat was failing 5/6 on the first commit, and updates the guard tests and.fork/customizations.yamlto pin the new metrics.Verified live against a seeded worktree dev environment by the maintainer, iterating on alignment with screenshots; 195 fork guard/custom tests pass and typecheck is clean.
Work by Claude Fable 5 via Claude Code, with maintainer-driven review in the live app.
Review updates
a636e5clands the maintainer review: the panel--muted-foregroundlift is gone (chrome keeps its--sidebar-muted-foregroundbrightness; receded card titles render again, guard pins the exact hex and the absence of the override), cards read one Done/Idle recede rule for surface and title while slim shelves keep upstream's, row-action focus rings clear the row clip (ring-offset-1), the stale chrome-column comments are rewritten, the 24px always-on floor is documented as the design-wide stance, and the deleted meta rationale is restored. Nits: redundant conjunct dropped, elapsed fade gated on actions existing, meta rows counted by testid, slim intrinsic-size 36px, offset table documents its empty entries.8949bd5deduplicates the card-height number into the card comment and gives the gap retune its reason.🤖 Generated with Claude Code