···126126 });
127127 // This line is never reached — browser redirects to the PDS
128128 } catch (err) {
129129- // Only fires if user cancels or navigates back
130129 if (err instanceof Error && err.message !== 'The user aborted a request.') {
131130 setError(err.message);
132131 }
132132+ throw err; // Re-throw so the caller can react (e.g. reset submitting state)
133133 }
134134 },
135135 [client]
+2
client/src/components/auth/LoginScreen.tsx
···2121 setIsSubmitting(true);
2222 try {
2323 await login(trimmed);
2424+ // On success the browser redirects to the PDS — this line is never reached.
2425 } catch {
2626+ // Error is already surfaced via auth context; just reset local UI state.
2527 setIsSubmitting(false);
2628 }
2729 };
+3-3
client/src/components/lobby/LobbyScreen.tsx
···22 * LobbyScreen — matchmaking interface.
33 *
44 * Shows four time-control options (1', 3', 5', 10') for real matchmaking,
55- * each with its own queue pool, and a "Play vs Self" option for untimed solo
55+ * each with its own queue pool, and a "Play with Yourself" option for untimed solo
66 * play. While searching, displays an animated indicator with the selected
77 * time control and a cancel option.
88 *
···105105 ))}
106106 </div>
107107108108- {/* Play vs Self — secondary option */}
108108+ {/* Play with Yourself — secondary option */}
109109 <button
110110 onClick={createSoloGame}
111111 disabled={!connected}
112112 className="mt-3 w-full rounded-xl border border-wood-600 bg-wood-800 px-5 py-3 text-sm text-wood-300 shadow-xl transition-colors hover:border-wood-500 hover:bg-wood-700 hover:text-wood-100 disabled:cursor-not-allowed disabled:opacity-40"
113113 >
114114- Play vs Self
114114+ Play with Yourself
115115 </button>
116116117117 {!connected && (