diff --git a/apps/web/src/components/ChatView.tsx b/apps/web/src/components/ChatView.tsx
index f4561188df0cc..35bbe28c21ecc 100644
--- a/apps/web/src/components/ChatView.tsx
+++ b/apps/web/src/components/ChatView.tsx
@@ -3494,7 +3494,7 @@ export default function ChatView(props: ChatViewProps) {
className={
isDraftHeroState
? "pointer-events-none absolute inset-0 z-20 flex items-center [@media(max-height:34rem)]:items-end"
- : "pointer-events-none absolute inset-x-0 bottom-0 z-20 pt-1.5 sm:pt-2"
+ : "pointer-events-none absolute inset-x-0 bottom-0 z-20 composer-overlay-fade pt-1.5 sm:pt-2"
}
>
diff --git a/apps/web/src/index.css b/apps/web/src/index.css
index 40daa0da7dcc8..f3a1aa852f19f 100644
--- a/apps/web/src/index.css
+++ b/apps/web/src/index.css
@@ -523,6 +523,12 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
var(--app-scrollbar-width) 100%;
}
+/* The composer overlay spans the timeline, so stop short of its scrollbar lane. */
+@utility composer-overlay-fade {
+ background: linear-gradient(to bottom, transparent, var(--background) 50%) left /
+ calc(100% - var(--app-scrollbar-width)) 100% no-repeat;
+}
+
/* Stage-channel art needs a mask and pseudo-element gradient, so keep the
behavior composable without tying it to the global components layer. */
@utility sidebar-stage-backdrop {