diff --git a/CLAUDE.md b/CLAUDE.md
index 43c994c..e4989dd 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -1 +1,81 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+
@AGENTS.md
+
+## Commands
+
+```bash
+pnpm dev # start dev server (Turbopack, port 3000)
+pnpm build # production build — catches TS and async-params errors
+pnpm lint # eslint
+```
+
+No test suite exists. Type-check only: `pnpm tsc --noEmit`.
+
+## Architecture
+
+**Knur** is a single-user personal training tracker: running data from Garmin Connect, strength workouts imported from the Strong app, AI analysis via Claude.
+
+Stack: Next.js 16.2.9 · App Router · React 19 · Turbopack · Tailwind v4 · MongoDB · TypeScript.
+
+### Key constraints from Next.js 16
+
+- `params` and `searchParams` in page components are always `Promise<...>` — always `await` them.
+- All pages reading from MongoDB must export `export const dynamic = "force-dynamic"` to prevent static caching.
+- `next/dynamic` with `ssr: false` cannot be called from Server Components — wrap it in a `"use client"` file (see `components/route-map-section.tsx`).
+- `import dynamic from "next/dynamic"` conflicts with the `dynamic` named export — rename the import: `import nextDynamic from "next/dynamic"`.
+
+### Data layer (`lib/`)
+
+`lib/db.ts` — singleton `MongoClient` cached on `global` to survive HMR. Call `getDb()` to get the `Db` instance. Database name defaults to `knur`.
+
+`lib/models/` — each model file exports a Zod schema, TypeScript types derived from it, and MongoDB CRUD helpers. MongoDB collections:
+- `running_activities` — deduplicated on `garminActivityId`; also stores lazy-loaded `routePoints: [lat, lon][]`
+- `strength_workouts` — deduplicated on `sourceKey` (= the Strong share URL or a hash)
+- `ai_analyses` — one doc per analysis; dashboard analysis uses sentinel `targetId = ObjectId("000000000000000000000001")`
+- `garmin_auth` — OAuth1 tokens (`_id: "tokens"`) and pending MFA state (`_id: "pending"`)
+- `sync_state` — singleton `{ _id: "garmin", lastSyncAt: Date }`
+
+`lib/garmin/` — Garmin Connect integration:
+- `sso.ts` — custom SSO login flow (fetches CSRF, posts credentials, handles MFA redirect)
+- `client.ts` — `getAuthorizedClient()` loads saved OAuth1 tokens; `fetchRunningActivities()` fetches up to 50 activities and maps them to `RunningActivityInput`; `fetchActivityRoutePoints()` fetches GPS polyline from the activity details endpoint
+- `wellness.ts` — `fetchRecentWellness(client, days)` fetches sleep/HRV data for N days concurrently via `Promise.allSettled`
+
+`lib/strong/parser.ts` — parses the plain-text "Share workout" output from the Strong iOS app into `StrengthWorkout[]`. Handles multiple workouts in one paste, comma-decimal weights (`12,5 kg`), and optional per-exercise `Notes:` blocks.
+
+`lib/ai/claude.ts` — builds prompts and calls the Anthropic API. Three entry points:
+- `generateAnalysis(targetType, targetId)` — per-workout/run analysis with context from previous sessions
+- `generateDashboardAnalysis()` — holistic analysis combining last 6 runs + 4 workouts + 7 days of Garmin wellness data; Garmin wellness fetch failure is swallowed so analysis works without it
+
+`lib/strength/stats.ts` — pure helpers for computing exercise volume/top-weight history (`getExerciseHistory`).
+
+### App routes (`app/`)
+
+| Route | Purpose |
+|---|---|
+| `/` | Dashboard: weekly stats, latest run/workout, comprehensive AI analysis card |
+| `/running` | Activity list + Garmin sync button |
+| `/running/[id]` | 3-col grid: route map (lazy via Suspense) + highlighted stats |
+| `/strength` | Workout list + volume chart |
+| `/strength/import` | Textarea form to paste Strong share text |
+| `/strength/[id]` | Exercise cards + AI analysis + progress charts |
+| `/settings` | Env config status + Garmin sync |
+| `/ai/actions.ts` | Server actions: `generateAnalysisAction`, `generateDashboardAnalysisAction` |
+
+### Garmin auth flow
+
+Garmin uses OAuth1 with a custom SSO. The first sync triggers a username/password login via `lib/garmin/sso.ts`. If MFA is required, the pending cookie state is stored in MongoDB (`garmin_login_pending`) and the UI prompts for the MFA code. On success, OAuth1 tokens are saved to `garmin_auth` and reused for all subsequent requests via `getAuthorizedClient()`.
+
+### Route map (GPS)
+
+GPS points are fetched lazily on first visit to a run detail page. `RouteMapFetcher` (async Server Component in `app/running/[id]/page.tsx`) checks `activity.routePoints` in DB — if absent and `hasRoute` is true, fetches from Garmin and caches. The map renders via Leaflet (`react-leaflet`) with CartoDB dark tiles (no API key required). Leaflet requires SSR bypass — see `components/route-map-section.tsx` ("use client" wrapper with `next/dynamic ssr: false`).
+
+### Theming
+
+Tailwind v4 with CSS custom properties defined in `app/globals.css`. Key tokens: `bg` (dark navy), `surface` (slightly lighter), `fg` (cream), `accent` (orange `#fb4617`), `muted`, `sand`. Use `var(--color-accent)` etc. when CSS variables are needed outside Tailwind (recharts, Leaflet SVG).
+
+### recharts pitfall
+
+`ResponsiveContainer` with `height="100%"` inside a dynamically-sized wrapper overflows when labels add extra space. Always use a fixed pixel `height` on `ResponsiveContainer` and do NOT set a fixed height on the wrapper div.
diff --git a/app/strength/[id]/page.tsx b/app/strength/[id]/page.tsx
index 4fbdd05..7152615 100644
--- a/app/strength/[id]/page.tsx
+++ b/app/strength/[id]/page.tsx
@@ -5,7 +5,7 @@ import { InfoTooltip } from "@/components/info-tooltip";
import { formatDate, formatDateShort } from "@/lib/format";
import { getLatestAnalysisForTarget } from "@/lib/models/analysis";
import { getStrengthWorkout, listStrengthWorkouts } from "@/lib/models/strength";
-import { getExerciseHistory } from "@/lib/strength/stats";
+import { exerciseE1rm, getExerciseHistory } from "@/lib/strength/stats";
export const dynamic = "force-dynamic";
@@ -43,19 +43,31 @@ export default async function StrengthWorkoutPage({
{exercise.name}
- {exercise.notes ?{exercise.notes}
: null} -{exercise.name}
+ {exercise.notes ?{exercise.notes}
: null} +