From e9b2e98d15324cbbd80bbbeff45cee82b2ba3d74 Mon Sep 17 00:00:00 2001
From: Naiyuan Qing <145280634+NevilleQingNY@users.noreply.github.com>
Date: Tue, 19 May 2026 16:12:41 +0800
Subject: [PATCH] =?UTF-8?q?fix(mobile):=20PulseDot=20uses=20brand=20colour?=
=?UTF-8?q?,=20not=20success=20=E2=80=94=20running=20=E2=89=A0=20completed?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The agent "is working" pulse dot (shown both in the issue Stack header
ambient badge and in the in-card AgentActivityRow "Working" row) was
backgroundColor #22c55e — that's the success/completed token. Reading
green here meant "task complete", which is the opposite of what the
animation represents.
Switch to THEME[scheme].brand (hsl(225 71% 58%)), matching:
- mobile RunRow status text: STATUS_CLASS.running = "text-brand"
- web agent-live-card.tsx:327:
- Apple HIG / shadcn semantic colour convention:
green = success, blue/brand = in-progress, red = destructive
One-line fix in pulse-dot.tsx; both call sites (AgentHeaderBadge top-right,
AgentActivityRow under the title) flip from green to brand blue
together. Docstring updated to spell out the rule for future readers:
DO NOT use success here.
Co-Authored-By: Claude Opus 4.7 (1M context)
---
apps/mobile/components/ui/pulse-dot.tsx | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/apps/mobile/components/ui/pulse-dot.tsx b/apps/mobile/components/ui/pulse-dot.tsx
index faaca184a..67dfa4855 100644
--- a/apps/mobile/components/ui/pulse-dot.tsx
+++ b/apps/mobile/components/ui/pulse-dot.tsx
@@ -1,15 +1,23 @@
/**
- * Slow green pulse — opacity oscillation on the UI thread via Reanimated's
- * `withRepeat`. 2-second cycle (1s in + 1s out). Same animation library as
- * comment-card.tsx, no new primitive.
+ * Slow brand-coloured pulse — opacity oscillation on the UI thread via
+ * Reanimated's `withRepeat`. 2-second cycle (1s in + 1s out). Same
+ * animation library as comment-card.tsx, no new primitive.
*
* Used by:
* - apps/mobile/components/issue/agent-activity-row.tsx (in-card "Working" row)
* - apps/mobile/components/issue/agent-header-badge.tsx (Stack header ambient badge)
*
- * Color is `#22c55e // success` (mobile tailwind.config.js:50). Inline hex
- * is the project's convention for animated backgroundColor values that
- * can't go through NativeWind className (see Reanimated style merging).
+ * Colour is the workspace `brand` token (mobile global.css:45 `--brand`),
+ * matching the "in-progress / live" semantic used everywhere else:
+ * `RunRow` paints dispatched/running state with `text-brand`, and web's
+ * `agent-live-card.tsx` uses `text-info` (also blue) for the same
+ * Loader2 spinner. **DO NOT** use the `success` token here — green means
+ * "completed", not "running" (Apple HIG / shadcn convention).
+ *
+ * Inline backgroundColor (rather than NativeWind className) is required
+ * because Reanimated's animated style merging doesn't compose cleanly
+ * with NativeWind class-derived styles; sibling `comment-card.tsx`
+ * follows the same pattern.
*/
import { useEffect } from "react";
import Animated, {
@@ -18,6 +26,8 @@ import Animated, {
withRepeat,
withTiming,
} from "react-native-reanimated";
+import { useColorScheme } from "@/lib/use-color-scheme";
+import { THEME } from "@/lib/theme";
interface Props {
/** Diameter in pt. Default 8 (matches the in-card row). */
@@ -25,6 +35,7 @@ interface Props {
}
export function PulseDot({ size = 8 }: Props) {
+ const { colorScheme } = useColorScheme();
const opacity = useSharedValue(0.3);
useEffect(() => {
opacity.value = withRepeat(
@@ -43,7 +54,7 @@ export function PulseDot({ size = 8 }: Props) {
width: size,
height: size,
borderRadius: size / 2,
- backgroundColor: "#22c55e", // success
+ backgroundColor: THEME[colorScheme].brand,
},
style,
]}