fix(web): thread hover cards show the provider icon in its brand color#31527
Problem
Hovering a sidebar thread opens a hover card whose provider icon is gray and faded, while the sidebar row right next to it shows the same provider in its brand color (Claude's orange). Reproduced on main 337c5858c3 in the web dev server: start a thread with a Claude model, hover its sidebar row; the card's icon computes filter: grayscale(1) in both light and dark themes, while the row's icon is unfiltered.
Change
Removes the leftover grayscale class from the provider icon in the two thread hover cards that share ThreadHoverCard:
SidebarThreadTooltip(apps/web/src/components/sidebar/SidebarThreadRow.tsx), the card the issue names. It keepssize-3 shrink-0 opacity-60, so it now matches the sidebar row's current-provider icon exactly.SubagentTooltipContent(apps/web/src/components/chat/SubagentTooltipContent.tsx), the subagent card in the timeline, relationships panel and workflow rows, which had the identical class string. It now shows the provider's brand color too, at the same 60% opacity as the sidebar card.
The deliberately dimmed icons of earlier providers in the sidebar row stack (opacity-35 grayscale) are unchanged.
Scope and approval
Fixes pingdotgg/t3code#31477
Triaged via the automated issue flow; GitCafe issue #31477.
Verification
vp run check:changed: format, lint, knip, typecheck (2 packages) and react compiler pass. No test added: this is a purely visual fix, so the proof is the before/after captures below.- Computed style in the real app: card icon
filtergoes fromgrayscale(1)(before) tonone(after); opacity stays0.6, matching the row icon.
Evidence. Real web app, each side served from its own checkout on a fresh database (T3CODE_DEV_SEED=0, empty home), seeded through the UI with real Claude and Codex turns; cards opened by hovering. Chrome 156 on Linux, no device emulation, DPR 2, 100% font scaling. Each sheet shows Before | After on top and Diff0 (absolute difference ×255) | DiffT (ImageMagick compare -fuzz 5%) below. Before = 337c5858c3, After = 30c91612dd for every row.
| Row (viewport, theme) | Before | After / Diff0 | DiffT |
|---|---|
| Sidebar card, Claude (1440, light) | |
| Sidebar card, Claude (1440, dark) | |
| Sidebar card, Claude (390, light) | |
| Sidebar card, Claude (390, dark) | |
| Sidebar search result card, Claude (1440, light) | |
| Subagent card, Claude child (1440, light) | |
| Subagent card, Claude child (1440, dark) | |
| Control: sidebar card, Codex (1440, light) | |
| Control: sidebar card, Codex (1440, dark) |
What else changed:
- Sidebar and search cards: at zero threshold, only the Claude icon differs, in the card crops and in the full viewports.
- Subagent card: at zero threshold, only the Claude icon differs in the card crops. Each side ran its own real agent turns, so the full viewports also differ in turn durations, the generated reply text and the Git panel (detached base versus the fix branch). That is why the crops are the evidence for this row.
- Codex control: the icon is monochrome. Dark is pixel-identical; light differs by at most 5/255 in one channel, at the icon only, and shows no difference at 5%.
Not verified:
- Brand-colored icons for providers not installed on the test machine (Antigravity's raster, Kiro, Muse, OpenCode). The change removes the same class for every icon type.
- The desktop app on macOS and Windows. Desktop renders this same web component.
Seeding driver, abbreviated (UI actions issued through the browser tool on each fresh server)
| 1 | // Successful UI action transcript used on each independently paired fresh server. |
| 2 | export async function seedUi(tools, tabId) { |
| 3 | const act = (args) => tools.preview_act({ tabId, ...args }); |
| 4 | const send = async (title, text) => { |
| 5 | await act({ action: 'type', locator: `role=textbox[name="Message ${title}"]`, text }); |
| 6 | await act({ action: 'click', locator: 'role=button[name="Submit message"]' }); |
| 7 | }; |
| 8 | const rename = async (from, to) => { |
| 9 | await act({ action: 'click', locator: `role=button[name="Thread actions for ${from}"]` }); |
| 10 | await act({ action: 'click', locator: 'text=Rename thread' }); |
| 11 | await act({ action: 'type', locator: 'role=textbox[name="Thread title"]', text: to, clear: true }); |
| 12 | await act({ action: 'press', key: 'Enter' }); |
| 13 | }; |
| 14 | // choose(provider, model): open the composer model picker, pick the provider tab and model. |
| 15 | await send('New thread', 'Reply with the word ok.'); // Codex control thread |
| 16 | await choose('Claude', 'Claude Haiku 5.5'); |
| 17 | await act({ action: 'click', locator: 'role=button[name="New thread"]' }); |
| 18 | await send('New thread', 'Reply with the word ok.'); // Claude thread |
| 19 | await send('Acknowledge with OK', "Use T3 delegate_task to start exactly one Claude Haiku 5.5 child titled 'Claude child' with task 'Reply with the word ok.' Wait for completion and reply ok."); |
| 20 | await rename('Acknowledge with OK', 'Claude fixture'); |
| 21 | await rename('Acknowledge with OK', 'Codex fixture'); |
| 22 | } |
| 23 | // Sidebar cells: hover the named row. Narrow cells: 390x844, open the sidebar, hover Claude fixture. |
| 24 | // Search cell: search "Claude fixture", hover the result. Subagent cell: open Claude fixture, |
| 25 | // thread details, Previous agents, hover "Claude child". |
AI-assisted; verified with the tests and tools listed above.
Checks
Added 1 commit
- fix(web): thread hover cards show the provider icon in its brand color30c9161
Approvability
Verdict: Approved at 30c9161
Macroscope's review found this PR approvable — Provider icons in thread and subagent hover cards now retain their brand colors, with sizing and opacity unchanged. The change is presentation-only and carries no material operational or customer-data risk.
You can add or adjust custom eligibility rules. Learn more.
No actionable comments were generated in the recent review.
Walkthrough
-
Two tooltip components no longer apply grayscale styling to provider icons. Their other icon styling remains unchanged.
Changes: Provider Icon Tooltips
Layer / File(s) Summary Remove grayscale styling
apps/web/src/components/chat/SubagentTooltipContent.tsx,apps/web/src/components/sidebar/SidebarThreadRow.tsxBoth components render provider icons without the grayscaleclass. Existing size, shrink, and opacity classes remain.Estimated code review effort: 1 (Trivial) | ~3 minutes
Change: Bug fix · Severity of issue fixed: Low
Possibly related issues
- Issue 31477 reports grayscale styling on the sidebar thread hover card. This change removes that styling while preserving
opacity-60.
Suggested reviewers:
maria-rcks - Issue 31477 reports grayscale styling on the sidebar thread hover card. This change removes that styling while preserving
Merge Risk: External image Minimal · up to 30c91
-
No actionable merge-blocking risk remains.
Pre-merge checks: Passed 4
-
Check name Status Explanation Title check Passed The title clearly and concisely describes the main change: restoring brand colors for provider icons in thread hover cards. Description check Passed The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the affected components, links the issue, documents focused checks and visual evidence… Linked Issues check Passed Check skipped because no linked issues were found for this pull request. Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request. Full details: Description check
-
Explanation
The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the affected components, links the issue, documents focused checks and visual evidence, and lists unverified environments and providers.
-
Finishing Touches
-
Generate docstrings
-
- Commit to this branch
- Create a new PR
Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
External image Recent review info
-
External image Run configuration
-
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: fix/issue-31477
- File: .coderabbit.config.ts
- Commit: 30c9161
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Team
- Run ID:
b09c6369-fb4f-4499-9050-3a16cae7e632
External image Commits
-
Reviewing files that changed from the base of the PR and between 337c5858c33bc7f8f6dfd391a2c279fa0f7e4d17 and 30c91612dd9aaeeea2f76705d86a7bedc5094035.
External image Files selected for processing: 2
-
apps/web/src/components/chat/SubagentTooltipContent.tsxapps/web/src/components/sidebar/SidebarThreadRow.tsx
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.
External image Recent review info
-
External image Run configuration
-
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: fix/issue-31477
- File: .coderabbit.config.ts
- Commit: 30c9161
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Team
- Run ID:
b09c6369-fb4f-4499-9050-3a16cae7e632
External image Commits
-
Reviewing files that changed from the base of the PR and between 337c5858c33bc7f8f6dfd391a2c279fa0f7e4d17 and 30c91612dd9aaeeea2f76705d86a7bedc5094035.
External image Files selected for processing: 2
-
apps/web/src/components/chat/SubagentTooltipContent.tsxapps/web/src/components/sidebar/SidebarThreadRow.tsx
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review.
-