diff --git a/.planning/phases/17-chat-planning/17-SPEC.md b/.planning/phases/17-chat-planning/17-SPEC.md
new file mode 100644
index 0000000..a71208c
--- /dev/null
+++ b/.planning/phases/17-chat-planning/17-SPEC.md
@@ -0,0 +1,112 @@
+# Phase 17: Chat & Planning — Specification
+
+**Created:** 2026-05-17
+**Ambiguity score:** 0.13 (gate: ≤ 0.20)
+**Requirements:** 6 locked
+
+## Goal
+
+Restyle the discussion view and planning page using design system components so both surfaces are visually consistent with the Phase 15–16 restyled tablos, with own-vs-others message alignment and date-grouped planning events.
+
+## Background
+
+Phases 15–16 restyled the dashboard and tablo-detail surfaces using the design system (`ui.Card`, `.overview-section`, `.project-card`, CSS tokens). The discussion view (`backend/templates/discussion.templ`) and planning page (`backend/templates/planning.templ`) were not touched and remain visually inconsistent: they use raw inline Tailwind classes with no card surfaces or overview-section structure.
+
+Current gaps:
+- **Discussion**: `DiscussionMessageRow` renders identical flat rows for all messages. `DiscussionMessageView` has no `IsOwn` field. The SSE stream handler (`DiscussionMessageFromRow`) also omits own-user context.
+- **Planning**: `PlanningPage` uses a raw `
` list with no overview-section heading. `PlanningEventRow` has `DateLabel string` but no day-separator logic. Events are not grouped under date headers.
+
+## Requirements
+
+1. **Discussion message alignment**: Own messages render right-aligned with a distinct background; others render left-aligned.
+ - Current: All `DiscussionMessageRow` items are identical flat rows — no user-context field exists in `DiscussionMessageView`
+ - Target: `DiscussionMessageView` gains an `IsOwn bool` field; `DiscussionMessagesFromRows` accepts a current-user ID parameter to set it; the template renders own messages in a right-aligned bubble (e.g. `bg-blue-50`/`bg-slate-50`) and others left-aligned
+ - Acceptance: Viewing a discussion where the signed-in user sent some messages shows own messages right-aligned with a different background; other users' messages are left-aligned
+
+2. **SSE stream own-message alignment**: New messages posted via SSE also render right-aligned for the posting user.
+ - Current: `DiscussionMessageFromRow` (used by the stream handler) has no user context; new messages stream without alignment differentiation
+ - Target: The SSE/stream path that renders a new `DiscussionMessageRow` also sets `IsOwn = true` for the posting user's message (the stream handler already knows the author)
+ - Acceptance: Posting a new message via the composer results in the new message row appearing right-aligned in the thread immediately (without reload)
+
+3. **Discussion card surface**: The message list container uses a card-style surface consistent with Phase 16 tab panels.
+ - Current: Messages container is a plain `div.rounded.border.border-slate-200.bg-white`
+ - Target: Messages container uses the `.ui-card` CSS class (or equivalent design token surface) so border-radius, shadow, and background match the Phase 16 card surfaces
+ - Acceptance: The discussion message container visually matches the card surfaces in the files and events tabs of the tablo-detail page
+
+4. **Planning overview-section heading**: The planning page header uses the `.overview-section` + `.overview-section-heading` layout classes.
+ - Current: Page header is a plain `` + nested flex div with inline Tailwind classes
+ - Target: The "Planning" heading and date-range label are wrapped in `.overview-section` / `.overview-section-heading` elements, matching the style used in `tablos.templ` and the detail page
+ - Acceptance: The Planning page heading visually matches the heading style on the dashboard and tablo-detail pages
+
+5. **Planning day separators**: Events are grouped under date-separator headers rather than showing the date as a column in each row.
+ - Current: Events render as a flat list; `DateLabel` is a column inside each `
- `
+ - Target: A `PlanningShowDaySeparator` helper compares consecutive event `DateLabel` strings; where the date changes, a day-separator element is rendered above the first event for that date; `DateLabel` is removed from the event row body (it's now the separator header)
+ - Acceptance: A 14-day window with events on 3 different dates renders 3 date separator headers, each followed by its events; events on the same date appear under one separator
+
+6. **Handler tests pass unchanged**: All existing Go tests for discussion and planning handlers continue to pass without modification.
+ - Current: `go test ./...` passes; handler tests reference `DiscussionMessagesFromRows`, `NewPlanningAgenda`, and related functions
+ - Target: Any function signature changes (e.g. adding `currentUserID uuid.UUID` to `DiscussionMessagesFromRows`) are reflected at all call sites; no test is deleted or skipped to make tests pass
+ - Acceptance: `go test ./... -count=1` exits 0 after all Phase 17 changes
+
+## Boundaries
+
+**In scope:**
+- `DiscussionMessageView` — add `IsOwn bool` field
+- `DiscussionMessagesFromRows` — add `currentUserID uuid.UUID` parameter; set `IsOwn` by comparing to each message's author
+- `DiscussionMessageFromRow` — add `isOwn bool` parameter for the SSE path
+- `DiscussionTabFragment` / `DiscussionMessageRow` — restyle as right/left-aligned chat bubbles; message container adopts `.ui-card` surface
+- `PlanningPage` / `PlanningEventListItem` — adopt `.overview-section` heading; add `PlanningShowDaySeparator` helper; add day-separator element; remove `DateLabel` from event row body
+- All call sites for changed function signatures (handlers, test files where necessary to compile)
+- Browser walkthrough confirming visual consistency on both pages
+
+**Out of scope:**
+- Avatars or profile pictures in message rows — not in v3.0 requirements
+- Message reactions or reply threading — not in v3.0 requirements
+- Planning page sorting or filtering controls — navigation controls already exist; no new controls
+- New database schema, migrations, or sqlc queries — restyling only
+- New routes or HTTP handlers — no new endpoints
+
+## Constraints
+
+- All Go handler tests must pass unchanged (or with compile-only call-site updates, no logic changes)
+- `PlanningShowDaySeparator` uses string comparison on `DateLabel` — no `Date time.Time` field added to `PlanningEventRow`
+- Design tokens and CSS classes from the existing design system only — no new CSS files or utility classes introduced
+- No new JavaScript added — HTMX + existing Sortable.js only
+
+## Acceptance Criteria
+
+- [ ] Discussion messages from the signed-in user render right-aligned with a distinct background color
+- [ ] Discussion messages from other users render left-aligned
+- [ ] Posting a new message via the composer renders the new row right-aligned immediately (SSE path)
+- [ ] Discussion message container uses `.ui-card` surface (border-radius + shadow match Phase 16 tab panels)
+- [ ] Planning page heading uses `.overview-section` / `.overview-section-heading` layout classes
+- [ ] Planning events in a 14-day window are grouped under date-separator headers (not shown as a date column in each row)
+- [ ] `go test ./... -count=1` exits 0 after all changes
+- [ ] Browser walkthrough: both discussion and planning views look visually consistent with Phase 15–16 restyled surfaces
+
+## Ambiguity Report
+
+| Dimension | Score | Min | Status | Notes |
+|--------------------|-------|------|--------|----------------------------------------------------|
+| Goal Clarity | 0.92 | 0.75 | ✓ | Chat bubble style and planning grouping locked |
+| Boundary Clarity | 0.90 | 0.70 | ✓ | Explicit in/out-of-scope confirmed by user |
+| Constraint Clarity | 0.80 | 0.65 | ✓ | Test constraint, string-compare grouping, no new CSS|
+| Acceptance Criteria| 0.82 | 0.70 | ✓ | 8 pass/fail checkboxes |
+| **Ambiguity** | 0.13 | ≤0.20| ✓ | |
+
+## Interview Log
+
+| Round | Perspective | Question summary | Decision locked |
+|-------|------------------|-------------------------------------------|-------------------------------------------------------------------|
+| 1 | Researcher | How to differentiate own vs. others? | Alignment (own right, others left) — classic chat bubble layout |
+| 1 | Researcher | Event grouping on planning page? | Group by date with day separators |
+| 2 | Researcher | How to thread own-message detection? | Add `IsOwn bool` to `DiscussionMessageView` |
+| 2 | Simplifier | String comparison vs. Date field for planning? | String comparison on DateLabel — no data model field added |
+| 3 | Boundary Keeper | Does SSE stream path need own-alignment? | Yes — stream handler also sets IsOwn for posting user |
+| 3 | Boundary Keeper | What's explicitly out of scope? | Avatars, reactions/threading, planning filter controls excluded |
+
+---
+
+*Phase: 17-chat-planning*
+*Spec created: 2026-05-17*
+*Next step: /gsd-discuss-phase 17 — implementation decisions (bubble CSS, card wrapping, separator markup)*