diff --git a/docs/DOM-CHAT-PANEL.md b/docs/DOM-CHAT-PANEL.md
index 28b4634..7ba9aa5 100644
--- a/docs/DOM-CHAT-PANEL.md
+++ b/docs/DOM-CHAT-PANEL.md
@@ -1,18 +1,20 @@
# muse.ai Chat Panel & Sidechat DOM Reference
-> Captured live via CDP on `opm` browser (warp-opm netns, CDP 9440) on 2026-10-04.
-> Page: `https://muse.ai/`, title "Chat โ operator-main".
+> Originally captured live via CDP on `opm` browser (warp-opm netns, CDP 9440).
+> **Re-verified 2026-10-04** via CDP `Runtime.evaluate` on three nodes:
+> `opm` (warp-opm, CDP 9440), `muse` (warp-muse, CDP 9410), `pip` (warp-pip, CDP 9420).
+> Page: `https://muse.ai/`. Sections marked โ verified 2026-10-04,
+> ๐ง corrected, ๐ new since original capture.
> This is a development reference for reliable automation of the chat navigation panel
> and sidechat creation. Prefer these selectors over text matching.
---
-## 1. Chat Panel Switcher
+## 1. Chat Panel Switcher โ (with corrections)
**Selector:** `[data-testid="hatch-chat-switcher-trigger"]`
-The button that toggles the chat navigation panel open/closed. Always present in the DOM,
-top-left of the viewport.
+The button that toggles the chat navigation panel open/closed.
```html
```
-**Key facts:**
+**Key facts (โ verified 2026-10-04 on opm/muse/pip):**
| Property | Value |
|---|---|
| Tag | `BUTTON` |
-| Always in DOM | Yes (both panel states) |
+| In DOM on `https://muse.ai/` or `/thread/` | โ Yes (both panel states) |
+| In DOM on `/thread/new` stripped state | ๐ง **NO โ completely absent** (see ยง8) |
| Visible | Yes (`offsetParent !== null`) |
-| Position | Top-left: `x:84, y:12, w:82, h:36` |
+| Position | Top-left: `x:84, y:12, w:82, h:36` (exact on opm) |
| `aria-expanded` | **Not set** (`null`) โ do NOT use for state detection |
-| Visible text | `Chats` |
-| Screen-reader text | `Open chat and side chats` |
-| Icon | Hamburger menu (3 horizontal lines), not a chat bubble |
+| `data-pel-click` | `chat_threads_open_click` |
+| `data-slot` | `popover-anchor` |
+| Visible text | ๐ง **Active chat title, NOT static "Chats".** Shows e.g. `Heartbeat check for job scheduler`, `646 pip cross-operator coordination chat`; reads `Chats` only when main chat is active |
+| Screen-reader text | `Open chat and side chats` (+ `Unread chats` when unread exist) |
+| Icon | Hamburger menu (3 horizontal `` lines), not a chat bubble |
-**Parent chain (bottom-up, 4 levels):**
+**Parent chain (bottom-up, 4 levels):** โ unchanged
```
1. DIV [data-testid="hatch-chat-leading-controls"]
@@ -57,17 +63,42 @@ top-left of the viewport.
4. DIV (no testid) class="relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden"
```
-**Behavior:** The switcher **toggles**. Clicking when the panel is closed opens it;
-clicking when open closes it. Always check panel state before clicking โ never
-blind-click.
+**Behavior (โ verified atomically 2026-10-04):** The switcher **toggles in place โ
+no navigation**. Click when closed โ panel opens (shell `innerHTML` 0 โ 60667,
+rows 0 โ 26 on opm). Click when open โ panel closes. Always check panel state
+before clicking โ never blind-click. (An earlier non-atomic probe appeared to
+navigate; that was a race with the live heartbeat job driving the same browser โ
+see ยง9.)
**Child testids** (for reference):
- `[data-testid="hatch-chat-switcher-icon-knockout"]` โ icon wrapper span
- `[data-testid="hatch-chat-switcher-navigation-icon"]` โ the hamburger SVG span
+- ๐ `[data-testid="hatch-chat-switcher-unread-indicator"]` โ unread blue dot (see ยง1b)
---
-## 2. Sidechat Create Button ("New side chat")
+## 1b. Unread Indicator ๐ (verified 2026-10-04 on muse)
+
+When unread chats exist, the switcher gains:
+
+```html
+
+Unread chats
+```
+
+| Property | Value |
+|---|---|
+| Selector | `[data-testid="hatch-chat-switcher-unread-indicator"]` |
+| Visual | Blue dot (`bg-fill-blue`, 8px circle) overlaid on the switcher icon |
+| `aria-hidden` | `true` โ screen readers get the sr-only `Unread chats` text instead |
+| Programmatic signal | **Presence = unread chats exist.** Most reliable unread check |
+| Companion signal | `document.title` gains an `(N)` prefix, e.g. `(1) Chat โ operator-pip` |
+
+---
+
+## 2. Sidechat Create Button ("New side chat") โ
**Selector:** `[data-testid="hatch-chat-compose"]`
@@ -88,48 +119,31 @@ is OPEN.** This makes it the most reliable "panel is open and ready" signal.
```
-**Key facts:**
+**Key facts (โ verified):**
| Property | Value |
|---|---|
| Tag | `BUTTON` |
| In DOM when panel closed | **No** โ completely absent |
-| In DOM when panel open | Yes |
+| In DOM when panel open | โ Yes (`visible: offsetParent !== null`) |
| Text content | None (icon-only) |
-| `aria-label` | `New side chat` |
-| `title` | `New side chat` |
+| `aria-label` / `title` | `New side chat` |
| Icon | Plus sign (`+`), single SVG path |
-**Parent chain (bottom-up, 8 levels):**
+**Parent chain (bottom-up, 8 levels):** โ unchanged โ `SPAN.contents > DIV.group/nav-section`
+(header row: `H3 "Side chats"` + compose) inside the `SECTION` "Side chats".
-```
-1. SPAN (no testid) class="contents" โ direct wrapper
-2. DIV (no testid) class="group/nav-section flex w-full items-center"
- children: [H3 "Side chats", SPAN(contents) > BUTTON#compose]
-3. SECTION (no testid) class="flex flex-col" โ "Side chats" section
- children: [DIV(header: H3 + compose), DIV(chat list)]
-4. DIV (no testid) class="flex flex-col relative grow-1"
- children: [DIV[data-testid="hatch-thread-row"] (Main chat),
- SECTION (Side chats),
- DIV[data-testid="active-side-chat-load-more-sentinel"]]
-5. DIV (no testid) class="flex flex-col overflow-hidden relative z-0 overflow-y-auto overscroll-y-contain min-h-0 min-w-0 flex-1 px-3 pb-3"
-6. DIV (no testid) class="flex min-h-0 flex-1 flex-col"
-7. DIV (no testid) class="text-text-primary flex h-full min-h-0 w-full flex-col overflow-hidden"
-8. DIV (no testid) class="min-h-0 min-w-0 flex-1"
-```
-
-**Location in UI:** Inside the "Side chats" section header row, to the right of the
-`H3` "Side chats" collapsible heading.
-
-**What clicking does:** Creates a new sidechat. Browser navigates to
-`https://muse.ai/thread/new` (placeholder URL; the real thread UUID appears after
-the first message is sent or navigation settles).
+**What clicking does (โ verified 2026-10-04):** Creates a new sidechat draft.
+Browser navigates `https://muse.ai/` โ `https://muse.ai/thread/new`
+(placeholder URL; the real thread UUID appears after the first message is sent
+or navigation settles). **No sidechat exists server-side until a message is sent**
+โ navigating to `/thread/new` and back is harmless.
---
-## 3. Chat Navigation Panel Structure
+## 3. Chat Navigation Panel Structure โ
-### 3a. Panel shell (always in DOM)
+### 3a. Panel shell (always in DOM โ except ยง8)
**Selector:** `[data-testid="hatch-side-chats-panel-shell"]`
@@ -141,70 +155,50 @@ the first message is sent or navigation settles).
```
-| State | `innerHTML` | `innerText` |
+| State | `innerHTML` | `style.width` / computed |
|---|---|---|
-| Closed | `""` (empty string) | `""` |
-| Open | Full `