// ════════════════════════════════════════════════════════════════ // StartupCard — детальная карточка компании из реестра // Открывается при клике на строку CorpusPage // ════════════════════════════════════════════════════════════════ const { useMemo: useMemoStartup } = React; function StartupCard({ startup, onClose }) { const D = window.SDH_DATA; const s = startup; // generate deterministic mock detail data from id const seed = s.id; function pr(n) { return ((seed * 9301 + n * 49297) % 233280) / 233280; } const fundingRound = s.funding_usd ? (pr(1) < 0.4 ? 'Seed' : pr(1) < 0.7 ? 'Series A' : 'Series B') : 'pre-seed'; const teamSize = 3 + Math.floor(pr(2) * 28); const founded = 2018 + Math.floor(pr(3) * 7); const website = `${s.name.toLowerCase().replace(/\s+/g, '')}.com`; // related ideas (5 from corpus seed) const relatedIdeas = useMemoStartup(() => { return Array.from({ length: 3 }).map((_, k) => { const idx = Math.floor(pr(10 + k) * D.ideas.length); return D.ideas[idx]; }); }, [seed]); // mention timeseries (28 days) const timeseries = useMemoStartup(() => { return Array.from({ length: 28 }).map((_, t) => ({ value: Math.max(0, Math.round((pr(t + 50) * 8) + (t === 27 ? 6 : 0))), })); }, [seed]); const totalMentions = timeseries.reduce((sum, p) => sum + p.value, 0); // signal tags const tags = useMemoStartup(() => { const all = ['B2B', 'B2C', 'enterprise', 'SaaS', 'open-source', 'API-first', 'on-prem', 'compliance', 'мобильное', 'edge']; return all.filter((_, i) => pr(100 + i) > 0.65).slice(0, 4); }, [seed]); const similarityZone = s.similarity < 0.5 ? { hue: 'rose', label: 'низкая' } : s.similarity < 0.75 ? { hue: 'amber', label: 'средняя' } : { hue: 'emerald', label: 'высокая' }; return (
e.stopPropagation()} className="sdh-fade" style={{ background: 'var(--surface-elevated)', borderRadius: 'var(--radius-2xl)', border: '1px solid var(--border-subtle)', maxWidth: 980, width: '100%', boxShadow: 'var(--shadow-xl)', position: 'relative', overflow: 'hidden', }}> {/* close */} {/* HERO — tinted by niche hue */}
стартап № {s.id} · {s.first_seen_at}

{s.name}

{s.desc}

{s.nicheLabel} {s.sourceLabel} {s.geo} {s.funding_usd && ( ${(s.funding_usd / 1000000).toFixed(1)}M {fundingRound} )}
{/* BODY — 2-column grid */}
{/* LEFT */}
{/* Quick facts */}

факты

{/* Mentions timeline */}

упоминания за 28 дней

{totalMentions} всего упоминаний
последнее: {s.daysAgo === 0 ? 'сегодня' : `${s.daysAgo}д назад`}
{/* Signals / tags */}

сигнальные теги

{tags.length === 0 && нет распознанных тегов} {tags.map(t => {t})}
{/* RIGHT */}
{/* Similarity */}

релевантность исследованию

{s.similarity.toFixed(2)} {similarityZone.label}
пороги: 0.50 · 0.75
{/* Related ideas */}

связанные идеи стартапзавода

{relatedIdeas.map((idea, k) => ( ))}
{/* Status / next action */}

статус наблюдения

{s.similarity >= 0.75 ? 'Высокая близость к фокусу исследования. Рекомендуем поставить на еженедельный мониторинг.' : s.similarity >= 0.5 ? 'Средняя релевантность. Дополнительный сигнал нужен для принятия решения.' : 'Низкая близость. Включён в корпус как контекстная единица.'}

{/* FOOTER actions */}
esc закрыть · j/k между карточками
); } function Fact({ label, value, link }) { return (
{label}
{value}
); } window.StartupCard = StartupCard;