/* ── LOGIN PAGE — light theme + CRM motion ─────────────────────────── */ function LoginPage() { const [email, setEmail] = useState(""); const [pwd, setPwd] = useState(""); const [showPwd, setShowPwd] = useState(false); const [keepSigned, setKeepSigned] = useState(true); const [submitting, setSubmitting] = useState(false); const [error, setError] = useState(""); // Rotating brand statements const STATEMENTS = [ { line1: "Every lead", line2: "in one place.", sub: "Auto-captured from Meta, Google, and your booking links — directly in your pipeline." }, { line1: "Every reply", line2: "on autopilot.", sub: "n8n flows fire WhatsApp, email, and SMS the moment a lead is ready to talk." }, { line1: "Every deal", line2: "visible in real-time.", sub: "A live pipeline that your whole team is looking at — together — like a Figma file." }, ]; const [stmt, setStmt] = useState(0); useEffect(() => { const t = setInterval(() => setStmt(s => (s + 1) % STATEMENTS.length), 5200); return () => clearInterval(t); }, []); async function submit(e) { e.preventDefault(); setError(""); setSubmitting(true); try { const base = (window.VITE_API_URL) || "/api"; const res = await fetch(base + "/auth/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, password: pwd }), }); if (!res.ok) { let msg = "Sign-in failed"; try { const j = await res.json(); msg = j.error || j.message || msg; } catch {} throw new Error(msg); } const data = await res.json(); if (data.token) localStorage.setItem("lf_token", data.token); window.location.href = "/dashboard"; } catch (err) { setError(err.message || "Something went wrong"); setSubmitting(false); } } function loginAsDemo(e) { if (e && e.preventDefault) e.preventDefault(); localStorage.setItem("lf_token", "demo-mode"); window.location.href = "/dashboard"; } return (
{/* ════════ LEFT — Light + CRM motion ════════ */}
{/* subtle grid */}
{/* dot mesh */}
{/* drifting orbs */}
{/* TOP — logo + status */}
All systems operational
{/* MIDDLE — brand statement + CRM visual */}
{/* Statement */}
The Modern Sales CRM

{STATEMENTS[stmt].line1}
{STATEMENTS[stmt].line2}

{STATEMENTS[stmt].sub}

{/* dots */}
{STATEMENTS.map((_, i) => (
{/* CRM motion visual */}
{/* BOTTOM — testimonial */}
{["#3b82f6","#8b5cf6","#10b981","#C9A227"].map((c, i) => ( {["RP","SA","AK","VT"][i]} ))}

"Kredoo is the first CRM my team didn't fight me on. Pipeline became real overnight."

Ananya R. · VP Sales, Trustfire Realty

{[0,1,2,3,4].map(i => ( ))}
{/* ════════ RIGHT — Form ════════ */}
{/* Mobile-only logo */}
Welcome back

Sign in to
Kredoo.

Pick up where you left off. Your pipeline never stopped.

setEmail(e.target.value)} placeholder="you@company.com" autoComplete="email" />
Forgot?
setPwd(e.target.value)} placeholder="••••••••••••" autoComplete="current-password" />
{error && (
{error}
)}
OR

Explore with sample data — no account needed

Don't have an account?{" "} Start free trial

); } Object.assign(window, { LoginPage });