/* Variation CTO — 10-question peer review for the technical director. Same warm-dark editorial language but framed as engineer-to-engineer. Uses ?role=cto to pull the technical question set + interactive widgets. */ // Inline ladder for {v, label} levels. function CTOLadder({ levels, value, onChange }) { return (
{levels.map(lv => ( ))}
); } function makeCTOQuestions(t) { const c = t.cq; const slider = (key) => ({ key, kicker: c[key].kicker, title: c[key].title, lead: c[key].lead, render: (a, set, onAuto) => ( set(key, v)} lowLabel={c[key].low} highLabel={c[key].high} leftWord={c[key].low} rightWord={c[key].high} /> ), }); const ladder = (key) => ({ key, kicker: c[key].kicker, title: c[key].title, lead: c[key].lead, render: (a, set) => set(key, v)} />, }); return [ slider('summary'), { key: 'mood', kicker: c.mood.kicker, title: c.mood.title, lead: c.mood.lead, render: (a, set, onAuto) => set('mood', v)} onAutoAdvance={onAuto} t={{ ...t, q: { ...t.q, mood: { moods: c.mood.moods } } }} /> }, { key: 'skills', kicker: c.skills.kicker, title: c.skills.title, lead: c.skills.lead, render: (a, set) => set('skills', v)} /> }, { key: 'stack', kicker: c.stack.kicker, title: c.stack.title, lead: c.stack.lead, render: (a, set) => set('stack', v)} /> }, { key: 'diff', kicker: c.diff.kicker, title: c.diff.title, lead: c.diff.lead, render: (a, set) => set('diff', v)} t={t} /> }, { key: 'pairs', kicker: c.pairs.kicker, title: c.pairs.title, lead: c.pairs.lead, render: (a, set) => set('pairs', v)} /> }, { key: 'pr', kicker: c.pr.kicker, title: c.pr.title, lead: c.pr.lead, render: (a, set) => set('pr', v)} /> }, slider('share'), ladder('grit'), { key: 'trust', kicker: c.trust.kicker, title: c.trust.title, lead: c.trust.lead, render: (a, set) => ({ ...it, levels: c.trust.levels }))} value={a.trust || {}} onChange={v => set('trust', v)} /> }, { key: 'ship', kicker: c.ship.kicker, title: c.ship.title, lead: c.ship.lead, render: (a, set) => set('ship', v)} yesLabel={c.ship.yes} noLabel={c.ship.no} reasonPlaceholder={c.ship.reasonPlaceholder} /> }, { key: 'rhythm', kicker: c.rhythm.kicker, title: c.rhythm.title, lead: c.rhythm.lead, render: (a, set) => set('rhythm', v)} weeks={8} /> }, { key: 'points', kicker: c.points.kicker, title: c.points.title, lead: c.points.lead, render: (a, set) => set('points', v)} total={100} /> }, { key: 'flow', kicker: c.flow.kicker, title: c.flow.title, lead: c.flow.lead, render: (a, set) => set('flow', v)} /> }, slider('hire'), { key: 'steal', kicker: c.steal.kicker, title: c.steal.title, lead: c.steal.lead, render: (a, set) => set('steal', v)} max={3} /> }, { key: 'sort', kicker: c.sort.kicker, title: c.sort.title, lead: c.sort.lead, render: (a, set) => set('sort', v)} /> }, { key: 'risk', kicker: c.risk.kicker, title: c.risk.title, lead: c.risk.lead, render: (a, set) => set('risk', v)} placeholder={c.risk.placeholder} severityLow={c.risk.sevLow} severityHigh={c.risk.sevHigh} /> }, ladder('readiness'), { key: 'open', kicker: c.open.kicker, title: c.open.title, lead: c.open.lead, render: (a, set) => set('open', v)} t={{ ...t, q: { ...t.q, open: c.open } }} /> }, ]; } function VariationCTO({ frameW = 1280, frameH = 820 }) { const { lang, id, setLang } = useRoute(); const t = useT(lang, 'cto'); const client = useClient(id); const questions = useMemo(() => makeCTOQuestions(t), [t]); const total = questions.length; const wiz = useWizard(id, total, 'vcto'); const { state, setAnswer, next, back, start, finish } = wiz; const stepIdx = state.step; const isStart = !state.started; const isDone = state.done; const onLast = stepIdx === total - 1; return (
{`{ }`}
{t.brand} · CTO TRACK
{t.pill} · /{lang}/{id}?role=cto
{state.started && !isDone && (
)}
{isStart ? (
{t.greetingKicker}

{t.greetingTitle(client.contact || client.name)}

{t.greetingLead}

{t.greetingMeta}
{questions.map((q, i) => ( {String(i + 1).padStart(2, '0')} {q.kicker.split('·')[1]?.trim() || ''} ))}
) : isDone ? (
{t.done.kicker}

{t.done.title}

{t.done.lead}

) : (
{questions[stepIdx].kicker}
{t.progress(stepIdx + 1, total)}

{questions[stepIdx].title}

{questions[stepIdx].lead}

{questions[stepIdx].render(state.answers, setAnswer, onLast ? finish : next)}
{stepIdx > 0 && }
)}
); } const vctoStyles = { frame: (w, h) => ({ width: w, height: h, background: 'var(--ink-bg)', color: 'var(--text)', fontFamily: "'Geist', system-ui, sans-serif", display: 'flex', flexDirection: 'column', overflow: 'hidden', position: 'relative', }), header: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '24px 56px', borderBottom: '1px solid var(--ink-line)', flexShrink: 0, }, mark: { width: 36, height: 36, borderRadius: 8, background: 'var(--accent-2)', color: 'var(--accent-ink)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: 'JetBrains Mono, monospace', fontWeight: 600, fontSize: 14, }, main: { flex: 1, padding: '48px 56px', display: 'flex', alignItems: 'flex-start', justifyContent: 'center', overflowY: 'auto', minHeight: 0 }, grid: { display: 'grid', gridTemplateColumns: '1.5fr 1fr', gap: 60, width: '100%', maxWidth: 1100, alignItems: 'center' }, h1: { fontSize: 56, lineHeight: 1.05, fontWeight: 400, letterSpacing: '-0.02em' }, h2: { fontSize: 38, lineHeight: 1.1, fontWeight: 400, letterSpacing: '-0.015em' }, lead: { fontSize: 17, lineHeight: 1.55, color: 'var(--text-2)', marginTop: 16, maxWidth: 640 }, aside: { borderLeft: '1px solid var(--ink-line)', paddingLeft: 36, display: 'flex', flexDirection: 'column' }, code: { fontFamily: 'JetBrains Mono, monospace', fontSize: 13, lineHeight: 1.6, color: 'var(--text-2)', marginTop: 18, whiteSpace: 'pre', background: 'rgba(255,255,255,0.03)', padding: 18, borderRadius: 12, border: '1px solid var(--ink-line)', }, stepGrid: { display: 'grid', gridTemplateColumns: '160px 1fr', gap: 56, width: '100%', maxWidth: 1100 }, stepLeft: { display: 'flex', flexDirection: 'column', paddingTop: 8, minHeight: 280 }, stepRight: { borderLeft: '1px solid var(--ink-line)', paddingLeft: 56 }, }; window.VariationCTO = VariationCTO; window.makeCTOQuestions = makeCTOQuestions;