- Add LogOut icon (lucide-react) and fetchLocalLogout (api/client) imports
- Add useNavigate (react-router) for post-logout redirect
- Implement handleSignOut: fire-and-best-effort try/catch, navigate to /login in both branches
- Add Sign out button row at bottom of sheet (44px tap target, var(--color-destructive), divider separator)
- Always navigates to /login even on API failure (server cookie cleared or expired)
Records approved brand decisions for plan 17-04:
- logo art approved (family-house redesign)
- brand accent #e8915a (warm amber)
- --brand-logo-border-radius: 0
- Overwrite logo.svg with approved higher-contrast family-house SVG
(warm peach gradient bg, amber roof, bold white walls, heart finial,
three clearly-spaced family figures in rose/gold/blue)
- Regenerate full icon/favicon set from new art:
favicon.svg, favicon.ico (967 B), icon-192.png (192x192),
icon-512.png (512x512), icon-maskable-512.png (512x512 safe-zone),
apple-touch-icon.png (180x180)
- Approved brand decisions recorded for plan 17-04:
accent #e8915a, --brand-logo-border-radius: 0
- Add @vite-pwa/assets-generator@1.0.2 as devDependency in apps/pwa
- Add pwa:icons script (pwa-assets-generator generate) to apps/pwa/package.json
- Approve sharp build scripts in pnpm-workspace.yaml (required for @vite-pwa/assets-generator)
- Hand-author apps/pwa/public/logo.svg: warm/rounded/at-home family scene with house, two adults, child, heart — square 512x512 viewBox, self-contained, text-free
- Create apps/pwa/pwa-assets.config.ts with minimal2023Preset, images: ['public/logo.svg'], no overrideManifestIcons
Lint (eslint --max-warnings 0):
- index.ts: disable no-unsafe-argument on the type-only Context mismatch when
delegating to the OIDC handler inside the local-session skip wrapper
- localAuth.ts: handleLogout is sync (no await) — drop async (require-await)
- devBypass.ts: disable detect-possible-timing-attacks on the public well-known
dev-placeholder string compare (not a secret comparison)
- remove dead code / unused bindings flagged by no-unused-vars: makeTestApp
(localSession.test), makeUnauthContext + BrowserContext import (login.spec),
unused memberId (admin.test), unused txSelectCount counter (me.test)
- localAuthMiddleware.test / me.test: fix unused + reflow-detached
eslint-disable directives
Format: prettier --write across the 20 Phase-19 files that were never formatted.
Secret scan (gitleaks): allowlist two false positives — the synthetic >=32-char
TEST_SECRET in localSession.test.ts, and .planning/ design prose (a generic-api-key
regex hit on "credential atomically, 409-equivalent"). Neither is a real secret.
Verified locally: format:check, lint, typecheck, md:lint, gitleaks (no leaks),
PWA 266/266, API 452/452.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>