diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md
deleted file mode 100644
index 02c2552..0000000
--- a/.claude/CLAUDE.md
+++ /dev/null
@@ -1,165 +0,0 @@
-# CLAUDE.md - UMBRA
-
-## CRUCIAL CONTEXT EFFICIENCY
-
-### Subagent Discipline
-- Prefer inline work for tasks under ~5 tool calls. Subagents have overhead — don't delegate trivially.
-- When using subagents, include output rules: "Final response under 2000 characters. List outcomes, not process."
-- Never call TaskOutput twice for the same subagent. If it times out, increase the timeout — don't re-read.
-
-### File Reading
-- Read files with purpose. Before reading a file, know what you're looking for.
-- Use Grep to locate relevant sections before reading entire large files.
-- Never re-read a file you've already read in this session.
-- For files over 500 lines, use offset/limit to read only the relevant section.
-
-### Responses
-- Don't echo back file contents you just read — the user can see them.
-- Don't narrate tool calls ("Let me read the file..." / "Now I'll edit..."). Just do it.
-- Keep explanations proportional to complexity. Simple changes need one sentence, not three paragraphs.
-
-## Deployment & Access
-
-- **UMBRA is hosted on a remote machine** at `http://10.0.69.35` (not localhost).
-- **Login PIN:** `1993`
-- **Rebuilds are manual.** Do not run `docker-compose` commands — the user will rebuild on the remote machine when needed.
-- **Browser automation** can access the live app at `http://10.0.69.35`.
-
-## Operational Procedures
-
-- Before making any changes or edits to code, create a branch. Once work is completed, commit and push to the branch automatically, then merge into main and push.
-- When required: For backend work invoke the 'backend-engineer' subagent, for work on the front end, invoke the 'frontend-engineer' subagent. To review work use the 'senior-code-reviewer' subagent and for any research use the 'research-analyst' subagent.
-- For any frontend UI related work you MUST use the frontend design skill AND reference the [stylesheet](.claude/context/stylesheet.md) to ensure visual consistency. The stylesheet defines all colors, typography, spacing, component patterns, and design principles for UMBRA. Do not invent new patterns.
-
-## Future Roadmap
-
-After the UI refresh is complete, the next major phases are:
-- **Multi-user authentication** — replace single PIN auth with per-user accounts
-- **Backend restructure** — add user_id foreign keys to all models, scope all queries per-user
-- **Always build for scale.** Even though UMBRA is currently single-user, design features, indexes, validations, and state machines with multi-user in mind. Cutting corners now means rework later.
-
-## Key Features & Patterns
-
-- **Reminder alerts**: Real-time polling (30s) via `AlertsProvider` context. Dashboard shows `AlertBanner`, other pages get Sonner toasts (max 3 + summary). Snooze/dismiss with `client_now` for Docker UTC offset.
-- **Two-click delete**: `useConfirmAction` hook in `hooks/useConfirmAction.ts` — first click shows "Sure?", auto-resets after 4s, second click executes. Used by TodoItem and ReminderItem.
-- **Naive datetime contract**: All datetimes are naive (no timezone). Frontend sends `toLocalDatetime()` from `lib/date-utils.ts` when the backend needs "now". Docker container runs UTC; `client_now` bridges the gap.
-
-## Known Issues
-
-- **Git push auth flake.** The first `git push` to the Gitea remote will fail with an authentication error. Simply retry the same push command — the second attempt succeeds.
-
-## Hard Rules
-
-- **Naive datetimes only.** The DB uses `TIMESTAMP WITHOUT TIME ZONE`. Never send timezone-aware strings (no `Z` suffix, no `.toISOString()`). Use local datetime formatting helpers instead.
-- **Eager load relationships in async SQLAlchemy.** Any `response_model` that includes a relationship (e.g. `ProjectResponse.tasks`) must use `selectinload()` when querying. Lazy loading raises `MissingGreenlet` in async context.
-- **Never shadow SQLAlchemy names.** Model columns must not be named `relationship`, `column`, `metadata`, or other SQLAlchemy reserved names. The `person.py` model aliases the import as `sa_relationship` for this reason.
-- **Frontend date inputs require exact formats.** `` needs `YYYY-MM-DD`, `` needs `YYYY-MM-DDThh:mm`. Backend may return `2026-02-15T00:00:00` which must be sliced/converted before binding.
-- **All API routes are prefixed with `/api`.** Frontend axios base URL is `/api`. Nginx proxies `/api/` to backend:8000. Never duplicate the prefix.
-
-## Tech Stack
-
-### Backend
-- **Python 3.12** (slim Docker image - no curl, use `urllib` for healthchecks)
-- **FastAPI** with async lifespan, Pydantic v2 (`model_dump()`, `ConfigDict(from_attributes=True)`)
-- **SQLAlchemy 2.0** async with `Mapped[]` type hints, `mapped_column()`, `async_sessionmaker`
-- **PostgreSQL 16** (Alpine) via `asyncpg`
-- **Alembic** for migrations
-- **Auth:** PIN-based with bcrypt + itsdangerous signed cookies (not JWT)
-
-### Frontend
-- **React 18** + TypeScript + Vite 6
-- **TanStack Query v5** for server state (`useQuery`, `useMutation`, `invalidateQueries`)
-- **FullCalendar 6** (dayGrid, timeGrid, interaction plugins)
-- **Tailwind CSS 3** with custom dark theme + accent color CSS variables
-- **Sonner** for toast notifications
-- **Lucide React** for icons
-- Custom shadcn/ui-style components in `frontend/src/components/ui/`
-
-### Infrastructure
-- **Docker Compose** - 3 services: `db`, `backend`, `frontend`
-- **Nginx** (Alpine) serves frontend SPA, proxies `/api/` to backend
-- Frontend served on port **80**, backend on port **8000**
-
-## Authority Links
-
-- [ui_refresh.md](.claude/projects/ui_refresh.md) - UI overhaul project plan, audit findings, implementation stages
-- [stylesheet.md](.claude/context/stylesheet.md) - Design system & visual reference for all frontend work
-
-## Project Structure
-
-```
-backend/app/
- main.py # FastAPI app, router registration, health endpoint
- config.py # Pydantic BaseSettings (DATABASE_URL, SECRET_KEY)
- database.py # Async engine, session factory, get_db dependency
- models/ # SQLAlchemy 2.0 models (Mapped[] style)
- schemas/ # Pydantic v2 request/response schemas
- routers/ # One router per feature (auth, todos, events, etc.)
-
-frontend/src/
- App.tsx # Routes + ProtectedRoute wrapper
- lib/api.ts # Axios instance + getErrorMessage helper
- hooks/ # useAuth, useSettings, useTheme, useCalendars
- types/index.ts # TypeScript interfaces matching backend schemas
- components/
- ui/ # 16 base components (Button, Dialog, Sheet, Card, Input, Select, etc.)
- layout/ # AppLayout + Sidebar
- auth/ # LockScreen (PIN setup/login)
- dashboard/ # DashboardPage + widgets (Stats, Calendar, Todo, Upcoming, Countdown, etc.)
- calendar/ # CalendarPage, CalendarSidebar, CalendarForm, EventForm, TemplateForm
- todos/ # TodosPage + TodoList + TodoItem + TodoForm
- reminders/ # RemindersPage + ReminderList + ReminderForm
- projects/ # ProjectsPage, ProjectCard, ProjectDetail, ProjectForm, KanbanBoard, TaskRow, TaskForm, TaskDetailPanel
- people/ # PeoplePage + PersonCard + PersonForm
- locations/ # LocationsPage + LocationCard + LocationForm
- settings/ # SettingsPage (accent color, PIN change, first day of week)
-```
-
-## Essential Commands
-
-```bash
-# Build and run all services
-docker-compose up --build
-
-# Rebuild single service after changes
-docker-compose up --build backend
-docker-compose up --build frontend
-
-# View logs
-docker-compose logs -f
-docker-compose logs -f backend
-
-# Reset database (destroys all data)
-docker-compose down -v && docker-compose up --build
-
-# Stop everything
-docker-compose down
-```
-
-## API Routes
-
-All routes require auth (signed cookie) except `/api/auth/*` and `/health`.
-
-| Prefix | Resource |
-|----------------------|-----------------|
-| `/api/auth` | PIN setup/login/logout/status |
-| `/api/todos` | Todos CRUD + toggle |
-| `/api/events` | Calendar events CRUD (incl. recurring) |
-| `/api/event-templates` | Event templates CRUD |
-| `/api/calendars` | User calendars CRUD + visibility |
-| `/api/reminders` | Reminders CRUD + dismiss |
-| `/api/projects` | Projects + nested tasks CRUD |
-| `/api/people` | People CRUD |
-| `/api/locations` | Locations CRUD + search |
-| `/api/settings` | Settings + PIN change |
-| `/api/dashboard` | Dashboard aggregation |
-| `/api/upcoming` | Unified upcoming items |
-| `/api/weather` | Weather data proxy |
-
-## Stop Conditions
-
-- **Do not** add timezone info to datetime strings sent to the backend
-- **Do not** use `datetime.utcnow()` - use `datetime.now(timezone.utc)` instead (deprecated in 3.12)
-- **Do not** return relationships from async endpoints without `selectinload()`
-- **Do not** use `curl` in backend Docker healthchecks (not available in python:slim)
-- **Do not** use `git push --force` or destructive git operations without explicit approval
diff --git a/.claude/context/stylesheet.md b/.claude/context/stylesheet.md
deleted file mode 100644
index 2eb589b..0000000
--- a/.claude/context/stylesheet.md
+++ /dev/null
@@ -1,359 +0,0 @@
-# UMBRA Design System & Stylesheet
-
-> This document defines the visual language for every page in UMBRA.
-> All frontend work MUST conform to these patterns. Do not invent new colors, spacing scales, or component styles.
-
----
-
-## Visual Reference
-
-The dashboard establishes the canonical look: a near-black canvas with thin-bordered cards, cyan accent highlights, the Sora/DM Sans type pairing, and subtle glow effects on interactive elements. Every page should feel like a natural extension of this dashboard.
-
-**Key visual characteristics:**
-- Ultra-dark background (~#0a0a0a) with very subtle card elevation (#0d0d0d cards)
-- Thin 1px borders in dark gray (#262626) - never heavy or prominent
-- Accent color (default cyan) used sparingly: active nav, stat icons, today highlights, hover glows
-- High-contrast white text on dark, with muted gray (#a3a3a3) for secondary content
-- Cards have a gentle hover glow (`shadow-accent/5`) - not dramatic, just a hint of life
-- Clean data-dense layouts with compact spacing - no wasted space
-- Type badges and priority pills use color-coded backgrounds at 10% opacity (e.g. `bg-blue-500/10 text-blue-400`)
-
----
-
-## 1. Color Tokens (CSS Custom Properties)
-
-All colors use HSL format via CSS variables. Never hardcode hex values.
-
-### Surface Colors
-| Token | HSL | Approx Hex | Usage |
-|---|---|---|---|
-| `--background` | `0 0% 3.9%` | `#0a0a0a` | Page background |
-| `--card` | `0 0% 5%` | `#0d0d0d` | Card/panel surfaces |
-| `--card-elevated` | `0 0% 7%` | `#121212` | Hover states, elevated surfaces |
-| `--secondary` | `0 0% 10%` | `#1a1a1a` | Secondary backgrounds, muted surfaces |
-| `--muted` | `0 0% 10%` | `#1a1a1a` | Disabled/muted backgrounds |
-
-### Text Colors
-| Token | HSL | Approx Hex | Usage |
-|---|---|---|---|
-| `--foreground` | `0 0% 98%` | `#fafafa` | Primary text |
-| `--muted-foreground` | `0 0% 63.9%` | `#a3a3a3` | Secondary/subtle text |
-
-### Border & Input
-| Token | HSL | Approx Hex | Usage |
-|---|---|---|---|
-| `--border` | `0 0% 14.9%` | `#262626` | All borders, dividers |
-| `--input` | `0 0% 14.9%` | `#262626` | Input borders |
-
-### Semantic Colors
-| Token | HSL | Usage |
-|---|---|---|
-| `--destructive` | `0 62.8% 30.6%` | Delete actions, errors |
-| `--primary` / `--accent-color` / `--ring` | Dynamic (accent HSL) | Primary actions, focus rings |
-
-### Accent System (Dynamic)
-
-The accent is composed of three root variables set at runtime by `useTheme`:
-- `--accent-h` (hue)
-- `--accent-s` (saturation)
-- `--accent-l` (lightness)
-
-These feed into `--primary`, `--ring`, and `--accent-color`.
-
-**Presets:**
-| Name | H | S | L | Approx Color |
-|---|---|---|---|---|
-| `cyan` (default) | 187 | 85.7% | 53.3% | Teal-cyan |
-| `blue` | 217 | 91.2% | 59.8% | Bright blue |
-| `purple` | 258 | 89.5% | 66.3% | Violet |
-| `orange` | 21 | 94.6% | 53.3% | Warm orange |
-| `green` | 142 | 70.6% | 45.3% | Emerald |
-
-### Semantic Color Assignments (Fixed per feature)
-
-These are NOT theme-dependent. They provide visual consistency for item types:
-
-| Feature | Text | Background | Usage |
-|---|---|---|---|
-| Todos | `text-blue-400` | `bg-blue-500/10` | Todo badges, type indicators |
-| Events | `text-purple-400` | `bg-purple-500/10` | Event badges, calendar items |
-| Reminders | `text-orange-400` | `bg-orange-500/10` | Reminder badges |
-| Projects | `text-blue-400` | `bg-blue-500/10` | Project counts |
-| In Progress | `text-purple-400` | `bg-purple-500/10` | Status indicators |
-| Open Todos | `text-teal-400` | `bg-teal-500/10` | Stat cards |
-| Weather | `text-amber-400` | `bg-amber-500/10` | Weather widget |
-| High priority | `text-red-400` | `bg-red-500/10` | Priority pills |
-| Medium priority | `text-yellow-400` | `bg-yellow-500/10` | Priority pills |
-| Low priority | `text-green-400` | `bg-green-500/10` | Priority pills |
-
----
-
-## 2. Typography
-
-### Font Families
-- **Headings:** `Sora` (`font-heading`) — all h1-h6, card titles, stat values, logo
-- **Body:** `DM Sans` (`font-body`) — everything else
-
-### Type Scale (as used)
-| Class | Usage |
-|---|---|
-| `text-[9px]` | Micro labels (priority badges, type tags) |
-| `text-[10px] tracking-wider uppercase` | Stat labels |
-| `text-[11px]` | Small metadata |
-| `text-xs` | Timestamps, secondary metadata |
-| `text-sm` | Body text, list items, form inputs, nav items |
-| `text-lg font-semibold` | Card titles (with `font-heading`) |
-| `text-xl font-bold tabular-nums` | Stat values (with `font-heading`) |
-| `text-3xl font-bold tracking-tight` | Page greeting/hero (with `font-heading`) |
-
-### Font Rendering
-```css
-font-feature-settings: "rlig" 1, "calt" 1;
--webkit-font-smoothing: antialiased;
-```
-
----
-
-## 3. Spacing & Layout
-
-### Border Radius
-| Token | Value | Usage |
-|---|---|---|
-| `rounded-lg` | `0.5rem` (8px) | Cards, panels |
-| `rounded-md` | `~6px` | Buttons, inputs |
-| `rounded-sm` | `~4px` | Small elements |
-| `rounded-full` | Pill | Badges, dots, icon containers |
-
-### Page Layout
-```
-App Shell: flex h-screen overflow-hidden bg-background
-├── Sidebar: w-64 (expanded) / w-16 (collapsed), border-r, bg-card
-│ transition-all duration-300
-└── Content: flex-1 flex flex-col overflow-hidden
- ├── MobileHeader: md:hidden, h-14, border-b, bg-card
- └── : flex-1 overflow-y-auto
- └── Page content: px-6 py-6
-```
-
-### Grid Patterns
-| Pattern | Classes | Usage |
-|---|---|---|
-| Stat row | `grid gap-2.5 grid-cols-2 lg:grid-cols-4` | Dashboard stats |
-| Main + sidebar | `grid gap-5 lg:grid-cols-5` → `lg:col-span-3` + `lg:col-span-2` | Dashboard layout |
-| Card grid | `grid gap-4 md:grid-cols-2 lg:grid-cols-3` | List pages (people, locations, projects) |
-
-### Standard Spacing
-- Page padding: `px-6 py-6`
-- Card padding: `p-5` (header), `p-5 pt-0` (content/footer)
-- Card gap in grid: `gap-4` to `gap-5`
-- List row padding: `py-1.5 px-2`
-- Section gap: `space-y-4` to `space-y-6`
-
----
-
-## 4. Component Patterns
-
-### Card
-```
-Base: rounded-lg border bg-card text-card-foreground shadow-sm
-Hover: hover:shadow-lg hover:shadow-accent/5 hover:border-accent/20
-Motion: transition-all duration-200
-Header: flex flex-col space-y-1.5 p-5
-Title: font-heading text-lg font-semibold leading-none tracking-tight
-Content: p-5 pt-0
-Footer: flex items-center p-5 pt-0
-```
-
-### Button (CVA variants)
-```
-Base: inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium
- transition-colors focus-visible:ring-2 focus-visible:ring-ring
-Variants:
- default: bg-accent text-accent-foreground hover:bg-accent/90
- destructive: bg-destructive text-destructive-foreground hover:bg-destructive/90
- outline: border border-input bg-background hover:bg-accent/10 hover:text-accent
- secondary: bg-secondary text-secondary-foreground hover:bg-secondary/80
- ghost: hover:bg-accent/10 hover:text-accent
- link: text-accent underline-offset-4 hover:underline
-Sizes:
- default: h-10 px-4 py-2
- sm: h-9 px-3
- lg: h-11 px-8
- icon: h-10 w-10
-```
-
-### Badge
-```
-Base: inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold
-Variants:
- default: border-transparent bg-accent text-accent-foreground
- secondary: border-transparent bg-secondary text-secondary-foreground
- destructive: border-transparent bg-destructive text-destructive-foreground
- outline: text-foreground
-```
-
-### Input / Select / Textarea
-```
-h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm
-placeholder:text-muted-foreground
-focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2
-disabled:cursor-not-allowed disabled:opacity-50
-```
-
-### Dialog
-```
-Overlay: fixed inset-0 bg-background/80 backdrop-blur-sm
-Content: border bg-card p-6 shadow-lg rounded-lg max-w-xl
-Header: flex flex-col space-y-1.5
-Title: text-lg font-semibold leading-none tracking-tight
-Footer: flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2
-Close: absolute right-4 top-4, X icon h-4 w-4
-```
-
-### Empty State
-```
-Container: flex flex-col items-center justify-center py-16 px-4
-Icon: rounded-full bg-muted p-4 mb-4, icon h-8 w-8 text-muted-foreground
-Title: text-lg font-semibold mb-1
-Desc: text-sm text-muted-foreground text-center max-w-sm mb-4
-Action: