// KineSuite landing — comparison table + roadmap notify form. const { useState: useNotifyS } = React; function CompStatusIcon({ kind }) { const map = { yes: { glyph: '✓', color: 'var(--semantic-green)', bg: 'var(--semantic-green-bg)' }, partial: { glyph: '~', color: 'var(--semantic-yellow)', bg: 'var(--semantic-yellow-bg)' }, no: { glyph: '×', color: 'var(--semantic-red)', bg: 'var(--semantic-red-bg)' }, }; const s = map[kind] || map.no; return ( {s.glyph} ); } function CompHeaderCell({ name, muted, highlight }) { return (
{name}
); } function CompareMobileCard({ row, t }) { const cols = [ { key: 'paper', label: t.compareColPaper }, { key: 'excel', label: t.compareColExcel }, { key: 'ks', label: 'KineSuite', highlight: true }, ]; return (

{row.label}

{cols.map(({ key, label, highlight }) => { const cell = row[key]; return (
{label}
{cell.label && ( {cell.label} )}
); })}
); } function ComparisonSection({ t }) { const rows = t.compareRows; return (
{t.compareEyebrow}

{t.compareTitle}

{t.compareSub}

{t.compareCriterion}
{rows.map((row, i) => { const last = i === rows.length - 1; const border = last ? 'none' : '1px solid var(--gray-200)'; return (
{row.label}
{row.paper.label && {row.paper.label}}
{row.excel.label && {row.excel.label}}
{row.ks.label && {row.ks.label}}
); })}
{rows.map((row, i) => ( ))}

{t.compareFootnote}

); } // Replace FORMSPREE_ID with your Formspree form ID (https://formspree.io → new form → copy the id) const FORMSPREE_ENDPOINT = 'https://formspree.io/f/mbdbdzgl'; function PriorityChip({ label, checked, disabled, onClick }) { return ( ); } function NotifySection({ t }) { const [email, setEmail] = useNotifyS(''); const [priorities, setPriorities] = useNotifyS([]); const [specialty, setSpecialty] = useNotifyS(''); const [missingScale, setMissingScale] = useNotifyS(''); const [done, setDone] = useNotifyS(false); const [error, setError] = useNotifyS(false); const [sending, setSending] = useNotifyS(false); const MAX = 3; const togglePriority = (id) => { setPriorities((prev) => { if (prev.includes(id)) return prev.filter((x) => x !== id); if (prev.length >= MAX) return prev; return [...prev, id]; }); }; const reset = () => { setDone(false); setEmail(''); setPriorities([]); setSpecialty(''); setMissingScale(''); }; const submit = async (e) => { e.preventDefault(); const ok = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim()); if (!ok) { setError(true); return; } setError(false); setSending(true); const payload = { email: email.trim(), prioridades: priorities.join(', ') || '—', especialidad: specialty || '—', escala_faltante: missingScale.trim() || '—', }; try { const res = await fetch(FORMSPREE_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json', Accept: 'application/json' }, body: JSON.stringify(payload), }); if (!res.ok) throw new Error('network'); } catch { try { localStorage.setItem('kinesuite-notify', JSON.stringify({ ...payload, at: Date.now() })); } catch {} } finally { setSending(false); } setDone(true); }; return (
{t.notifyEyebrow}

{t.notifyTitle}

{t.notifySub}

{done ? (

{t.notifyDoneTitle}

{t.notifyDoneBody}

) : (
{/* ── Email ── */} {/* ── Priority chips (grouped) ── */}
{t.notifyMaxHint} = MAX ? 'var(--primary)' : 'var(--gray-400)', }}> {priorities.length}/{MAX}
{t.notifyGroups.map((group) => (
{group.label}
{group.items.map((item) => { const checked = priorities.includes(item.id); const disabled = !checked && priorities.length >= MAX; return ( togglePriority(item.id)} /> ); })}
))}
{/* ── Specialty ── */}
{t.notifySpecialtyLabel}
{t.notifySpecialtyOptions.map((opt) => { const active = specialty === opt; return ( ); })}
{/* ── Missing scale ── */}

{t.notifyFinePrint}

{t.notifyTrustNoSpam}

)}
); } Object.assign(window, { ComparisonSection, NotifySection, });