const SignIn = ({ onSignIn }) => { // step: 'credentials' → 'mfa' → reload const [step, setStep] = React.useState('credentials'); const [email, setEmail] = React.useState(''); const [password, setPassword] = React.useState(''); const [mfaToken, setMfaToken] = React.useState(null); const [mfaCode, setMfaCode] = React.useState(''); const [methods, setMethods] = React.useState([]); const [busy, setBusy] = React.useState(false); const [error, setError] = React.useState(null); const [info, setInfo] = React.useState(null); async function postJSON(path, body) { const r = await fetch(window.CHVault.apiRoot + path, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(body), }); let j = {}; try { j = await r.json(); } catch {} if (!r.ok) { const msg = (j && (j.detail?.message || j.detail || j.message)) || `HTTP ${r.status}`; const err = new Error(msg); err.status = r.status; err.payload = j; throw err; } return j; } async function submitCredentials(e) { e.preventDefault(); setBusy(true); setError(null); setInfo(null); try { const j = await postJSON('/api/v1/auth/login', { email, password }); if (j.requires_mfa) { setMfaToken(j.mfa_session_token); setMethods(j.methods_available || (j.mfa_type ? [j.mfa_type] : ['totp'])); setStep('mfa'); setBusy(false); return; } // No MFA — cookie is set, reload into the dashboard. window.location.reload(); } catch (e) { setError(e.message || 'Sign-in failed'); setBusy(false); } } async function submitMfa(e) { e.preventDefault(); setBusy(true); setError(null); try { await postJSON('/api/v1/auth/mfa-verify', { mfa_session_token: mfaToken, totp_code: mfaCode.replace(/\D/g, '').slice(0, 6), }); window.location.reload(); } catch (e) { setError(e.message || 'MFA verification failed'); setBusy(false); } } async function sendEmailCode() { setInfo(null); setError(null); setBusy(true); try { await postJSON('/api/v1/auth/mfa-email/challenge', { mfa_session_token: mfaToken }); setInfo('A 6-digit code was emailed to you. Enter it below.'); } catch (e) { setError(e.message); } setBusy(false); } async function sendSmsCode() { setInfo(null); setError(null); setBusy(true); try { await postJSON('/api/v1/auth/mfa-sms/challenge', { mfa_session_token: mfaToken }); setInfo('A 6-digit code was texted to you. Enter it below.'); } catch (e) { setError(e.message); } setBusy(false); } const wrap = { minHeight: '100vh', display: 'grid', gridTemplateColumns: '1fr 1fr', background: 'var(--bg-bone)' }; const left = { padding: '64px 56px', display: 'flex', flexDirection: 'column', justifyContent: 'space-between', background: 'var(--bg-parchment)', borderRight: '1px solid var(--border-1)' }; const right = { display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 64 }; const eyebrow = { fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--accent-clinical)' }; const h1 = { fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 48, lineHeight: 1.05, letterSpacing: '-0.02em', margin: '14px 0 12px', color: 'var(--fg-1)' }; const sub = { fontSize: 16, color: 'var(--fg-2)', maxWidth: 420, lineHeight: 1.55 }; const eq = { marginTop: 32, fontFamily: 'var(--font-equation)', fontStyle: 'italic', color: 'var(--fg-1)', fontSize: 18, padding: 18, background: 'var(--bg-bone)', border: '1px solid var(--border-1)', borderRadius: 12 }; const meta = { fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--fg-3)' }; const card = { width: '100%', maxWidth: 420, padding: 32, background: 'var(--bg-parchment)', border: '1px solid var(--border-1)', borderRadius: 16, boxShadow: 'var(--elev-2)' }; const field = { display: 'flex', flexDirection: 'column', gap: 6, marginBottom: 16 }; const label = { fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase', color: 'var(--fg-3)' }; const input = { background: 'var(--bg-bone)', border: '1px solid var(--border-1)', borderRadius: 8, padding: '12px 14px', color: 'var(--fg-1)', fontFamily: 'var(--font-sans)', fontSize: 14, outline: 'none' }; const cta = (disabled) => ({ width: '100%', padding: '14px', borderRadius: 10, background: disabled ? 'var(--border-2)' : 'var(--accent-clinical)', color: 'white', border: 'none', fontWeight: 600, fontSize: 14, cursor: disabled ? 'wait' : 'pointer' }); return (
Conceptual Health®
Guardian Orb™

Your CH score, alive.

Eight axes. One equation. Track your multidimensional wellness in real time. Earn HCR (HEALTHCOIN™) for every healthy behavior.

CH = (S × Sp)C × (T + E)p × (ER × RS)C/3
HIPAA · AES-256-GCM · Patent Pending 63/921,717
{step === 'credentials' ? (
Sign In

Welcome back.

{error &&
{error}
}
setEmail(e.target.value)} placeholder="you@example.com" />
setPassword(e.target.value)} placeholder="••••••••" />
Forgot password → {' · '} Create account →
By signing in you agree to the Conceptual Health Standard.
) : (
Two-Factor Verification

Enter your 6-digit code.

Open your Guardian Orb Authenticator or third-party authenticator (Google Authenticator, 1Password, etc.) and enter the current code.
{error &&
{error}
} {info &&
{info}
}
setMfaCode(e.target.value.replace(/\D/g, '').slice(0,6))} placeholder="••••••" />
{methods.includes('email') && Email me a code} {methods.includes('email') && methods.includes('sms') && ' · '} {methods.includes('sms') && Text me a code}
{ setStep('credentials'); setMfaCode(''); setError(null); }} style={{ color: 'var(--fg-3)', textDecoration: 'underline', cursor: 'pointer' }}>← Use a different account
)}
); }; window.SignIn = SignIn;