Build and push server image / build-and-push (push) Successful in 34s
New FrameStats (first_seen, device_wakes, photos_displayed, photos_removed, battery_reports, recharge_cycles, ota_updates_applied, config_saves), persisted alongside everything else in config.json. Incremented at the existing route/photo_queue.py call sites that already own each event -- no new instrumentation plumbing, no behavior depends on these, purely informational. GET /api/stats serves them; the web UI renders them into a native <details> "Stats" card (collapsed by default, no JS needed for the expand/collapse), fetched once on page load like the battery-history chart. Verified: TestClient run through /frame/config (wakes + first_seen + OTA-applied detection), /frame/battery (reports + recharge detection), /api/config (saves); direct photo_queue.py unit checks for advance/back/remove covering the "did the current photo actually change" distinction (removing a queued-but-not-current photo bumps photos_removed but not photos_displayed).