diff --git a/packages/app/CONTEXT.md b/packages/app/CONTEXT.md
index 53a5f5e8f0..7a8bf1bde4 100644
--- a/packages/app/CONTEXT.md
+++ b/packages/app/CONTEXT.md
@@ -92,6 +92,34 @@ It persists until onboarding is complete and then disappears; it never gates the
_Avoid_: Onboarding modal, wizard (the wizard is the conversational interview; the nudge
only surfaces its state), setup wall
+### Activity vocabulary
+
+**Activity**:
+The one semantic state set every status surface speaks — session dots (tab strip,
+sessions dropdown, sidebar, home), run status (run window, run view), health dots
+(connection, MCP, LSP, server, vault), build status, and status banners. Five roles,
+each a `--activity-*` token in `src/design-polish.css` (solid dot colour plus a `-soft`
+fill) aliasing the theme's v2 state tokens so light and dark move together:
+
+| Role | Colour | Means |
+| --- | --- | --- |
+| `running` | blue | in progress — working, solving, pending, validating |
+| `attention` | amber | waiting on you — permission, question, needs auth, expired, drift, stalled |
+| `success` | green | done-unread, healthy, finished |
+| `error` | red | failed, unreachable |
+| `idle` | grey | done-seen, aborted, stopped, disabled |
+
+A session's tab status ranks **error > attention > running > done-unread > idle**. Running
+dots share one reduced-motion-aware pulse (`.amc-activity-pulse`). Colour is never the
+only signal: every status dot carries an accessible label or sits beside text that
+names the state.
+
+**Yellow never encodes a state.** Yellow is brand and selection only (the `--accent`
+family). Amico's presence — the thought-rail harmonic dot, the working lane, the
+thinking wave, the mark — is brand, not status, and keeps the accent.
+_Avoid_: yellow "running", gold/amber warning edges from the theme as an attention
+colour, the agent identity tint on a status spinner, raw hex status colours
+
## Relationships
- The **Landing** is a **Chat**; the window never opens on anything else.
diff --git a/packages/app/src/components/connection-banner.tsx b/packages/app/src/components/connection-banner.tsx
index be54a988d9..8be6b59fe1 100644
--- a/packages/app/src/components/connection-banner.tsx
+++ b/packages/app/src/components/connection-banner.tsx
@@ -1,6 +1,7 @@
import { Show, createEffect, createSignal, onCleanup } from "solid-js"
import { useLanguage } from "@/context/language"
import { useServerSDK } from "@/context/server-sdk"
+import { ActivityDot } from "@opencode-ai/ui/amicode-activity"
// Amicode webview: a dead server (e.g. an opencode:build restart) used to read
// as an endless "thinking" wave — the event loop retries silently every 250ms.
@@ -64,12 +65,18 @@ export function ConnectionBanner() {
"border-radius": "var(--radius-full)",
"font-size": "12px",
"font-weight": 600,
- border: "1px solid var(--v2-border-border-base, #3c3c3c)",
- background: "var(--v2-background-bg-layer-01, #1e1e1e)",
- "box-shadow": "0 8px 24px rgba(0, 0, 0, 0.35)",
- color: down() ? "var(--v2-state-fg-warning, #d29922)" : "var(--v2-state-fg-success, #3fb950)",
+ display: "flex",
+ "align-items": "center",
+ gap: "var(--space-2)",
+ border: "1px solid var(--v2-border-border-base)",
+ background: "var(--v2-background-bg-layer-01)",
+ "box-shadow": "var(--elev-float)",
+ color: "var(--v2-text-text-base)",
}}
>
+ {/* activity dot: attention while the link is down, success once back.
+ The words carry the state; the dot is the at-a-glance colour. */}
+