// Settings dialog + Why-10-Layers dialog + error toast. const { useState: useStateD } = React; function Modal({ children, onClose }){ return (
e.stopPropagation()}> {children}
); } function SettingsDialog({ apiKey, onSave, onClose }){ const [k, setK] = useStateD(apiKey || ''); const [err, setErr] = useStateD(null); const submit = () => { if (k && k.startsWith('sk-bad')) { setErr('Invalid API key — check your dashboard.'); return; } onSave(k); onClose(); }; return (
▸ settings
API key
Set the API key for the TrueDetect engine. Stored in localStorage only — it never leaves the browser.
{setK(e.target.value); setErr(null);}} placeholder="sk-td-…" style={{ background:'var(--bg)', border:'1px solid var(--border)', padding:'10px 12px', fontSize:13, color:'var(--text)', outline:'none', borderColor: err ? 'var(--red)' : 'var(--border)', }} onFocus={e=>e.target.style.borderColor = err ? 'var(--red)' : 'var(--blue)'} onBlur={e=>e.target.style.borderColor = err ? 'var(--red)' : 'var(--border)'} /> {err &&
✗ {err}
}
format: 64-char hex prefixed sk-td-
); } function WhyLayersDialog({ onClose }){ return (
▸ methodology
Why 10 layers?
A single classifier can be fooled. Ten orthogonal forensic signals — text, structure, source — agree, disagree, and surface the disagreement.
{window.LAYER_META.map(m => ( ))}
{m.short} {m.name} {pct0(m.weight)} {window.LAYER_DESCRIPTIONS[m.key]}
); } // Toast for errors function Toast({ kind, title, body, onAction, actionLabel, onClose }){ const colorVar = kind === 'error' ? 'var(--red)' : kind === 'warn' ? 'var(--amber)' : 'var(--blue)'; const icon = kind === 'error' ? '✗' : kind === 'warn' ? '⚠' : 'ℹ'; return (
{icon}
{title}
{body}
{onAction && actionLabel && ( )}
); } window.SettingsDialog = SettingsDialog; window.WhyLayersDialog = WhyLayersDialog; window.Toast = Toast;