diff --git a/.Jules/changelog.md b/.Jules/changelog.md
index d438210..59e26ef 100644
--- a/.Jules/changelog.md
+++ b/.Jules/changelog.md
@@ -12,8 +12,11 @@
- Comprehensive `EmptyState` component for Groups and Friends pages to better guide new users.
- Toast notification system (`ToastContext`, `Toast` component) for providing non-blocking user feedback.
- Keyboard navigation support for Groups page, enabling accessibility for power users.
+- Global `ErrorBoundary` component to catch React render errors and display a dual-theme friendly fallback UI.
+- "Try Again" and "Back to Home" recovery actions for crashed application states.
### Changed
+- Wrapped `AppRoutes` in `web/App.tsx` with `ErrorBoundary` to ensure global error catching coverage.
- Updated JULES_PROMPT.md based on review of successful PRs:
- Emphasized complete system implementation over piecemeal changes
- Added best practices from successful PRs (Toast system, keyboard navigation iteration)
diff --git a/.Jules/knowledge.md b/.Jules/knowledge.md
index d69c659..4ff96a2 100644
--- a/.Jules/knowledge.md
+++ b/.Jules/knowledge.md
@@ -619,6 +619,29 @@ _Document errors and their solutions here as you encounter them._
---
+### ✅ Successful PR Pattern: Error Boundary with Dual Theme
+
+**Date:** 2026-01-14
+**Context:** Implementing global error handling
+
+**What was implemented:**
+1. Created `ErrorBoundary` class component (required for `componentDidCatch`).
+2. Created separate `ErrorFallback` functional component to support hooks (`useTheme`, `useNavigate` equivalent).
+3. Wrapped `AppRoutes` but kept `ToastContainer` outside to allow notifications during crashes.
+4. Implemented dual-theme styles (Glassmorphism/Neobrutalism) for the fallback UI.
+
+**Why it succeeded:**
+- ✅ Solved the "Class components can't use hooks" limitation by separating logic and UI.
+- ✅ Preserved the dual-theme requirement even in error states.
+- ✅ Verified using a temporary Playwright script that simulated specific render errors.
+
+**Key learnings:**
+- **Hooks in Error Boundaries:** You cannot use hooks in the `ErrorBoundary` class itself. Pass props or use a child component for the UI.
+- **Verification:** To verify `componentDidCatch`, you must throw a real error in the render phase. Event handler errors are NOT caught by React boundaries.
+- **Playwright Mocking:** When mocking routes for verification, ensure specific paths (e.g., `/users/me/balance-summary`) are registered *after* general wildcards (e.g., `**/users/me`) if the generic one handles the request first, or use strict matching.
+
+---
+
## Dependencies Reference
### Web
diff --git a/.Jules/todo.md b/.Jules/todo.md
index 894e27f..7caafa4 100644
--- a/.Jules/todo.md
+++ b/.Jules/todo.md
@@ -34,12 +34,10 @@
- Impact: Guides new users, makes app feel polished
- Size: ~70 lines
-- [ ] **[ux]** Error boundary with retry for API failures
- - Files: Create `web/components/ErrorBoundary.tsx`, wrap app
- - Context: Catch errors gracefully with retry button
- - Impact: App doesn't crash, users can recover
- - Size: ~60 lines
- - Added: 2026-01-01
+- [x] **[ux]** Error boundary with retry for API failures
+ - Completed: 2026-01-14
+ - Files modified: `web/components/ErrorBoundary.tsx`, `web/App.tsx`
+ - Impact: Catches render errors, prevents white screens, and provides "Try Again" / "Back to Home" recovery options with dual-theme support.
### Mobile
diff --git a/web/App.tsx b/web/App.tsx
index 1461005..66511c9 100644
--- a/web/App.tsx
+++ b/web/App.tsx
@@ -6,6 +6,7 @@ import { AuthProvider, useAuth } from './contexts/AuthContext';
import { ThemeProvider } from './contexts/ThemeContext';
import { ToastProvider } from './contexts/ToastContext';
import { ToastContainer } from './components/ui/Toast';
+import { ErrorBoundary } from './components/ErrorBoundary';
import { Auth } from './pages/Auth';
import { Dashboard } from './pages/Dashboard';
import { Friends } from './pages/Friends';
@@ -51,8 +52,10 @@ const App = () => {
+ We encountered an unexpected error. +
+ {error && ( +