function ScreenLogin({ onSignedIn }) { const [mode, setMode] = useState('login'); // 'login' | 'recover' const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [showPw, setShowPw] = useState(false); const [loading, setLoading] = useState(false); const [err, setErr] = useState(null); const [info, setInfo] = useState(null); const submit = async (e) => { e.preventDefault(); setErr(null); setInfo(null); if (!email.trim()) { setErr('Informe o e-mail.'); return; } setLoading(true); try { if (mode === 'login') { const { data, error } = await scpAuth.signIn(email.trim(), password); if (error) { setErr(traduzErroAuth(error.message)); return; } onSignedIn?.(data.session); } else { const { error } = await scpAuth.resetPassword(email.trim()); if (error) { setErr(traduzErroAuth(error.message)); return; } setInfo('E-mail de recuperação enviado. Verifique sua caixa de entrada.'); } } finally { setLoading(false); } }; return (
{/* Lado esquerdo: imagem temática + manchete + diferenciais */} {/* Lado direito: form de login */}
SCP Sistema de Cotação de Preços

{mode === 'login' ? 'Entrar na sua conta' : 'Recuperar senha'}

{mode === 'login' ? 'Use seu e-mail e senha cadastrados.' : 'Te enviamos um link para definir uma nova senha.'}

{err &&
{err}
} {info &&
{info}
} {mode === 'login' && ( )} }> {loading ? 'Aguarde…' : mode === 'login' ? 'Entrar' : 'Enviar link'}
{mode === 'login' ? ( ) : ( )} v 1.2.4
Desenvolvido por JuFlow Digital · © 2026
); } function traduzErroAuth(msg) { if (!msg) return 'Falha ao entrar.'; const m = msg.toLowerCase(); if (m.includes('invalid login credentials')) return 'E-mail ou senha incorretos.'; if (m.includes('email not confirmed')) return 'Confirme seu e-mail antes de entrar.'; if (m.includes('user not found')) return 'Usuário não encontrado.'; if (m.includes('rate limit')) return 'Muitas tentativas. Aguarde alguns minutos.'; return msg; } (function injectLoginCss() { if (document.getElementById('scp-login-css')) return; const s = document.createElement('style'); s.id = 'scp-login-css'; s.textContent = ` .scp-login { position: fixed; inset: 0; display: grid; grid-template-columns: 1.15fr 1fr; background: var(--bg); overflow: hidden; } /* ============ Lado esquerdo (visual) ============ */ .scp-login-visual { position: relative; overflow: hidden; display: flex; flex-direction: column; justify-content: center; padding: 60px 64px; } /* Camada 1: foto temática — restaurante/cozinha (Unsplash) */ .scp-login-bg { position: absolute; inset: -20px; background-image: linear-gradient(120deg, oklch(0.10 0.012 250 / .80) 0%, oklch(0.12 0.025 250 / .65) 50%, oklch(0.10 0.012 250 / .85) 100%), url('https://images.unsplash.com/photo-1414235077428-338989a2e8c0?auto=format&fit=crop&w=1920&q=70'); background-size: cover; background-position: center; filter: blur(1px) saturate(1.05); animation: bgDriftIn 1.2s ease-out both; } @keyframes bgDriftIn { from { opacity: 0; transform: scale(1.06); } to { opacity: 1; transform: scale(1); } } /* Camada 2: mesh gradient premium */ .scp-login-mesh { position: absolute; inset: 0; background: radial-gradient(700px 500px at 18% 22%, oklch(0.52 0.18 160 / .42), transparent 60%), radial-gradient(600px 400px at 78% 78%, oklch(0.46 0.16 285 / .32), transparent 65%), radial-gradient(500px 400px at 50% 50%, oklch(0.42 0.14 230 / .18), transparent 70%); mix-blend-mode: screen; animation: meshPulse 14s ease-in-out infinite alternate; } @keyframes meshPulse { 0% { transform: translate3d(0,0,0) scale(1); opacity: .9; } 50% { transform: translate3d(-30px, 20px, 0) scale(1.05); opacity: 1; } 100% { transform: translate3d(20px, -30px, 0) scale(1.02); opacity: .85; } } /* Camada 3: grain sutil */ .scp-login-grain { position: absolute; inset: 0; pointer-events: none; opacity: .35; mix-blend-mode: overlay; background-image: url("data:image/svg+xml;utf8,"); } /* Conteúdo do lado visual */ .scp-login-visual-content { position: relative; z-index: 2; max-width: 560px; display: flex; flex-direction: column; gap: 18px; animation: fadein .8s ease both; } .scp-login-tag { display: inline-flex; align-items: center; gap: 8px; align-self: flex-start; padding: 6px 12px; border-radius: 999px; background: oklch(0.24 0.05 160 / .55); border: 1px solid oklch(0.40 0.08 160 / .55); color: oklch(0.92 0.13 160); font-size: 11.5px; font-weight: 600; letter-spacing: .02em; backdrop-filter: blur(8px); } .scp-login-tag .dot { width: 7px; height: 7px; border-radius: 999px; background: oklch(0.82 0.16 160); box-shadow: 0 0 12px oklch(0.78 0.18 160 / .8); animation: pulseDotLogin 1.8s ease-out infinite; } @keyframes pulseDotLogin { 50% { transform: scale(1.3); opacity: .7; } } .scp-login-visual h1 { margin: 0; font-size: 54px; font-weight: 600; line-height: 1.05; letter-spacing: -0.035em; color: oklch(0.97 0.005 250); text-shadow: 0 4px 24px rgba(0,0,0,0.55); } .scp-login-visual h1 .hl { background: linear-gradient(120deg, oklch(0.86 0.14 160), oklch(0.78 0.18 200)); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; } .scp-login-visual > .scp-login-visual-content > p { margin: 0; color: oklch(0.85 0.012 250); font-size: 15px; line-height: 1.6; max-width: 500px; text-shadow: 0 1px 12px rgba(0,0,0,0.45); } .scp-login-stats { display: grid; grid-template-columns: repeat(3, auto); gap: 28px; margin-top: 14px; padding-top: 22px; border-top: 1px solid oklch(0.50 0.014 250 / .25); } .scp-login-stats > div { display: flex; flex-direction: column; gap: 2px; } .scp-login-stats strong { font-size: 30px; font-weight: 700; letter-spacing: -0.025em; font-family: var(--font-sans); color: oklch(0.96 0.14 160); text-shadow: 0 2px 16px oklch(0.50 0.16 160 / .35); } .scp-login-stats span { font-size: 11.5px; color: oklch(0.78 0.012 250 / .9); text-transform: uppercase; letter-spacing: .08em; font-weight: 600; } .scp-login-quote { margin-top: 22px; padding: 16px 18px; background: oklch(0.18 0.012 250 / .55); backdrop-filter: blur(14px); border: 1px solid oklch(0.42 0.014 250 / .35); border-radius: 14px; display: grid; grid-template-columns: 18px 1fr; gap: 12px; align-items: start; box-shadow: 0 12px 32px -16px rgba(0,0,0,0.6); } .scp-login-quote > svg { color: oklch(0.86 0.14 160); margin-top: 4px; } .scp-login-quote span { display: block; font-size: 14px; color: oklch(0.92 0.012 250); font-style: italic; line-height: 1.5; font-family: 'Instrument Serif', serif; letter-spacing: .005em; } .scp-login-quote small { display: block; margin-top: 8px; font-size: 11.5px; color: var(--fg-3); letter-spacing: .04em; font-style: normal; font-family: var(--font-sans); } /* ============ Lado direito (form) ============ */ .scp-login-side { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40px; background: radial-gradient(80% 80% at 50% 30%, oklch(0.18 0.014 250) 0%, oklch(0.135 0.012 250) 100%); border-left: 1px solid var(--border-soft); } .scp-login-card { position: relative; z-index: 2; width: 100%; max-width: 380px; padding: 32px 30px 22px; display: flex; flex-direction: column; gap: 14px; background: oklch(0.20 0.012 250 / .9); backdrop-filter: blur(20px) saturate(1.1); -webkit-backdrop-filter: blur(20px) saturate(1.1); border: 1px solid oklch(0.42 0.014 250 / .35); border-radius: 18px; box-shadow: 0 24px 80px -20px rgba(0,0,0,0.7), 0 1px 0 oklch(0.65 0.014 250 / .10) inset; } .scp-login-brand { display: flex; align-items: center; gap: 12px; margin-bottom: 4px; } .scp-login-brand .t { display: block; font-weight: 700; font-size: 18px; letter-spacing: -0.01em; } .scp-login-brand .s { display: block; font-size: 12px; color: var(--fg-3); margin-top: 2px; } .scp-login-card h2 { margin: 6px 0 2px; font-size: 22px; font-weight: 600; letter-spacing: -0.02em; } .scp-login-card > p { margin: 0 0 6px; color: var(--fg-3); font-size: 13px; line-height: 1.5; } .scp-login-card .scp-field { gap: 6px; } .scp-login-card .scp-field > span { font-size: 12px; color: var(--fg-3); font-weight: 600; } .scp-login-card .scp-input { width: 100%; } .scp-login-card .scp-btn.kind-primary { justify-content: center; margin-top: 4px; } .scp-login-alert { padding: 10px 12px; border-radius: 10px; font-size: 12.5px; border: 1px solid; } .scp-login-alert.tone-coral { background: oklch(0.26 0.08 25 / .35); border-color: oklch(0.42 0.10 25 / .55); color: oklch(0.88 0.14 25); } .scp-login-alert.tone-emerald { background: oklch(0.26 0.06 160 / .35); border-color: oklch(0.42 0.10 160 / .55); color: oklch(0.92 0.14 160); } .scp-login-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 8px; padding-top: 14px; border-top: 1px solid var(--border-soft); font-size: 11.5px; color: var(--fg-3); } .scp-login-foot button { color: oklch(0.86 0.14 160); font-weight: 600; transition: color .12s; } .scp-login-foot button:hover { color: oklch(0.94 0.14 160); } .scp-login-version { font-family: 'JetBrains Mono', monospace; font-size: 10.5px; } .scp-login-copy { margin-top: 22px; font-size: 12px; color: oklch(0.55 0.012 250); letter-spacing: .02em; text-align: center; } .scp-login-copy strong { color: oklch(0.86 0.13 160); font-weight: 600; } /* ============ Responsivo ============ */ @media (max-width: 980px) { .scp-login { grid-template-columns: 1fr; } .scp-login-visual { padding: 36px 28px 28px; min-height: 320px; } .scp-login-visual h1 { font-size: 36px; } .scp-login-visual .scp-login-quote { display: none; } .scp-login-stats { gap: 18px; } .scp-login-stats strong { font-size: 22px; } .scp-login-side { border-left: 0; border-top: 1px solid var(--border-soft); } } @media (max-width: 560px) { .scp-login-visual { padding: 28px 22px; min-height: 240px; } .scp-login-visual h1 { font-size: 28px; } .scp-login-visual > .scp-login-visual-content > p { font-size: 13.5px; } .scp-login-stats { display: none; } .scp-login-side { padding: 24px 18px; } } `; document.head.appendChild(s); })(); window.ScreenLogin = ScreenLogin;