diff --git a/.claude/commands/overnight.md b/.claude/commands/overnight.md
new file mode 100644
index 00000000..459a148e
--- /dev/null
+++ b/.claude/commands/overnight.md
@@ -0,0 +1,11 @@
+Prepare and launch the overnight automation loop. Do ALL of these steps in order:
+
+1. Commit all uncommitted changes on the current branch with message: `chore: pre-overnight snapshot`
+2. Push the current branch to origin
+3. Check if branch `overnight/$DATE` exists (where $DATE is today's date YYYY-MM-DD). If it does, check it out. If not, run `./loop/prepare.sh` to create it.
+4. Commit `loop/plan.md` and `loop/prompt.md` on the overnight branch: `chore: overnight plan $DATE`
+5. Push the overnight branch: `git push -u origin overnight/$DATE`
+6. Start the loop in the background: run `caffeinate -i ./loop/loop.sh` using Bash with `run_in_background: true`
+7. Report: branch name, task count from plan.md, and confirm the loop is running
+
+If any step fails, stop and report the error — do not continue.
diff --git a/loop/plan.md b/loop/plan.md
index 8f81cfa8..a2ec7b56 100644
--- a/loop/plan.md
+++ b/loop/plan.md
@@ -1,84 +1,59 @@
-# Overnight Plan — iOS HIG Compliance & Continued Hardening
+# Overnight Plan — 2026-03-04
-> **Format**: `- [ ]` = pending, `- [x]` = done.
-> Make at least 30 attempts on any difficult task before moving on. Loop reads this file.
-> After each phase, commit and push.
+## Phase 1: Critical Fixes
-## Phase 1: Input & Text Foundation (Prevent iOS Zoom + Readability)
+- [ ] P1-1: Brighten SVG fallbacks — increase background lightness from 18% to 28% across all 8 generators in `useImageFallback.ts` (generateSongCoverFallback, generatePodcastCoverFallback, generateNewsFallback, generateImageFallback, generatePosterFallback, generateTVSeriesFallback, generateBookCoverFallback, generatePlaceFallback). Proportionally increase all inner element lightness by +10%. TEST: run `pnpm typecheck` and visually confirm SVGs generate valid data URIs.
+- [ ] P1-2: Add `.catch(() => {})` to all cover fetch promise chains in grid components — SongGrid.vue (line 157), FilmGrid.vue (line 143), TVSeriesGrid.vue (line 160), BookGrid.vue (line 141), PodcastGrid.vue (line 130). Prevents unhandled rejection if fetch throws unexpectedly. TEST: `pnpm typecheck && pnpm lint`.
+- [ ] P1-3: Refine mobile keyboard handling — In `useVisualViewport.ts`, add debounce to viewport change handler (50ms) to prevent jittery resizing. In `App.vue`, ensure the `rootStyle` computed applies `overflow: hidden` when keyboard is open. TEST: `pnpm typecheck`.
+- [ ] P1-4: Verify service worker cleanup — Confirm `dev-dist/sw.js` contains the self-destructing SW and `vite.config.ts` has `devOptions.enabled: false`. If not, fix. TEST: read both files and verify.
-- [x] **T1** — Fix all input/textarea font sizes to prevent iOS auto-zoom. Every ``, `