🔇 feat: Let a Theme Quiet Decorative Borders - #16741
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
e73ec58 to
275e229
Compare
275e229 to
69cc1b3
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 69cc1b324a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| activeTab === category.value | ||
| ? 'border-border-heavy bg-surface-active-alt text-text-primary' | ||
| : 'border-border-light bg-surface-secondary text-text-secondary hover:bg-surface-hover hover:text-text-primary', | ||
| : 'border-border-chrome bg-surface-secondary text-text-secondary hover:bg-surface-hover hover:text-text-primary', |
There was a problem hiding this comment.
Apply chrome alpha to the selected tab border
When the ClickHouse theme is active and a marketplace category is selected, only the inactive branch uses border-border-chrome; the active branch still paints border-border-heavy. As a result, the selected pill retains a visible stroke even though this theme sets chromeBorderAlpha to zero specifically because its basic tabs communicate hover and selection through fill rather than strokes. Route the active border through an alpha-aware chrome role as well while preserving the heavier default-theme appearance.
AGENTS.md reference: AGENTS.md:L144-L151
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in d9e6feb: the selected pill now draws border-chrome-heavy (border-heavy at the chrome share), so it is unchanged in the bundled themes and quiet in ClickHouse.
69cc1b3 to
fbcfb5e
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fbcfb5ee40
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| <span | ||
| className={cn( | ||
| 'border-border-light bg-surface-tertiary text-text-secondary inline-flex max-w-full items-center rounded-full border px-2.5 py-1 text-xs leading-4 font-medium', | ||
| 'border-border-chrome bg-surface-tertiary text-text-secondary inline-flex max-w-full items-center rounded-full border px-2.5 py-1 text-xs leading-4 font-medium', |
There was a problem hiding this comment.
Preserve the Click UI badge stroke for category badges
When the ClickHouse theme is active, this makes every agent category badge border transparent because chromeBorderAlpha is 0. However, this component already matches Click UI's opaque badge in fill, text, and full radius, and the checked-in Click UI reference explicitly gives that badge a visible click.badge.opaque.color.stroke.default (#e6e7e9 light / #323232 dark), which is the theme's border-light. Keep this badge on border-border-light or introduce a badge-specific role rather than classifying it as borderless chrome.
AGENTS.md reference: AGENTS.md:L144-L151
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in d9e6feb: Click UI's opaque badge keeps stroke.default, so the category badge is back on border-light.
| showBorder: false, | ||
| className: | ||
| 'rounded-full bg-surface-tertiary ring-1 ring-border-light transition-colors duration-150 group-hover:ring-border-medium', | ||
| 'rounded-full bg-surface-tertiary ring-1 ring-border-chrome transition-colors duration-150 group-hover:ring-border-medium', |
There was a problem hiding this comment.
Keep the avatar hover ring on the chrome role
When a ClickHouse user hovers an agent card, group-hover:ring-border-medium overrides the new ring-border-chrome, so the avatar immediately regains a visible ring despite this theme setting chromeBorderAlpha to zero and the change explicitly migrating the avatar ring to quiet chrome. Use an alpha-aware chrome color for the hover state (or remove that ring state) so interaction does not bypass the theme role.
AGENTS.md reference: AGENTS.md:L144-L151
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in d9e6feb: the hover ring is border-chrome-medium (border-medium at the chrome share), identical in the bundled themes, so hover no longer bypasses the chrome share.
| </TooltipAnchor> | ||
| render={ | ||
| <Button | ||
| size="icon" |
There was a problem hiding this comment.
Preserve the multi-conversation button size
When multi-conversation access is enabled, replacing the fixed size-9 control with size="icon" changes this header button to the theme's general button size: 40px in the default theme and 32px in ClickHouse, while the adjacent model, bookmark, share, temporary-chat, and background-task controls remain 36px. The resulting button is visibly misaligned and changes the header layout even though this migration only needs native button behavior and the shared hover treatment; retain the previous 36px size while using the shared primitive.
AGENTS.md reference: AGENTS.md:L144-L151
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in d9e6feb: the button keeps size-9 on the shared Button, matching the other 36px header controls.
fbcfb5e to
8834f0b
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8834f0b50b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| /** Click UI strokes cards, panels, dialogs, fields and tables in stroke.default, but not the | ||
| * controls and chat chrome LibreChat outlines (iconButton.*.stroke.default and tabs.basic are | ||
| * transparent), and it separates a card's inner regions by fill. */ | ||
| chromeBorderAlpha: '0', // iconButton.primary.stroke.default |
There was a problem hiding this comment.
Route surface chips through the chrome border role
When the ClickHouse theme is active and a user stages a quote or skill in the composer, client/src/components/Chat/Input/Composer/Chip.tsx renders the shared Chip with tone="surface", but that primitive still hard-codes border-border-light in packages/client/src/components/Chip.tsx. Consequently, setting chromeBorderAlpha to zero here does not quiet these actual shell chips despite the new role explicitly covering chips; migrate the shared surface tone to border-border-chrome rather than only updating feature-local pill implementations.
AGENTS.md reference: AGENTS.md:L144-L151
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in d9e6feb: the shared Chip surface tone draws border-chrome, so staged quote and skill chips follow the theme role.
| variant: 'outline', | ||
| size: ['icon', 'icon-sm', 'icon-xs', 'icon-theme'], | ||
| class: 'border-border-chrome', |
There was a problem hiding this comment.
Include subtle icon buttons in the chrome mapping
When the ClickHouse theme is active and the agent version-history panel is opened, its back control renders Button with variant="subtle" and size="icon", but the subtle recipe still uses border-border-light. This compound mapping only covers outline, so that icon button retains a visible stroke even though chromeBorderAlpha is zero; apply the chrome border role to icon-sized subtle buttons as well.
AGENTS.md reference: AGENTS.md:L144-L151
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in d9e6feb: the icon-sized chrome compound covers the subtle variant too, and IconButton secondary takes the chrome border.
| <div className="overflow-hidden" ref={expandRef}> | ||
| {shouldRenderBody && ( | ||
| <div className="border-border-light bg-surface-secondary text-text-secondary relative my-2 rounded-2xl border p-4"> | ||
| <div className="border-border-inset bg-surface-secondary text-text-secondary relative my-2 rounded-2xl border p-4"> |
There was a problem hiding this comment.
Keep outer reasoning cards on the surface border
When the ClickHouse theme is active and a user expands reasoning, this is the card's only outer edge rather than a hairline inside an already-stroked surface, so insetBorderAlpha: 0 removes the entire card stroke even though the theme definition explicitly says Click UI cards remain stroked. Keep this edge on border-border-light; the same outer-card misclassification appears on ThinkingContent in Thinking.tsx.
AGENTS.md reference: AGENTS.md:L144-L151
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in d9e6feb: Reasoning and Thinking cards are the only edge of a card, so they stay on border-light.
d9e6feb to
c76cf2f
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c76cf2fb94
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| * controls and chat chrome LibreChat outlines (iconButton.*.stroke.default and tabs.basic are | ||
| * transparent), and it separates a card's inner regions by fill. */ | ||
| chromeBorderAlpha: '0', // iconButton.primary.stroke.default | ||
| insetBorderAlpha: '0', // separation by fill, not a nested stroke |
There was a problem hiding this comment.
Route the subagent progress divider through the inset role
When a background task includes an activity digest, SubagentProgress.tsx still renders its top divider with border-border-light, so ClickHouse continues to show that inner stroke even though this new insetBorderAlpha: '0' setting removes the equivalent result and error dividers in BackgroundTaskCard.tsx. Migrate the progress divider to border-border-inset as well so all sections of the same stroked card honor the theme setting consistently.
AGENTS.md reference: AGENTS.md:L144-L151
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in d3def05: the subagent progress divider draws border-border-inset with the other inner card dividers, identical in the bundled themes.
c76cf2f to
d3def05
Compare
d3def05 to
801001b
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 801001b8c7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (type === 'hunk') { | ||
| if (!text) { | ||
| return <div className="border-border-light mx-3 my-1.5 border-t" />; | ||
| return <div className="border-border-inset mx-3 my-1.5 border-t" />; |
There was a problem hiding this comment.
Keep batched-edit dividers visible
When the ClickHouse theme renders a file-authoring call containing multiple structured edits, buildEditPreviewDiff inserts these empty hunk rows as the only visual boundary between edits, but border-border-inset becomes fully transparent. Consecutive replacements—especially adjacent rows with the same add/delete coloring—then appear to be one edit, obscuring the grouping the divider was created to convey. Keep this semantic separator on border-border-light or introduce a separator-specific role rather than using the quiet inset role.
AGENTS.md reference: AGENTS.md:L144-L151
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 79c5b06: the empty-hunk divider between batched edits is the only boundary between edits, so it stays on border-border-light.
801001b to
6eb84dc
Compare
6eb84dc to
290972c
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 290972c52f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| 'hover:bg-surface-hover flex gap-2.5 px-3 py-2 transition-colors', | ||
| snippet ? 'items-start' : 'items-center', | ||
| i > 0 && 'border-border-light border-t', | ||
| i > 0 && 'border-border-inset border-t', |
There was a problem hiding this comment.
Keep list-row separators on a visible border role
When the ClickHouse theme displays an expanded search with multiple sources, insetBorderAlpha: 0 makes every divider here transparent, so consecutive same-surface links lose their only visual row boundary. These are list separators rather than redundant hairlines between fill-separated card regions—the theme's own reference notes that Click UI retains separators—and the same misclassification affects place-result rows in verticals.tsx and activity rows in EventSubagentActivityGroup.tsx; keep these dividers on border-border-light or add a separator-specific semantic role.
AGENTS.md reference: AGENTS.md:L144-L151
Useful? React with 👍 / 👎.
Summary
The ClickHouse theme draws more strokes than Click UI does. LibreChat outlines icon buttons, chips, avatar rings and the rail beside the sidebar, and stacks three or four hairlines inside one tool or marketplace card, where Click UI separates regions by fill. The decorative border values are already Click UI's own
stroke.default, so the problem is how many borders are drawn, and a theme could not remove them without also removing the card, popover and dialog strokes Click UI keeps.This adds two appearance roles,
chromeBorderAlphaandinsetBorderAlpha(default 1), and theborder-chromeandborder-insetutilities, which areborder-lightat those shares. ClickHouse sets both to 0; the 1px box stays, so layout and hover geometry do not move, and the bundled themes draw exactly theborder-lightthey drew before. Call sites that Click UI draws borderless move onto them: outlined icon buttons and the header action inButton, header pills, skill and quote chips, the marketplace card's avatar ring, category chip and footer rule, tool-card inner dividers and nested thought boxes, the rail rule beside the sidebar, and the settings dialog title rule. The Settings dialog also picks up--theme-dialog-stroke, so it is stroked like every other dialog in ClickHouse.Fields keep their 3:1 edge: the sign-in, registration and password forms drop their
border-lightoverride and take theInputprimitive's ownborder-control, and the search field and the agent builder's model trigger move toborder-controltoo (equal toborder-lightin the bundled themes).Type of change
Testing
Tested environments/configuration:
interface.theme: clickhouseand the default themeAutomated tests:
cd packages/client && npx jest(947 passed),cd client && npx jest --findRelatedTests <changed files>(7196 passed), data-provider theme specse2e/specs/mock/scenarios/chrome-border.spec.ts(default light/dark unchanged, ClickHouse light/dark draw nothing and keep the 1px box, a theme with its own shares)npm run static-checks -- --against origin/devpasses;eslint-suppressions.jsoncounts only go downdev, maximum channel difference 2 on anti-aliased edgesScreenshots / recordings
Before and after screenshots below (ClickHouse, light and dark).
Risk / compatibility
Stacked on the
focus-subtlePR.AddMultiConvonow renders the sharedButton(header-action) insideTooltipAnchor, so it is a real button with the shared hover fill instead of a styledrole="button"div. The chat direction toggle and the legacy parameters button keepborder-light: both sit on primitives that reject a border override.Checklist
packages/client/src/theme/README.md)