// app/screen-login.jsx — token-paste login, a quote from your own notes // overlaid on photography. Responsive across desktop / tablet / mobile. function LoginScreen() { const { login, layout, state, set } = useApp(); const [token, setToken] = React.useState(''); const [busy, setBusy] = React.useState(false); const isMobile = layout === 'mobile'; const err = state.loginError; // Bearer auth is enforced on the live API: a wrong token rejects and login() // keeps us on this screen with state.loginError set. Submit clears any prior // error, shows a checking state, and lets the store decide success/failure. const submit = async (t) => { if (busy) return; if (err) set({ loginError: null }); setBusy(true); await login(t); setBusy(false); // on success this screen has already unmounted }; const photo = (
from your notes

“Doubled the garlic last time — better. Save the poaching liquid; it's practically stock.”

Sichuan-style cold chicken · cooked 12 times
); const form = (

Welcome back.

Paste your cookbook token to unlock your library. This is your kitchen — not a SaaS gateway. Magic-link sign-in lands with multi-user.

{ setToken(e.target.value); if (err) set({ loginError: null }); }} placeholder="lc_live_••••••••••••••••" onKeyDown={(e) => { if (e.key === 'Enter') submit(token); }} aria-invalid={err ? 'true' : 'false'} style={{ width: '100%', marginTop: 10, padding: '15px 16px', borderRadius: 12, background: 'rgba(0,0,0,0.35)', border: `1px solid ${err ? 'var(--tomato)' : 'var(--hairline)'}`, color: 'var(--ink)', fontFamily: 'var(--mono)', fontSize: 15, outline: 'none', boxSizing: 'border-box' }} /> {err && (
{err}
)}
submit(token)} disabled={busy} style={{ width: '100%', marginTop: 16, minHeight: 56, opacity: busy ? 0.65 : 1 }}> {busy ? 'Checking…' : Open my cookbook }
); if (isMobile) { return (
{photo}
{form}
); } return (
{photo}
{form}
); } Object.assign(window, { LoginScreen });