authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-07-24 14:25:01+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-07-24 12:25:01+00:00
logece05087a70e94efcd57441337fa1249559362ba
tree7ddb5f0bbe25e83c82b6af4082b26e2e1199333b
parenta7ee3092c3c4383a65a16a51de7e0328d6e027c9
signature Signed by PGP key B5690EEEBB952194

[codex] Fix glass hover compositing artifacts (#4446)

Co-authored-by: codex <codex@users.noreply.github.com>

6 files changed, 29 insertions(+), 11 deletions(-)

apps/web/src/components/SidebarV2.tsx+5-3
...@@ -18,7 +18,6 @@ import {...@@ -18,7 +18,6 @@ import {
18 AlarmClockOffIcon,18 AlarmClockOffIcon,
19 CheckIcon,19 CheckIcon,
20 ChevronDownIcon,20 ChevronDownIcon,
21 ChevronRightIcon,
22 CircleAlertIcon,21 CircleAlertIcon,
23 CircleCheckIcon,22 CircleCheckIcon,
24 CircleDashedIcon,23 CircleDashedIcon,
...@@ -240,7 +239,11 @@ function SidebarV2ThreadTooltip({...@@ -240,7 +239,11 @@ function SidebarV2ThreadTooltip({
240 side="right"239 side="right"
241 align="start"240 align="start"
242 sideOffset={8}241 sideOffset={8}
243 className="dropdown-glass max-w-80 border-0! bg-[color-mix(in_srgb,var(--background)_var(--glass-opacity),transparent)] text-left whitespace-normal shadow-lg/10 before:hidden dark:shadow-none"242 className="dropdown-glass max-w-80 border-0! text-left whitespace-normal shadow-lg/10 before:hidden dark:shadow-none"
243 style={{
244 background:
245 "color-mix(in srgb, var(--popover) 18%, color-mix(in srgb, var(--popover) var(--glass-opacity), transparent))",
246 }}
244 >247 >
245 <div className="flex max-w-80 flex-col gap-2 p-2">248 <div className="flex max-w-80 flex-col gap-2 p-2">
246 <div className="whitespace-nowrap text-sm font-medium text-foreground">{thread.title}</div>249 <div className="whitespace-nowrap text-sm font-medium text-foreground">{thread.title}</div>
...@@ -652,7 +655,6 @@ const SidebarV2Row = memo(function SidebarV2Row(props: {...@@ -652,7 +655,6 @@ const SidebarV2Row = memo(function SidebarV2Row(props: {
652 // content; surface is reserved for interaction (hover, multi-select, route).655 // content; surface is reserved for interaction (hover, multi-select, route).
653 const rowSurfaceClassName = cn(656 const rowSurfaceClassName = cn(
654 "group/v2-row relative w-full cursor-pointer overflow-hidden rounded-md text-left outline-none select-none",657 "group/v2-row relative w-full cursor-pointer overflow-hidden rounded-md text-left outline-none select-none",
655 variant === "card" && "backdrop-blur-[16px]",
656 props.isActive658 props.isActive
657 ? "bg-sidebar-row-active text-sidebar-foreground"659 ? "bg-sidebar-row-active text-sidebar-foreground"
658 : isSelected660 : isSelected
apps/web/src/components/chat/ModelListRow.tsx+1-1
...@@ -51,7 +51,7 @@ export const ModelListRow = memo(function ModelListRow(props: {...@@ -51,7 +51,7 @@ export const ModelListRow = memo(function ModelListRow(props: {
51 contentClassName="flex w-full items-center gap-3"51 contentClassName="flex w-full items-center gap-3"
52 className={cn(52 className={cn(
53 "group relative w-full !min-w-0 max-w-full cursor-pointer rounded-md px-2 py-2.5 transition-[background-color,box-shadow,color]",53 "group relative w-full !min-w-0 max-w-full cursor-pointer rounded-md px-2 py-2.5 transition-[background-color,box-shadow,color]",
54 "data-highlighted:bg-muted/56 data-selected:bg-foreground/[0.08] data-selected:text-foreground data-selected:ring-0",54 "hover:bg-[color-mix(in_srgb,var(--popover)_90%,var(--foreground))] data-highlighted:bg-[color-mix(in_srgb,var(--popover)_90%,var(--foreground))] data-selected:bg-foreground/[0.08] data-selected:text-foreground data-selected:ring-0 [&[data-highlighted][data-selected]]:bg-[color-mix(in_srgb,var(--popover)_90%,var(--foreground))]",
55 props.disabledReason &&55 props.disabledReason &&
56 "data-disabled:pointer-events-auto data-disabled:cursor-not-allowed data-disabled:hover:bg-transparent",56 "data-disabled:pointer-events-auto data-disabled:cursor-not-allowed data-disabled:hover:bg-transparent",
57 )}57 )}
apps/web/src/components/chat/ModelPickerContent.tsx+1-1
...@@ -521,7 +521,7 @@ export const ModelPickerContent = memo(function ModelPickerContent(props: {...@@ -521,7 +521,7 @@ export const ModelPickerContent = memo(function ModelPickerContent(props: {
521 return (521 return (
522 <TooltipProvider delay={0}>522 <TooltipProvider delay={0}>
523 <div523 <div
524 className="dropdown-glass model-picker-surface relative flex h-screen max-h-96 w-screen max-w-100 flex-row overflow-hidden rounded-lg text-popover-foreground"524 className="dropdown-glass model-picker-surface relative flex h-screen max-h-96 w-screen max-w-100 flex-row overflow-hidden rounded-lg text-popover-foreground [clip-path:inset(0_round_var(--radius-lg))]"
525 data-model-picker-content="true"525 data-model-picker-content="true"
526 >526 >
527 {/* Sidebar */}527 {/* Sidebar */}
apps/web/src/components/chat/ModelPickerSidebar.tsx+2-2
...@@ -125,7 +125,7 @@ export const ModelPickerSidebar = memo(function ModelPickerSidebar(props: {...@@ -125,7 +125,7 @@ export const ModelPickerSidebar = memo(function ModelPickerSidebar(props: {
125 render={125 render={
126 <button126 <button
127 className={cn(127 className={cn(
128 "relative isolate flex w-full cursor-pointer aspect-square items-center justify-center rounded-md transition-colors hover:bg-muted",128 "relative isolate flex w-full cursor-pointer aspect-square items-center justify-center rounded-md transition-colors hover:bg-[color-mix(in_srgb,var(--popover)_90%,var(--foreground))] focus-visible:bg-[color-mix(in_srgb,var(--popover)_90%,var(--foreground))] focus-visible:outline-none",
129 )}129 )}
130 onClick={() => handleSelect("favorites")}130 onClick={() => handleSelect("favorites")}
131 type="button"131 type="button"
...@@ -172,7 +172,7 @@ export const ModelPickerSidebar = memo(function ModelPickerSidebar(props: {...@@ -172,7 +172,7 @@ export const ModelPickerSidebar = memo(function ModelPickerSidebar(props: {
172 <button172 <button
173 data-model-picker-provider={entry.instanceId}173 data-model-picker-provider={entry.instanceId}
174 className={cn(174 className={cn(
175 "relative isolate flex w-full cursor-pointer aspect-square items-center justify-center rounded-md transition-colors hover:bg-muted",175 "relative isolate flex w-full cursor-pointer aspect-square items-center justify-center rounded-md transition-colors hover:bg-[color-mix(in_srgb,var(--popover)_90%,var(--foreground))] focus-visible:bg-[color-mix(in_srgb,var(--popover)_90%,var(--foreground))] focus-visible:outline-none",
176 isDisabled && "opacity-50 cursor-not-allowed hover:bg-transparent",176 isDisabled && "opacity-50 cursor-not-allowed hover:bg-transparent",
177 )}177 )}
178 data-provider-accent-color={entry.accentColor}178 data-provider-accent-color={entry.accentColor}
apps/web/src/components/chat/ProviderModelPicker.tsx+2-2
...@@ -187,8 +187,8 @@ export const ProviderModelPicker = memo(function ProviderModelPicker(props: {...@@ -187,8 +187,8 @@ export const ProviderModelPicker = memo(function ProviderModelPicker(props: {
187 </PopoverTrigger>187 </PopoverTrigger>
188 <PopoverPopup188 <PopoverPopup
189 align="start"189 align="start"
190 className="border-0 bg-transparent p-0 shadow-none before:hidden [--viewport-inline-padding:0]"190 className="border-0 bg-transparent p-0 shadow-none before:hidden [-webkit-backdrop-filter:none]! [--viewport-inline-padding:0] [backdrop-filter:none]!"
191 viewportClassName="rounded-lg !overflow-hidden p-0 [clip-path:inset(0_round_var(--radius-lg))]"191 viewportClassName="rounded-lg !overflow-hidden p-0"
192 >192 >
193 <ModelPickerContent193 <ModelPickerContent
194 activeInstanceId={activeInstanceId}194 activeInstanceId={activeInstanceId}
apps/web/src/index.css+18-2
...@@ -574,7 +574,6 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil...@@ -574,7 +574,6 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
574 --alert-glass-tint: var(--warning);574 --alert-glass-tint: var(--warning);
575 }575 }
576576
577 .dropdown-glass,
578 .dialog-glass {577 .dialog-glass {
579 background: color-mix(in srgb, var(--background) var(--glass-opacity), transparent);578 background: color-mix(in srgb, var(--background) var(--glass-opacity), transparent);
580 -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));579 -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturation));
...@@ -588,6 +587,19 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil...@@ -588,6 +587,19 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
588 }587 }
589588
590 .dropdown-glass {589 .dropdown-glass {
590 /*
591 * Elevated glass needs a denser tint than broad ambient surfaces. Nesting
592 * the user-controlled mix inside an 18% popover tint preserves the full
593 * opacity setting range (40% -> 51%, 80% -> 84%, 100% -> 100%) while
594 * keeping high-contrast page content from blooming through menus.
595 */
596 background: color-mix(
597 in srgb,
598 var(--popover) 18%,
599 color-mix(in srgb, var(--popover) var(--glass-opacity), transparent)
600 );
601 -webkit-backdrop-filter: blur(var(--glass-blur));
602 backdrop-filter: blur(var(--glass-blur));
591 border: 1px solid color-mix(in srgb, var(--foreground) 10%, transparent);603 border: 1px solid color-mix(in srgb, var(--foreground) 10%, transparent);
592 box-shadow: 0 16px 40px -18px rgb(0 0 0 / 55%);604 box-shadow: 0 16px 40px -18px rgb(0 0 0 / 55%);
593 }605 }
...@@ -602,7 +614,11 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil...@@ -602,7 +614,11 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
602 }614 }
603615
604 .dark .model-picker-surface.model-picker-surface {616 .dark .model-picker-surface.model-picker-surface {
605 background: color-mix(in srgb, var(--background) var(--glass-opacity), transparent);617 background: color-mix(
618 in srgb,
619 var(--popover) 18%,
620 color-mix(in srgb, var(--popover) var(--glass-opacity), transparent)
621 );
606 }622 }
607623
608 .dark .dialog-glass {624 .dark .dialog-glass {