diff --git a/src/App.css b/src/App.css index e92f2fd..63b07e7 100644 --- a/src/App.css +++ b/src/App.css @@ -104,7 +104,7 @@ display: flex; flex-direction: column; gap: 1.75rem; - background: var(--color-surface); + background: #fff; border-radius: 24px; border-top: 4px solid #22c55e; padding: 2rem 1.75rem; @@ -168,6 +168,29 @@ text-align: left; } +/* Login page is always light — ignore dark / liquid-glass themes */ +[data-theme="dark"] .lp, +[data-theme="liquid-glass"] .lp { + background: linear-gradient(160deg, #eef6ee 0%, #dcfce7 100%); +} +[data-theme="dark"] .lp__form, +[data-theme="liquid-glass"] .lp__form { + background: #fff; + backdrop-filter: none; + -webkit-backdrop-filter: none; + border: none; + border-top: 4px solid #22c55e; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08); +} +[data-theme="dark"] .lp__tagline, +[data-theme="liquid-glass"] .lp__tagline { + color: #4b505a; +} +[data-theme="dark"] .lp__privacy, +[data-theme="liquid-glass"] .lp__privacy { + color: #6d727a; +} + /* kept for other callers */ .login-card__error { margin: 0; @@ -3215,8 +3238,7 @@ [data-theme="liquid-glass"] .settings-tutorial-btn, [data-theme="liquid-glass"] .settings-clear-btn, [data-theme="liquid-glass"] .settings-signout-btn, -[data-theme="liquid-glass"] .bottom-nav, -[data-theme="liquid-glass"] .lp__form { +[data-theme="liquid-glass"] .bottom-nav { background: var(--glass-bg); backdrop-filter: var(--glass-blur); -webkit-backdrop-filter: var(--glass-blur); @@ -3497,6 +3519,21 @@ box-shadow: 0 1px 8px rgba(74, 222, 128, 0.1); } +/* Login page is always light — force button to light style */ +[data-theme="dark"] .lp .google-sign-in-btn, +[data-theme="liquid-glass"] .lp .google-sign-in-btn { + background: #fff; + border-color: #dadce0; + color: #3c4043; +} + +[data-theme="dark"] .lp .google-sign-in-btn:hover:not(:disabled), +[data-theme="liquid-glass"] .lp .google-sign-in-btn:hover:not(:disabled) { + background: #f8f9fa; + border-color: #dadce0; + box-shadow: 0 1px 6px rgba(0, 0, 0, 0.1); +} + /* ============================ WELCOME MODAL ============================ */ diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index ee87da3..4275350 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -191,11 +191,12 @@ export function AuthProvider({ children }: { children: ReactNode }) { } useEffect(() => { - // Handle returning from a redirect sign-in (mobile flow) + // Handle returning from a redirect sign-in (Safari / iOS / Android WebViews) getRedirectResult(auth).catch((error) => { console.error('[Auth] Redirect sign-in error:', error) setAuthError(error instanceof Error ? error.message : 'Sign-in failed') }) + // onAuthStateChanged below handles the successful redirect result automatically const unsubscribe = onAuthStateChanged(auth, async (u) => { setUser(u) @@ -218,6 +219,14 @@ export function AuthProvider({ children }: { children: ReactNode }) { async function signInWithGoogle() { setAuthError(null) await setPersistence(auth, browserLocalPersistence) + + // Safari blocks cross-origin storage in popups (ITP), so use redirect flow + const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent) + if (isSafari) { + await signInWithRedirect(auth, googleProvider) + return + } + try { await signInWithPopup(auth, googleProvider) } catch (err: unknown) { diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index 504e70c..ea2f8a5 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -40,7 +40,7 @@ export default function LoginPage() { // Without the `user` check here, the login form flashes for one frame // between loading→false and the useEffect redirect. if (loading || signingIn || user) { - return + return
} return (