// 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 (
);
}
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}
{rows.map((row, i) => {
const last = i === rows.length - 1;
const border = last ? 'none' : '1px solid var(--gray-200)';
return (
{row.paper.label && {row.paper.label}}
{row.excel.label && {row.excel.label}}
{row.ks.label && {row.ks.label}}
);
})}
{rows.map((row, i) => (
))}
{t.compareFootnote}
);
}
function NotifySection({ t }) {
const [email, setEmail] = useNotifyS('');
const [scaleId, setScaleId] = useNotifyS(t.notifyScales[0].id);
const [done, setDone] = useNotifyS(false);
const [error, setError] = useNotifyS(false);
const scale = t.notifyScales.find((s) => s.id === scaleId) || t.notifyScales[0];
const submit = (e) => {
e.preventDefault();
const ok = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.trim());
if (!ok) { setError(true); return; }
setError(false);
try {
localStorage.setItem('kinesuite-notify', JSON.stringify({ email: email.trim(), scaleId, at: Date.now() }));
} catch {}
setDone(true);
};
return (
{t.notifyEyebrow}
{t.notifyTitle}
{t.notifySub}
{done ? (
{t.notifyDoneTitle}
{t.notifyDoneBody.replace('{scale}', scale.label)}
) : (
)}
);
}
Object.assign(window, {
ComparisonSection, NotifySection,
});