diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md
index 8776c63..75b146b 100644
--- a/.planning/ROADMAP.md
+++ b/.planning/ROADMAP.md
@@ -35,7 +35,7 @@ Make FamilySync configurable, administrable, and maintainable for real multi-mem
- [x] **Phase 14: Desktop E2E Coverage** - Add a Desktop Chrome Playwright profile + make the mobile-authored specs desktop-safe so the Phase 8 regression gate validates desktop, not just mobile (completed 2026-06-12)
- [x] **Phase 15: Doc-Only CI Skip + Markdown Lint** - Aggregate-gate the slow api/harness CI jobs so doc-only PRs to main merge without running them (no branch-protection deadlock), and add markdownlint to `fast-checks` so docs get a fast format+lint gate (promoted from backlog 999.17) (completed 2026-06-12)
- [x] **Phase 16: CI Dependency Audit, Security Checks & Image Hygiene** - Extend Gitea CI with outdated-dependency reporting + vulnerability audit + a baseline of additional security checks, and enforce the dev/prod image boundary so no dev-bypass, secret, or family data ships in published images (absorbs backlog 999.17); independent of the admin chain (completed 2026-06-13)
-- [ ] **Phase 17: UI Optimization & Polish** - Responsive/layout polish pass for the PWA — fix the long-standing phone-layout overlap where the fixed BottomTabBar covers the New Event FAB and the calendar colour legend, and sweep other small-viewport spacing/tap-target issues surfaced in use (CSS/layout only, no behaviour change)
+- [ ] **Phase 17: UI Optimization & Polish** - Phone-layout polish + branding + theme groundwork: fix the long-standing phone-layout overlap where the fixed BottomTabBar covers the New Event FAB and the colour legend (+ small-viewport sweep), finish the branding assets (real FamilySync logo into the BrandSlot seam + a complete favicon/PWA-icon set replacing the placeholder stubs), and restructure tokens.css into a themeable token layer (light-only groundwork for future dark mode). Shipped dark theme → backlog 999.20; broader styling refresh → backlog 999.21 (future milestone)
## Phase Details
@@ -394,10 +394,11 @@ Plans:
### Phase 17: UI Optimization & Polish
-**Goal**: A responsive/layout polish pass for the PWA so the phone (≤767px) layout has no fixed-chrome overlap and small-viewport spacing reads cleanly — starting with the long-standing BottomTabBar overlap that hides the New Event FAB and the calendar colour legend.
+**Goal**: A visual-identity & polish pass for the PWA spanning three workstreams: **(A) phone-layout polish** so the phone (≤767px) layout has no fixed-chrome overlap and small-viewport spacing reads cleanly — starting with the long-standing BottomTabBar overlap that hides the New Event FAB and the colour legend, plus a small-viewport sweep; **(B) branding assets** — generate a real FamilySync logo into the existing `BrandSlot` seam (`apps/pwa/src/components/BrandSlot.tsx`) and a complete favicon/PWA-icon set replacing the placeholder stubs in `apps/pwa/public/`; **(C) theme-token groundwork** — restructure `apps/pwa/src/styles/tokens.css` into a themeable semantic-token layer (swappable by `data-theme`/`prefers-color-scheme`), light staying the only shipped theme, so a future dark theme is cheap.
**Mode:** standard
-**Depends on**: Nothing structural (CSS/layout only). Best sequenced after Phase 10 merges (the BottomTabBar gained an Admin tab and the new SetupBanner adds top pressure on phone), but otherwise independent of the admin chain.
-**Requirements**: TBD (UI/UX polish — define/promote in discuss-phase)
+**Depends on**: Nothing structural (CSS/layout + assets only). Best sequenced after Phase 10 merges (the BottomTabBar gained an Admin tab and the new SetupBanner adds top pressure on phone), but otherwise independent of the admin chain.
+**Requirements**: TBD (UI/UX polish + branding — define/promote in plan-phase; decisions captured in 17-CONTEXT.md)
+**Scope boundary (set in `/gsd-discuss-phase 17`, 2026-06-17):** Workstream C ships token groundwork **only** — no dark palette, no theme toggle (→ backlog **999.20**). A broader "modern styling" visual refresh is **out of scope** and routed to backlog **999.21** (future milestone). Keep Phase 17 a focused polish + branding + groundwork pass, not a redesign.
**Seed defect — phone-layout bottom-bar overlap (documented 2026-06-13; long-standing, NOT introduced by Phase 10 — the BottomTabBar dates to Phase 04):**
diff --git a/.planning/phases/17-ui-optimization-polish/17-CONTEXT.md b/.planning/phases/17-ui-optimization-polish/17-CONTEXT.md
new file mode 100644
index 0000000..731a87a
--- /dev/null
+++ b/.planning/phases/17-ui-optimization-polish/17-CONTEXT.md
@@ -0,0 +1,120 @@
+# Phase 17: UI Optimization & Polish - Context
+
+**Gathered:** 2026-06-17
+**Status:** Ready for planning
+
+
+## Phase Boundary
+
+A **visual-identity & polish pass** for the PWA, spanning three bounded workstreams:
+
+- **A — Phone-layout polish.** Fix the long-standing phone (≤767px) fixed-chrome overlap where the `position: fixed` BottomTabBar covers the New Event FAB (FAB lands on the Admin tab) and occludes the bottom of the calendar + the colour-legend chips, then sweep other small-viewport spacing / tap-target / overflow issues. CSS/layout only, no behaviour change.
+- **B — Branding assets.** Generate a real **FamilySync** logo and drop it into the already-built `BrandSlot` seam (`apps/pwa/src/components/BrandSlot.tsx`), and produce a **complete favicon / PWA-icon set** to replace the placeholder stubs in `apps/pwa/public/` (`icon-192.png` 699 B, `icon-512.png`, `apple-touch-icon.png` 617 B — all generated stubs; there is currently **no `favicon.ico`/`favicon.svg`** and index.html links only the apple-touch icon).
+- **C — Theme-token groundwork.** Restructure `apps/pwa/src/styles/tokens.css` from its single light `:root` into a **themeable semantic-token layer** (swappable by `data-theme` / `prefers-color-scheme`). Light stays the only *shipped* theme — this is enabling groundwork only.
+
+**Out of scope (explicitly deferred this discussion, 2026-06-17):**
+- **Shipped dark theme + light/dark/system toggle** → backlog **999.20** (Phase 17's token groundwork is the enabling seam).
+- **Broader "modern styling" visual refresh** (contemporary restyle of login/calendar/event-form/lists/admin) → backlog **999.21**, flagged for a **future milestone** — a redesign track, not a polish phase.
+
+This stays a focused polish + branding + groundwork pass, **not a redesign**.
+
+
+
+## Implementation Decisions
+
+### A — Phone-layout polish
+- **D-01:** Fix the seed defect (BottomTabBar overlapping the FAB + colour legend) AND run a bounded small-viewport sweep — the Phase 7 `layout.spec.ts` assertions (tap targets ≥44px, no horizontal overflow, critical elements in-viewport, accessible names) are the checklist; fix what they flag across phone routes. Bounded and checklist-driven, not a free-form audit.
+- **D-02:** **Fix technique and regression-guard mechanism are the researcher's call** (deferred from discussion). Inputs the researcher must weigh: the ROADMAP/todo fix sketch (lift FAB to `bottom: calc(56px + env(safe-area-inset-bottom,0px) + var(--space-6))` + matching content `padding-bottom`, OR shrink the `100dvh` column by the bar height) vs. a single shared `--bottom-chrome-h` token consumed by both the FAB offset and the content padding (single source of truth). Researcher also decides whether to add a permanent overlap assertion to `layout.spec.ts` (FAB/legend must not intersect the BottomTabBar rect on phone profiles) vs. playwright-cli manual verification only. **Default lean if evidence is neutral:** shared token + add the CI assertion (hardest to regress), but this is the researcher's decision to make on the merits.
+
+### B — Branding assets
+- **D-03:** **Logo + full icon set are AI-generated in-phase** (option 2a). Claude generates the logo and the complete icon/favicon set from the brief below, wires them in (BrandSlot ``, `apps/pwa/public/` files, `index.html` ``s, and the `vite-plugin-pwa` manifest `icons[]` in `apps/pwa/vite.config.ts`), and the user approves the result before it's final. No external designer / user-supplied art.
+- **D-04:** Deliver a **complete** icon set, not just a logo: `favicon.ico` + `favicon.svg`, `icon-192.png`, `icon-512.png`, a **proper maskable** 512 (the current manifest reuses the non-maskable 512 as maskable — a real maskable needs safe-zone padding), and `apple-touch-icon.png` (180×180). Update `index.html` (add the missing ``s; `theme-color` currently `#4A90D9`) and the `vite.config.ts` manifest to reference them.
+- **D-05:** Drive the logo through the existing `BrandSlot` seam contract — swap the placeholder `
` for an `` and override the `--brand-logo-*` tokens — **without changing `LoginPage` layout** (the seam was built in Phase 19 precisely to isolate this). Keep the accessibility shape: `
` carries the app name, logo image is decorative (`alt=""` / `aria-hidden`), no layout shift.
+
+### C — Theme-token groundwork
+- **D-06:** Restructure `tokens.css` into a themeable layer (semantic tokens resolvable per theme via `data-theme`/`prefers-color-scheme`) — **groundwork only** (option 3a). **Do NOT** author dark palette values, wire `prefers-color-scheme` to actually flip, or add a toggle this phase. Light remains the sole shipped theme. Keep the existing invariant: no hard-coded hex/px in component files — all values stay in `tokens.css`. The restructure must leave the Schedule-X `--sx-color-*` overrides (bottom of tokens.css) working unchanged.
+
+### Claude's Discretion
+- **D-02** (fix technique + regression guard) is explicitly delegated to the researcher/planner.
+- Exact small-viewport issues surfaced by the `layout.spec` sweep (D-01) — fix as found, within the no-behaviour-change boundary.
+- Logo visual execution within the brand brief (see Specific Ideas) — subject to user approval at the checkpoint.
+
+### Folded Todos
+- **`2026-06-13-pwa-phone-bottombar-overlap.md`** (`area: pwa-ui`, `resolves_phase: 17`) — the phase's seed defect. Phone-layout fixed BottomTabBar overlaps the New Event FAB + colour legend at ≤767px. Reproduced 2026-06-13 via playwright-cli at 390×844 (FAB over Admin tab; "Dev User" legend clipped) vs 1280×800 (no overlap). Long-standing (BottomTabBar dates to Phase 04), not a Phase 10 regression. This is workstream A's anchor — its `files:` list (`App.tsx`, `BottomTabBar.tsx`, `CalendarShell.tsx`) is the fix surface.
+
+
+
+## Canonical References
+
+**Downstream agents MUST read these before planning or implementing.**
+
+### Phase scope & seed defect
+- `.planning/ROADMAP.md` §"Phase 17: UI Optimization & Polish" — goal, three-workstream scope, scope boundary, seed-defect detail + CSS fix sketch.
+- `.planning/todos/pending/2026-06-13-pwa-phone-bottombar-overlap.md` — the folded seed-defect todo (repro, fix sketch, affected files).
+- `.planning/ROADMAP.md` §"Phase 999.20" / §"Phase 999.21" — the deferred dark-mode and styling-refresh backlog items (what is explicitly NOT in this phase).
+
+### A — Phone layout (fix surface)
+- `apps/pwa/src/App.tsx` — `window.matchMedia('(max-width: 767px)')` phone breakpoint + `contentStyle` (currently reserves no `padding-bottom` for the fixed bar).
+- `apps/pwa/src/components/BottomTabBar.tsx` — `position: fixed; height: calc(56px + env(safe-area-inset-bottom)); z-index: 200`.
+- `apps/pwa/src/components/CalendarShell.tsx` — the "New Event" FAB (`position: fixed; bottom: var(--space-6); right: var(--space-6)`).
+- `apps/pwa/e2e/layout.spec.ts` — Phase 7 quality-bar assertions (UI-SPEC Rules 1–4: ≥44px tap targets, no overflow, in-viewport, accessible names); the sweep checklist AND the home for any new overlap regression assertion.
+- `apps/pwa/playwright.config.ts` — `iphone` (iPhone 14/WebKit 390×844), `pixel` (Pixel 7/Chromium 412×915), `desktop` (Desktop Chrome 1280×720) profiles to verify across.
+
+### B — Branding
+- `apps/pwa/src/components/BrandSlot.tsx` — the Phase-17 branding seam; header documents the `--brand-logo-*` token contract and the swap-div-for-`` plan.
+- `.planning/phases/19-local-auth-no-oidc-mode/19-UI-SPEC.md` §Brand Slot — the seam's design contract (referenced by BrandSlot.tsx).
+- `apps/pwa/public/` — `apple-touch-icon.png`, `icon-192.png`, `icon-512.png` (placeholder stubs to replace).
+- `apps/pwa/index.html` — current `` + `theme-color` meta (no `` yet).
+- `apps/pwa/vite.config.ts` §`VitePWA({ manifest: { icons: [...] } })` (lines ~29–41) — PWA manifest icon list to update (incl. the improper maskable reuse).
+
+### C — Theming
+- `apps/pwa/src/styles/tokens.css` — the single light `:root` token system to restructure into a themeable layer (note the Schedule-X `--sx-color-*` overrides at the bottom and the `--brand-logo-*` defaults).
+
+
+
+## Existing Code Insights
+
+### Reusable Assets
+- **`BrandSlot` seam** (`apps/pwa/src/components/BrandSlot.tsx`): purpose-built in Phase 19 to absorb the real logo with zero `LoginPage` layout change — swap the placeholder div for an `` and set `--brand-logo-*`. The branding workstream is wiring, not new architecture.
+- **`layout.spec.ts` + 3 Playwright profiles** (Phase 7/14): a ready, CI-wired structural quality bar (tap targets / overflow / in-viewport / a11y names) — doubles as the sweep checklist (D-01) and the natural home for a regression guard (D-02).
+- **CSS custom-property token system** (`tokens.css`): everything is already a variable with "no hard-coded hex/px in components" enforced — the themeable-layer restructure (D-06) builds on an already-favourable structure rather than fighting inline values.
+- **`vite-plugin-pwa` manifest** (`vite.config.ts`): the icon set is declared in one place; replacing stubs = update files in `public/` + the manifest `icons[]` + `index.html` links.
+
+### Established Patterns
+- **Phone/desktop split at 767/768px** via `matchMedia` in `App.tsx`; phone uses top AppNav (PhoneNav ``) + fixed BottomTabBar (sole `
+
+
+## Specific Ideas
+
+**Logo / brand brief (user, 2026-06-17):**
+- **FamilySync *is* the brand** — family-oriented, the name is the identity.
+- **Caricature-family vibes** — a warm, characterful family feel (not a cold/corporate geometric mark).
+- **Warm tones.**
+- **Rounded corners / rounded shapes.**
+- Overall it should **"make you feel comfortable and at home."**
+
+This brief drives the AI-generated logo + icon set (D-03/D-04). Present generated options at a user-approval checkpoint before finalizing; the warm/rounded/at-home direction is the acceptance lens. Note the current `theme-color` is `#4A90D9` (cool blue) and `--color-shared-family` is rose `#f25c7a` — the warm-tone brief may motivate revisiting the brand/theme accent during the token-groundwork work (keep within light-theme scope).
+
+
+
+## Deferred Ideas
+
+- **Shipped dark theme + light/dark/system toggle** — captured as backlog **999.20** (PWA dark mode / theming). Phase 17 ships the enabling token groundwork only.
+- **Modern visual styling refresh** (contemporary restyle across high-visibility surfaces) — captured as backlog **999.21**, flagged for a **future milestone** (redesign risk; own track).
+
+### Reviewed Todos (not folded)
+- **`2026-06-10-gitea-ci-regression-and-docker-publish.md`** — surfaced as a weak keyword match (score 0.6) but is CI/tooling work already shipped in Phase 8/14; unrelated to this UI phase. Not folded.
+
+
+---
+
+*Phase: 17-ui-optimization-polish*
+*Context gathered: 2026-06-17*
diff --git a/.planning/phases/17-ui-optimization-polish/17-DISCUSSION-LOG.md b/.planning/phases/17-ui-optimization-polish/17-DISCUSSION-LOG.md
new file mode 100644
index 0000000..0559374
--- /dev/null
+++ b/.planning/phases/17-ui-optimization-polish/17-DISCUSSION-LOG.md
@@ -0,0 +1,102 @@
+# Phase 17: UI Optimization & Polish - Discussion Log
+
+> **Audit trail only.** Do not use as input to planning, research, or execution agents.
+> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
+
+**Date:** 2026-06-17
+**Phase:** 17-ui-optimization-polish
+**Areas discussed:** Scope breadth, Fix technique, Regression guard, Phase shape, Branding asset ownership, Dark-mode depth, Styling-refresh boundary, Logo/brand direction
+
+---
+
+## Phase shape / sequencing
+
+Initial framing was a CSS-only layout-polish phase. Mid-discussion the user expanded scope to also include branding/logo assets (started but unfinished, incl. favicon), groundwork for themes (dark mode), and a modern styling refresh. This pushed past the ROADMAP's original "CSS/layout only, not a redesign" boundary, so scope was re-negotiated.
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| One phase, four workstreams (A layout + B branding + C dark mode + D styling) | Keep everything in Phase 17 | |
+| Split — keep layout + branding + token groundwork; defer dark theme & styling | Bound the phase, route the rest to backlog | ✓ |
+| One phase but styling "light" | A+B+C full, D incidental only | |
+
+**User's choice:** "spin dark mode and styling into /gsd-capture --backlog. We do the rest in the phase." → Phase 17 = layout polish + branding + theme-token groundwork. Shipped dark theme → backlog 999.20; styling refresh → backlog 999.21 (future milestone).
+**Notes:** ROADMAP Phase 17 goal/scope updated to match; two backlog items created and committed (916fb34).
+
+## A — Scope breadth (layout)
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Seed defect + targeted sweep | Fix overlap, then run Phase 7 layout.spec checklist across phone routes | ✓ (implied by keeping the layout workstream) |
+| Seed defect only | Fix just the bottom-bar overlap | |
+| Broad small-viewport audit | Free-form audit of every phone screen | |
+
+**User's choice:** Layout workstream retained as the bounded, checklist-driven sweep (D-01).
+**Notes:** Phase 7 `layout.spec.ts` assertions are the checklist.
+
+## A — Fix technique & regression guard
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Shared bar-height token + padding / inline calc / shrink column | CSS technique for the overlap | (researcher decides) |
+| Add overlap assertions to layout.spec / manual playwright-cli / both | Regression guard | (researcher decides) |
+
+**User's choice:** "5 - have the researcher decide."
+**Notes:** Delegated to research/planning (D-02). Default lean noted: shared `--bottom-chrome-h` token + CI assertion, but researcher decides on the merits.
+
+## B — Branding asset ownership
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| AI-generate in-phase | Claude generates logo + full icon set, wires in, user approves | ✓ |
+| User supplies final art | User provides logo, Claude derives icon set | |
+| Generate placeholders now, real art later | Stopgap improved mark via the seam | |
+
+**User's choice:** "2a" — AI-generate in-phase.
+**Notes:** No existing logo draft found beyond the "FS" placeholder + stub icons. Full icon set incl. proper maskable + favicon.ico/svg (D-03/D-04/D-05).
+
+## C — Dark-mode depth
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| Groundwork only | Themeable token restructure, light stays default; dark flippable later | ✓ |
+| Ship working dark mode | Finished dark theme via prefers-color-scheme | |
+| Ship dark mode + in-app toggle | Plus persisted light/dark/system toggle | |
+
+**User's choice:** "3a" — groundwork only. Combined with "spin dark mode into backlog," the *token restructure* stays in-phase; the *shipped dark theme + toggle* go to backlog 999.20 (D-06).
+**Notes:** Light remains the sole shipped theme this phase.
+
+## D — Styling-refresh boundary
+
+| Option | Description | Selected |
+|--------|-------------|----------|
+| In-system polish | Modernize within existing design system | |
+| Component-level refresh | Rework high-visibility surfaces | |
+| Broader visual overhaul | Open-ended modern restyle | (deferred) |
+
+**User's choice:** "Dont do 4 - that goes into future milestone." → routed entirely to backlog 999.21.
+**Notes:** Redesign risk; own track in a future milestone.
+
+## Logo / brand direction
+
+**User's choice (free-text):** "FamilySync is the brand — family orientated. I like caricature family kind of vibes, warm tones, rounded corner sort of thing. Something that makes you feel comfortable and at home."
+**Notes:** Captured verbatim into CONTEXT Specific Ideas as the acceptance lens for generated logo/icon options. Current theme-color `#4A90D9` (cool blue) may be revisited toward warm tones within light-theme scope.
+
+---
+
+## Claude's Discretion
+
+- Fix technique + regression-guard mechanism for the layout overlap (delegated to researcher — D-02).
+- Specific small-viewport issues surfaced by the `layout.spec` sweep (fix as found, no behaviour change).
+- Logo visual execution within the brand brief, subject to user approval at a checkpoint.
+
+## Deferred Ideas
+
+- Shipped dark theme + light/dark/system toggle → backlog **999.20**.
+- Modern visual styling refresh → backlog **999.21** (future milestone).
+- (Reviewed, not folded) `2026-06-10-gitea-ci-regression-and-docker-publish.md` — weak keyword match, already-shipped CI work, unrelated to this UI phase.
+
+---
+
+## Process note — interactive question tool blocked
+
+The `AskUserQuestion` tool returned "Permission denied by hook" during this discussion. Investigation: no configured PreToolUse hook or permission rule matches `AskUserQuestion` (user-settings matchers are only `Write|Edit`/`Bash`/`MultiEdit`; `defaultMode: bypassPermissions`; no managed settings). The block correlates with an active background subagent (the Phase 19 `--fix --auto` fixer) running concurrently — interactive questions are suppressed while a background agent is live. Discussion proceeded via the plain-text numbered-list fallback.