diff --git a/CLAUDE.md b/CLAUDE.md
index 0046ac0..933b20b 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -1,3 +1,1024 @@
+# Work Order System — Build TODO
+> Hand this file to Claude Code. All frontend files use `.mjs` extensions.
+> Stack: Go · Pure JS + Web Components · SQL Server · Docker
+
+---
+
+## Table of Contents
+- [Design System](#design-system)
+- [Project Structure](#project-structure)
+- [Phase 1 — Foundation](#phase-1--foundation)
+- [Phase 2 — Field Features](#phase-2--field-features)
+- [Phase 3 — Integrations & Admin](#phase-3--integrations--admin)
+- [Phase 4 — Polish & Optimization](#phase-4--polish--optimization)
+- [Component Inventory](#component-inventory)
+- [API Endpoints](#api-endpoints)
+- [Database Schema](#database-schema)
+- [Conventions](#conventions)
+
+---
+
+## Design System
+
+### Color Palette
+```css
+:root {
+ /* Brand */
+ --navy: #0D2137; /* Primary dark — sidebar, headers */
+ --teal: #0A7EA4; /* Primary accent — buttons, links, active states */
+ --teal-lt: #14B8D4; /* Light accent — hover states, highlights */
+ --teal-dk: #075E7A; /* Dark accent — pressed states */
+
+ /* Surfaces */
+ --bg: #F0F6FA; /* Page background */
+ --surface: #FFFFFF; /* Cards, panels */
+ --surface-2: #E8F0F5; /* Inset areas, table stripes */
+ --sidebar-bg: #0D2137; /* Sidebar background */
+ --sidebar-hover: #153248;
+ --sidebar-active: #0A7EA4;
+
+ /* Text */
+ --text: #1A2E3B; /* Primary text */
+ --text-muted: #64748B; /* Secondary / helper text */
+ --text-inv: #FFFFFF; /* Text on dark backgrounds */
+
+ /* Semantic */
+ --success: #1D9D6C;
+ --warning: #E07B39;
+ --danger: #C0392B;
+ --info: #0A7EA4;
+
+ /* Borders & Shadows */
+ --border: #D1DDE6;
+ --border-lt: #E8F0F5;
+ --shadow-sm: 0 1px 3px rgba(0,0,0,.08);
+ --shadow-md: 0 4px 12px rgba(0,0,0,.10);
+ --shadow-lg: 0 8px 24px rgba(0,0,0,.12);
+
+ /* Status Pills */
+ --status-draft: #94A3B8;
+ --status-assigned: #0A7EA4;
+ --status-scheduled: #8B5CF6;
+ --status-in_progress: #E07B39;
+ --status-pending_review: #D97706;
+ --status-closed: #1D9D6C;
+
+ /* Priority */
+ --priority-low: #64748B;
+ --priority-normal: #0A7EA4;
+ --priority-high: #E07B39;
+ --priority-urgent: #C0392B;
+
+ /* Spacing */
+ --radius-sm: 4px;
+ --radius: 8px;
+ --radius-lg: 12px;
+ --radius-xl: 16px;
+
+ /* Sidebar width */
+ --sidebar-w: 260px;
+ --sidebar-collapsed: 64px;
+}
+```
+
+### Typography
+Load via `` in `index.html` — no build step needed:
+```html
+
+
+
+```
+
+```css
+:root {
+ --font-body: 'Inter', 'Segoe UI', system-ui, sans-serif;
+ --font-mono: 'JetBrains Mono', 'Cascadia Code', monospace;
+
+ --text-xs: 0.70rem; /* 11px — labels, caps */
+ --text-sm: 0.813rem; /* 13px — helper, meta */
+ --text-base: 0.938rem; /* 15px — body */
+ --text-md: 1.063rem; /* 17px — subheadings */
+ --text-lg: 1.25rem; /* 20px — section headers */
+ --text-xl: 1.5rem; /* 24px — page titles */
+ --text-2xl: 2rem; /* 32px — dashboard hero numbers */
+
+ --weight-normal: 400;
+ --weight-medium: 500;
+ --weight-semibold: 600;
+ --weight-bold: 700;
+}
+```
+
+### Component Design Patterns
+- Cards: white background, `var(--border)` border, `var(--radius)` corners, `var(--shadow-sm)`
+- Buttons: filled primary = `--teal`, ghost = transparent + `--teal` border, danger = `--danger`
+- Inputs: `--border` border, focus ring `--teal` 2px outline-offset, `--radius-sm` corners
+- Tables: header row `--surface-2`, alternating rows, sticky header on scroll
+- Status pills: colored dot + label, pill shape, light background tint of the status color
+- Icon + label pattern everywhere — use Lucide icons loaded via CDN (no npm)
+
+### Icons
+```html
+
+
+```
+Call `lucide.createIcons()` after each render. Use named icons:
+`clipboard-list`, `users`, `truck`, `wrench`, `map-pin`, `camera`, `file-invoice`,
+`layout-dashboard`, `settings`, `bell`, `chevron-left`, `plus`, `search`, `filter`
+
+---
+
+## Project Structure
+
+```
+workorder/
+├── CLAUDE.md ← !! READ FIRST — conventions for Claude Code
+├── cmd/server/main.go
+├── internal/
+│ ├── api/
+│ │ ├── router.go
+│ │ ├── middleware/
+│ │ │ ├── auth.go
+│ │ │ ├── cors.go
+│ │ │ └── logger.go
+│ │ └── handlers/
+│ │ ├── auth.go
+│ │ ├── workorder.go
+│ │ ├── step.go
+│ │ ├── resource.go
+│ │ ├── attachment.go
+│ │ ├── accounting.go
+│ │ ├── user.go
+│ │ ├── registry.go ← people/vehicle/equipment/material master lists
+│ │ ├── dashboard.go
+│ │ └── report.go
+│ ├── service/
+│ │ ├── workorder.go
+│ │ ├── notification.go
+│ │ ├── spatial.go
+│ │ └── export.go ← CSV/Excel export
+│ ├── repository/
+│ │ ├── db.go
+│ │ ├── workorder.go
+│ │ ├── step.go
+│ │ ├── resource.go
+│ │ ├── attachment.go
+│ │ ├── accounting.go
+│ │ ├── user.go
+│ │ └── registry.go
+│ ├── model/
+│ │ ├── workorder.go
+│ │ ├── step.go
+│ │ ├── resource.go
+│ │ ├── attachment.go
+│ │ ├── accounting.go
+│ │ ├── user.go
+│ │ └── dashboard.go
+│ └── config/config.go
+│
+├── web/ ← All frontend — served as static files by Go
+│ ├── index.html ← App shell, loads fonts, Lucide, Leaflet
+│ ├── app.mjs ← custom element + client router
+│ │
+│ ├── components/
+│ │ ├── layout/
+│ │ │ ├── app-sidebar.mjs ← Left nav — collapsible, mobile drawer
+│ │ │ ├── app-topbar.mjs ← Top bar — breadcrumb, notifications bell, user avatar
+│ │ │ ├── app-root.mjs ← Shell that wires sidebar + topbar +
+│ │ │ └── app-mobile-nav.mjs ← Bottom tab bar for mobile (≤768px)
+│ │ │
+│ │ ├── work-orders/
+│ │ │ ├── wo-list.mjs ← Searchable, filterable WO list
+│ │ │ ├── wo-kanban.mjs ← Kanban board view (by status column)
+│ │ │ ├── wo-form.mjs ← Create / edit full form
+│ │ │ ├── wo-detail.mjs ← Read-only detail — tabs for each section
+│ │ │ ├── wo-checklist.mjs ← Step checklist with check-off + progress bar
+│ │ │ ├── wo-resource-panel.mjs← Assign people, vehicles, equipment, materials
+│ │ │ ├── wo-photo-panel.mjs ← Photo gallery, capture, before/during/after
+│ │ │ ├── wo-map.mjs ← Leaflet map + directions button
+│ │ │ ├── wo-accounting.mjs ← GL, cost center, WBS, billing ref fields
+│ │ │ ├── wo-timeline.mjs ← Audit/activity log feed
+│ │ │ └── wo-print.mjs ← Print-friendly layout for field packets
+│ │ │
+│ │ ├── dashboard/
+│ │ │ ├── dash-root.mjs ← Dashboard page shell
+│ │ │ ├── dash-kpi-card.mjs ← Reusable stat card (number + trend + icon)
+│ │ │ ├── dash-status-chart.mjs← Doughnut chart — WOs by status
+│ │ │ ├── dash-priority-bar.mjs← Bar chart — WOs by priority
+│ │ │ └── dash-recent-feed.mjs ← Recent activity feed
+│ │ │
+│ │ ├── registry/
+│ │ │ ├── people-list.mjs ← Manage crew / technician records
+│ │ │ ├── people-form.mjs
+│ │ │ ├── vehicle-list.mjs ← Manage fleet / vehicles
+│ │ │ ├── vehicle-form.mjs
+│ │ │ ├── equipment-list.mjs ← Manage tools & equipment
+│ │ │ ├── equipment-form.mjs
+│ │ │ ├── material-list.mjs ← Manage materials / inventory
+│ │ │ └── material-form.mjs
+│ │ │
+│ │ ├── users/
+│ │ │ ├── user-list.mjs ← User management (admin only)
+│ │ │ ├── user-form.mjs ← Create / edit user, assign role
+│ │ │ └── user-profile.mjs ← Current user profile + password change
+│ │ │
+│ │ ├── reports/
+│ │ │ ├── report-root.mjs ← Reports landing page
+│ │ │ ├── report-by-status.mjs
+│ │ │ ├── report-by-cost.mjs
+│ │ │ └── report-export.mjs ← CSV / Excel download triggers
+│ │ │
+│ │ └── shared/
+│ │ ├── ui-badge.mjs ← — status + priority pills
+│ │ ├── ui-button.mjs ← — primary/ghost/danger variants
+│ │ ├── ui-card.mjs ← — surface container
+│ │ ├── ui-dialog.mjs ← — modal with backdrop
+│ │ ├── ui-drawer.mjs ← — slide-in panel (mobile forms)
+│ │ ├── ui-toast.mjs ← — success/error notifications
+│ │ ├── ui-spinner.mjs ← — loading state
+│ │ ├── ui-empty.mjs ← — empty state illustration + CTA
+│ │ ├── ui-confirm.mjs ← — "Are you sure?" dialog
+│ │ ├── ui-search.mjs ← — debounced search input
+│ │ ├── ui-tabs.mjs ← — tab bar + panels
+│ │ ├── ui-avatar.mjs ← — initials or photo avatar
+│ │ └── ui-tooltip.mjs ← — hover tooltip
+│ │
+│ ├── lib/
+│ │ ├── api.mjs ← Fetch wrapper, auth header, error handling
+│ │ ├── router.mjs ← Hash/history client router
+│ │ ├── store.mjs ← Reactive state (lightweight signal pattern)
+│ │ ├── auth.mjs ← JWT storage, decode, role checks
+│ │ ├── format.mjs ← Date, currency, phone formatters
+│ │ ├── validate.mjs ← Form field validators
+│ │ └── utils.mjs ← Misc helpers, debounce, deepMerge
+│ │
+│ └── styles/
+│ ├── global.css ← CSS custom properties (design tokens above)
+│ ├── reset.css ← Modern CSS reset
+│ ├── typography.css ← Base font rules
+│ ├── forms.css ← Shared input/select/textarea styles
+│ ├── tables.css ← Shared table styles
+│ └── print.css ← Print overrides for wo-print.mjs
+│
+├── migrations/
+│ ├── 001_initial.sql
+│ ├── 002_resources.sql
+│ ├── 003_attachments.sql
+│ ├── 004_accounting.sql
+│ ├── 005_users_roles.sql
+│ └── 006_audit_log.sql
+│
+├── uploads/ ← Bind-mounted in Docker
+├── Dockerfile
+├── docker-compose.yml
+├── .env.example
+└── go.mod
+```
+
+---
+
+## Phase 1 — Foundation
+**Goal:** Running app with shell, sidebar, auth, and WO CRUD.
+
+### 1.1 CLAUDE.md (create first)
+- [ ] Document `.mjs` extension convention for all frontend JS modules
+- [ ] Document Go conventions: package names, error wrapping, named DB params
+- [ ] Document CSS convention: always use design token vars, never hardcoded hex
+- [ ] Document component convention: Shadow DOM, `#private` fields, custom events
+- [ ] List all CDN dependencies and their globals (`L` for Leaflet, `lucide`, `Chart`)
+
+### 1.2 Go Project Bootstrap
+- [ ] `go mod init github.com/yourorg/workorder`
+- [ ] Add dependencies: `chi/v5`, `sqlx`, `go-mssqldb`, `golang-jwt/jwt/v5`, `google/uuid`, `joho/godotenv`
+- [ ] `internal/config/config.go` — load from env: `ADDR`, `DB_DSN`, `JWT_SECRET`, `UPLOAD_PATH`, `BASE_URL`
+- [ ] `internal/repository/db.go` — `sqlx.Connect`, pool settings (max open 25, max idle 5, lifetime 5min)
+- [ ] `cmd/server/main.go` — wire config → db → router → `http.ListenAndServe`
+
+### 1.3 Database — Migration 001
+```sql
+-- work_orders table (full schema as planned)
+-- Computed wo_number column: 'WO-' + zero-padded id
+-- status CHECK constraint
+-- priority CHECK constraint
+-- Indexes on status, parent, scheduled_start
+```
+
+### 1.4 Auth
+- [ ] `migrations/005_users_roles.sql`
+ ```sql
+ CREATE TABLE users (
+ id INT IDENTITY PRIMARY KEY,
+ username NVARCHAR(100) NOT NULL UNIQUE,
+ email NVARCHAR(200) NOT NULL UNIQUE,
+ display_name NVARCHAR(200),
+ password_hash NVARCHAR(200) NOT NULL, -- bcrypt
+ role NVARCHAR(30) NOT NULL DEFAULT 'viewer',
+ -- admin | dispatcher | field_tech | viewer
+ avatar_url NVARCHAR(500),
+ active BIT NOT NULL DEFAULT 1,
+ last_login DATETIME2,
+ created_at DATETIME2 NOT NULL DEFAULT GETUTCDATE()
+ );
+ -- Seed one admin user
+ ```
+- [ ] `POST /api/auth/login` — bcrypt compare, return `{ token, user }` with 8hr JWT
+- [ ] `POST /api/auth/refresh` — accepts valid token, returns new token
+- [ ] `GET /api/auth/me` — current user from token claims
+- [ ] JWT middleware: attach user to `context.Context`, return 401 JSON on failure
+- [ ] Role helper: `RequireRole(roles ...string)` middleware
+
+### 1.5 Work Order Backend (CRUD)
+- [ ] `model/workorder.go` — `WorkOrder`, `WorkOrderListItem`, `WorkOrderDetail` structs with `db:` and `json:` tags
+- [ ] `repository/workorder.go`
+ - `List(ctx, filters)` — status, search, priority, parentType, page/limit
+ - `GetByID(ctx, id)` — single WO
+ - `Create(ctx, wo)` — insert + return generated ID
+ - `Update(ctx, wo)` — partial update, always set `updated_at = GETUTCDATE()`
+ - `UpdateStatus(ctx, id, status, userID)` — transition + audit log insert
+ - `Delete(ctx, id)` — soft delete (add `deleted_at` column)
+ - `GetDetail(ctx, id)` — joins WO + steps + resources + attachments + accounting in one call
+- [ ] Handlers: `List`, `Get`, `Create`, `Update`, `Delete`, `UpdateStatus`
+- [ ] Paginated response: `{ data: [...], meta: { page, per_page, total } }`
+
+### 1.6 Frontend Shell
+- [ ] `web/index.html`
+ - Load Google Fonts (Inter + JetBrains Mono)
+ - Load Lucide CDN
+ - Load Leaflet CSS + JS CDN
+ - Load Chart.js CDN
+ - `
+
+
+
+
+
+
+
+```
+
+---
+
+*Start with Phase 1 in order. Each checkbox is one commit. Don't skip CLAUDE.md — it must exist before any code is written.*
+
+---
+
# Work Order System — Technical Build Plan
**Stack:** Go (backend API) · Pure JavaScript + Web Components (frontend) · SQL Server (MSSQL) · Docker