Uh oh!
There was an error while loading. Please reload this page.
fix(web): seal the seam between attached banners and the composer - #8551
fix(web): seal the seam between attached banners and the composer#8551vitalyiegorov wants to merge 1 commit into
Conversation
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Warning Your free Security trial is over. An organization admin can activate Security or dismiss this notice. Comment |
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This is a narrowly scoped one-file CSS seam fix, but the 1px bleed changes production rendering where configurable glass opacity and alert tint variants may differ across the overlap. The unresolved visual-consistency concern needs human validation across those states. No code changes detected at You can add or adjust custom eligibility rules. Learn more. |
There was a problem hiding this comment.
One finding on the new attachment-seal strip: its fill does not follow the same surface composition as the drawer it seals, so the sealed row can read as a band rather than a continuation of the drawer. Geometry, the shoulder-tab exclusion, and the --chat-composer-drawer-inset inheritance (via [data-chat-composer-form="true"]) all check out.
Posted via Macroscope — UI Consistency
| background: | ||
| linear-gradient( | ||
| var(--chat-composer-attachment-seal-shade), | ||
| var(--chat-composer-attachment-seal-shade) | ||
| ), | ||
| var(--chat-composer-glass-surface); |
There was a problem hiding this comment.
The strip paints the glass surface fully opaque and untinted, but the surface it is sealing is color-mix(in srgb, <surface> var(--glass-opacity), transparent) plus --chat-composer-attached-tint. Since bottom: calc(100% - 1px) puts 2 of the 3px on top of the drawer's own surface, the mismatch is visible there:
--glass-opacityis a runtime user setting (40-100%, default 80;routes/__root.tsx:171). Every other composer/drawer surface derives from it, and the only other opaque paints of--chat-composer-glass-surfaceare inside@supports not (backdrop-filter)fallbacks. Below 100% the seal reads as a solid strip over translucent glass.- The tint is dropped: the internal top drawer always sets
data-variant="info"|"warning"(ChatComposer.tsx:2979) and banner-stack alerts set error/warning/success, each of which layers--chat-composer-attached-tintonto the drawer surface.
Consider composing the strip from the same tokens - the glass-opacity mix plus the drawer tint - and giving it its own backdrop-filter, so any row it loses at its own top edge lands on the drawer's already-blurred surface, keeping the opaque paint only for the @supports not fallback. The tint currently lives on the drawer element, so it needs hoisting to the shell (next to --chat-composer-attachment-seal-shade) for the strip to read it.
- var(--chat-composer-glass-surface);+ color-mix(in srgb, var(--chat-composer-glass-surface) var(--glass-opacity), transparent);+ -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));+ backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));Posted via Macroscope — UI Consistency
69cbd4c to
cb2663dCompareDismissing prior approval to re-evaluate cb2663d
There was a problem hiding this comment.
One finding on the attachment seal: the repainted strip does not reproduce the glass composition of the surfaces it covers, so it becomes visible as an opaque band under non-default glass opacity and on tinted banner variants.
Posted via Macroscope — UI Consistency
Uh oh!
There was an error while loading. Please reload this page.
cb2663d to
36fe1b9CompareThere was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 36fe1b9. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
36fe1b9 to
b6a13d1Comparevitalyiegorov
commented
Aug 29, 2026
On the open visual-consistency question — configurable glass opacity and the alert tint variants across the overlap. The bleed does not introduce a new surface. It extends the drawer's own masked surface one CSS px further down, into a strip the composer's surface already covers, so the two overlap there instead of leaving a row painted by neither. That means the only thing that can differ is a double composite of two semi-transparent surfaces over one CSS px. Measured every state that can vary across the overlap — glass opacity 100 / 80 (default) / 40 %, light and dark, and the default / info / warning / error banner tints:
Rows above the seam are bit-identical in every combination. Only the two device rows at the seam change, and there they go from showing chat text through the gap to the surface colour. The residual at 40 % is the expected double composite, and it lands strictly closer to the intended surface colour than the leak it replaces. Worth stating plainly: this gives back 1 px of the 17 px the overlap lost in #8083. That is the cost of the fix, and I did not find a way to seal the seam without it — a border, an inset shadow, and a token-matched strip all still leaked, and an outset shadow sealed it but broke surface parity far worse (178–222 / 255). |
b6a13d1 to
2497405CompareA row about one device pixel tall at the join between an attached banner and the composer was painted by neither surface, so the chat behind it showed through crisp and unblurred. The row is the drawer's own last masked row. Chromium drops the final device-pixel row of a filtered backdrop when the mask cut-off lands off the pixel grid, and the composer's surface begins exactly at that cut-off, so nothing covers it. Bleeding the cut-off one pixel past the seam lets the drawer paint that row itself. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2497405 to
7a8c97eComparevitalyiegorov
commented
Aug 31, 2026
Closing — no longer reproducible on recent nightlies. If the seam leak resurfaces, the root-cause analysis and per-DPR measurements in this thread should spare the next person the diagnosis. |


Closes#8546.
What Changed
At the join between an attached banner and the composer, a row one device pixel tall was painted by neither surface, so the chat behind it showed through crisp and unblurred. The drawer's mask cut-off now bleeds one pixel past the seam, so the drawer paints that row itself.
One rule, one file. Stacked banners get the same repair for free, since they share the mask.
Why
The lost row is the drawer's own last masked row — measured at DPR 1.25 it sits at device offset −1.00 relative to the composer's top edge. Chromium drops the final device-pixel row of a filtered backdrop when the mask cut-off lands off the pixel grid, and the composer's surface begins exactly at that cut-off, so nothing covers it.
That rules out anything that paints at offset ≥ 0. Measured over 224 configurations (7 device pixel ratios × 8 sub-pixel phases × ancestor transform × light/dark):
maintodayborder-top, orbox-shadow: inset 0 1px 0, on the composerbackdrop-filterThis finishes #8083, which fixed the same symptom on this same mask by dropping
before:mask-noneso the overlap is masked again. One device row survived that fix — the cut-off row itself — and that is what this closes.The
- 1pxis absolute rather than scaled with the1remin--chat-composer-attachment-overlap: it repairs a device-pixel rounding artefact, not a layout distance, so it must not grow with interface font size. 2px is no better (also 0 leaks), so 1px is the minimum.Cost: surface parity is ≤7/255 worst case (dark,
--glass-opacity: 40%), ≤4 at the 80% default, 0 at 100%. Rows above the seam are bit-identical.UI Changes
Reported on the macOS desktop app — a line of chat text visible through the seam:
Re-verified against
main@053affbed, 34 commits after this branch's base: the fix cherry-picks with no conflict and every selector it relies on is unchanged. Measured in the running app at DPR 2, dark, with a real attached banner and high-contrast content behind the seam, toggling only the mask cut-off on one page instance:The mean-50.5-against-peak-77 spread is the artifact: bright content punching through. Afterwards those rows read flat. Exactly two device rows change, which is the 1 CSS px at DPR 2.
Checklist
Built with Claude Fable 5 and Claude Opus 5 in the Claude Code harness.
🤖 Generated with Claude Code
Note
Low Risk
Single-file CSS mask tweak for composer chrome; no logic, data, or security surface changes.
Overview
Fixes a 1 device-pixel leak at the join between attached chat banners (drawers) and the composer, where unblurred chat content could show through because neither the masked glass pseudo-element nor the composer surface painted that row.
The attached drawer
::beforemask cut-off now usescalc(var(--chat-composer-attachment-overlap) - 1px)instead of the overlap value directly, so the masked backdrop bleeds 1px past the seam and Chromium still paints the last filtered row. A short comment documents the browser rounding behavior. Stacked banners pick up the same fix via the shared selector inindex.css.Reviewed by Cursor Bugbot for commit 7a8c97e. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Fix 1px gap at composer-attachment seam in backdrop mask
Shifts the
-webkit-mask-imageandmask-imagelinear-gradient cut-offs by 1px usingcalc(var(--chat-composer-attachment-overlap) - 1px)in index.css. This creates a 1px bleed so the backdrop covers a device-pixel row that Chromium was leaving transparent at the seam.Macroscope summarized 7a8c97e.