authorgravatar for me@t3.ggTheo Browne <me@t3.gg> 2026-08-07 04:27:31-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-07 01:27:31-07:00
log3ffe84f9688e22afea531988807a1c7faeccdc37
treea8b33f1a995452c2d8e4d79d4fca4c0a1ee38fe8
parent220efad62b7ce7b9ee4befff75edb0753467df0a
signature Signed by PGP key B5690EEEBB952194

fix(web): stop the sidebar "Working" label from pulsing (#5580)

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>

2 files changed, 8 insertions(+), 20 deletions(-)

apps/web/src/components/SidebarV2.tsx+8-4
...@@ -502,13 +502,17 @@ const SidebarV2Row = memo(function SidebarV2Row(props: {...@@ -502,13 +502,17 @@ const SidebarV2Row = memo(function SidebarV2Row(props: {
502 ? {502 ? {
503 label: "Working",503 label: "Working",
504 icon: "working" as const,504 icon: "working" as const,
505 className:505 // No shimmer: a label that animates forever is noise in a sidebar
506 "animate-sidebar-working-text text-sky-600 motion-reduce:animate-none dark:text-sky-400",506 // full of them (and repaints every vsync on high-refresh displays).
507 // Working is a background state, so it rests at the dim end of what
508 // the old pulse cycled through; only the thread you have open gets
509 // the label at full strength.
510 className: cn("text-sky-600 dark:text-sky-400", !props.isActive && "opacity-75"),
507 }511 }
508 : status === "monitoring"512 : status === "monitoring"
509 ? {513 ? {
510 // Steady label, no duty-cycled shimmer: monitoring is calm514 // Monitoring is calm background presence, not active progress
511 // background presence, not active progress (monitoring-pill D6).515 // (monitoring-pill D6), so it keeps the label at full strength.
512 label: "Monitoring",516 label: "Monitoring",
513 icon: null,517 icon: null,
514 className: "text-sky-600 dark:text-sky-400",518 className: "text-sky-600 dark:text-sky-400",
apps/web/src/index.css-16
...@@ -146,7 +146,6 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil...@@ -146,7 +146,6 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
146 compositor updates discrete frames instead of every vsync. */146 compositor updates discrete frames instead of every vsync. */
147 --animate-status-pulse: status-pulse 2s infinite;147 --animate-status-pulse: status-pulse 2s infinite;
148 --animate-status-ping: status-ping 2s infinite;148 --animate-status-ping: status-ping 2s infinite;
149 --animate-sidebar-working-text: sidebar-working-text 3.4s infinite;
150 --color-warning-foreground: var(--warning-foreground);149 --color-warning-foreground: var(--warning-foreground);
151 --color-warning: var(--warning);150 --color-warning: var(--warning);
152 --color-success-foreground: var(--success-foreground);151 --color-success-foreground: var(--success-foreground);
...@@ -223,21 +222,6 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil...@@ -223,21 +222,6 @@ html[data-mobile-composer-route-transition="true"]::view-transition-old(t3-mobil
223 scale: 2;222 scale: 2;
224 }223 }
225 }224 }
226 @keyframes sidebar-working-text {
227 0%,
228 36% {
229 opacity: 1;
230 animation-timing-function: steps(10);
231 }
232 50%,
233 86% {
234 opacity: 0.75;
235 animation-timing-function: steps(10);
236 }
237 100% {
238 opacity: 1;
239 }
240 }
241}225}
242226
243@layer base {227@layer base {