diff --git a/docs/superpowers/plans/2026-07-03-leptos-messages-phase3.md b/docs/superpowers/plans/2026-07-03-leptos-messages-phase3.md
new file mode 100644
index 0000000..b52c04c
--- /dev/null
+++ b/docs/superpowers/plans/2026-07-03-leptos-messages-phase3.md
@@ -0,0 +1,556 @@
+# Phase 3: Messages Feature — Implementation Plan
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** Implement the complete Messages panel — message list with infinite scroll, user-grouped cards, Discord emoji rendering, AI status filtering, full-text search, image grid, reanalyze actions, and WS-driven real-time updates.
+
+**Architecture:** Leptos signals + Resources for state and data fetching. `web-sys` `IntersectionObserver` for infinite scroll sentinel. `ws::context::WsContext` drives real-time message_created/updated/deleted/analyzed events. Components follow the existing `ui/*` + `layout/*` patterns. CSS classes defined in Phase 2's `app.css`.
+
+**Tech Stack:** Leptos 0.7 CSR, `gloo-net` fetch, `web-sys` (IntersectionObserver, console), `serde`/`serde_json`, `lucide-leptos` icons, plain CSS.
+
+## Global Constraints
+
+- Branch: `leptos-rewrite` at `/mnt/code/bete/.worktrees/leptos-rewrite/`
+- Use `use leptos::prelude::*;` (NOT `use leptos::*;`)
+- Combine duplicate `class=` attributes into single `format!()` strings
+- `#[serde(rename_all = "camelCase")]` on structs where backend sends camelCase
+- All timestamps are `i64` (millis since epoch), not strings
+- Rust types must match the JSON wire format from backend exactly
+
+---
+
+## File Structure
+
+```
+services/frontend-leptos/frontend/src/
+├── features/
+│ ├── mod.rs # mod messages;
+│ └── messages/
+│ ├── mod.rs # MessagesPanel component
+│ ├── components/
+│ │ ├── mod.rs # mod message_feed message_card image_grid;
+│ │ ├── message_feed.rs # Infinite scroll, user grouping
+│ │ ├── message_card.rs # User-grouped message card
+│ │ └── image_grid.rs # Masonry-like image grid
+│ └── hooks/
+│ ├── mod.rs # mod use_messages;
+│ └── use_messages.rs # Data fetching, pagination, reanalyze
+```
+
+**Files to modify:**
+- `services/frontend-leptos/frontend/src/lib.rs` — add `pub mod features;`
+- `services/frontend-leptos/frontend/src/app.rs` — wire `MessagesPanel` as default tab content
+- `services/frontend-leptos/frontend/src/app.css` — add message-specific CSS classes
+
+**Files to create (8 new):**
+- `services/frontend-leptos/frontend/src/features/mod.rs`
+- `services/frontend-leptos/frontend/src/features/messages/mod.rs`
+- `services/frontend-leptos/frontend/src/features/messages/components/mod.rs`
+- `services/frontend-leptos/frontend/src/features/messages/components/message_feed.rs`
+- `services/frontend-leptos/frontend/src/features/messages/components/message_card.rs`
+- `services/frontend-leptos/frontend/src/features/messages/components/image_grid.rs`
+- `services/frontend-leptos/frontend/src/features/messages/hooks/mod.rs`
+- `services/frontend-leptos/frontend/src/features/messages/hooks/use_messages.rs`
+
+---
+
+### Task 1: Module skeleton + use_messages hook
+
+**Files:**
+- Create: `services/frontend-leptos/frontend/src/features/mod.rs`
+- Create: `services/frontend-leptos/frontend/src/features/messages/mod.rs`
+- Create: `services/frontend-leptos/frontend/src/features/messages/components/mod.rs`
+- Create: `services/frontend-leptos/frontend/src/features/messages/hooks/mod.rs`
+- Create: `services/frontend-leptos/frontend/src/features/messages/hooks/use_messages.rs`
+- Modify: `services/frontend-leptos/frontend/src/lib.rs` — add `pub mod features;`
+- Modify: `services/frontend-leptos/frontend/src/features/messages/mod.rs` — add placeholder `MessagesPanel` component
+
+**Interfaces:**
+- Consumes: `shared_types::message::{MessageRecord, PageResult}` from shared-types crate, `api::messages::{get_messages, search_messages, reanalyze_message, reanalyze_batch}` from API client
+- Produces: `MessagesState` struct returned by `use_messages()` that later tasks wire into `MessagesPanel`
+
+**Step 1: Create module files**
+
+`services/frontend-leptos/frontend/src/features/mod.rs`:
+```rust
+pub mod messages;
+```
+
+`services/frontend-leptos/frontend/src/features/messages/hooks/mod.rs`:
+```rust
+pub mod use_messages;
+```
+
+`services/frontend-leptos/frontend/src/features/messages/components/mod.rs`:
+```rust
+pub mod message_feed;
+pub mod message_card;
+pub mod image_grid;
+```
+
+`services/frontend-leptos/frontend/src/features/messages/mod.rs` (placeholder for now):
+```rust
+use leptos::prelude::*;
+
+pub mod components;
+pub mod hooks;
+
+#[component]
+pub fn MessagesPanel() -> impl IntoView {
+ view! {
+
"Messages Panel (loading...)"
+ }
+}
+```
+
+**Step 2: Create use_messages hook**
+
+`services/frontend-leptos/frontend/src/features/messages/hooks/use_messages.rs`:
+
+This hook ports the React `useMessages` logic. It manages:
+- `messages: RwSignal>` — the message list, sorted by created_at desc
+- `loading: Signal` — loading state
+- `loading_more: RwSignal` — infinite scroll loading
+- `cursor: RwSignal