// intake.jsx — the client-facing "Ledger Spine" intake questionnaire.
// Ported from the Claude Design handoff ("Intake — Ledger Spine"). Wrapped in an
// IIFE so its hooks/components stay local (the no-build setup runs every JSX file
// in the shared global scope, so top-level names would otherwise collide).
//
// Persistence: all answers autosave to the backend via window.API (PUT /api/intake,
// 600ms debounce) — no localStorage. Uploads and "Questions for Linea" hit the API.
// Stage 2 unlocks when the server marks the intake stage2_unlocked (admin-driven);
// Stage 3 (the report) unlocks when the assessment is delivered.

(function () {
  'use strict';
  const { useState, useEffect, useRef, useMemo, useCallback } = React;
  const D = window.INTAKE_DATA;
  // Document defs keyed by id, so each Stage-1 section can pull just the cards
  // it owns (org/jobs, systems/report, sops) without iterating the whole list.
  const DOC = {};
  D.DOCS.forEach(d => { DOC[d.id] = d; });

  // ── palette / shared style fragments ───────────────────────────────────────
  const C = {
    paper: '#fafafa', white: '#ffffff', paper2: '#f5f4f0', paper3: '#efeee9',
    ink: '#0a0a0a', ink1: '#2a2c30', sec: '#5e6068', meta: '#8b8d94', dim: '#b8bac0',
    blue: '#2e5dff', blueDk: '#1c3db8', blueTint: '#f4f6fe', good: '#1a8f59', warn: '#a06d10',
    rule: 'rgba(10,10,10,0.09)', rule2: 'rgba(10,10,10,0.14)',
  };
  const INPUT = {
    border: '1px solid ' + C.rule2, borderRadius: 6, background: C.white, color: C.ink,
    fontFamily: "'Outfit',sans-serif", fontSize: 14, padding: '0 13px', height: 44,
    width: '100%', boxSizing: 'border-box',
  };
  const TEXTAREA = Object.assign({}, INPUT, { height: 'auto', padding: '11px 13px', lineHeight: 1.5, resize: 'vertical' });

  function cls(...a) { return a.filter(Boolean).join(' '); }
  function uid() { return 'x' + Math.random().toString(36).slice(2, 9); }

  // ── chips ───────────────────────────────────────────────────────────────────
  function Chip({ label, on, onClick, small }) {
    return (
      <button type="button" onClick={onClick} aria-pressed={on}
        className="intk-chip"
        style={{
          fontFamily: "'Outfit',sans-serif", cursor: 'pointer', borderRadius: 999,
          fontSize: small ? 12 : 13, minHeight: small ? 32 : 38, padding: small ? '0 11px' : '0 14px',
          border: '1px solid ' + (on ? 'transparent' : C.rule2),
          background: on ? C.ink : C.white, color: on ? C.white : C.ink1,
          fontWeight: on ? 600 : 400, transition: 'all .15s',
        }}>{label}</button>
    );
  }
  function ChipRow({ options, value, onPick, multi, small }) {
    const arr = multi ? (value || []) : null;
    return (
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 7 }} role="group">
        {options.map(o => (
          <Chip key={o} label={o} small={small}
            on={multi ? arr.indexOf(o) >= 0 : value === o}
            onClick={() => {
              if (multi) {
                const next = arr.indexOf(o) >= 0 ? arr.filter(x => x !== o) : arr.concat([o]);
                onPick(next);
              } else { onPick(value === o ? '' : o); }
            }} />
        ))}
      </div>
    );
  }

  // ── small inline icons ────────────────────────────────────────────────────
  const Pencil = () => <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 20h9" /><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z" /></svg>;
  const Trash = () => <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M3 6h18M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2m2 0v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6" /></svg>;
  const Check = () => <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><path d="M20 6 9 17l-5-5" /></svg>;
  const SignOutIcon = () => <svg width="13" height="13" viewBox="0 0 16 16" aria-hidden="true"><path d="M 6 2.5 H 3.5 a 1 1 0 0 0 -1 1 v 9 a 1 1 0 0 0 1 1 H 6 M 10 11 l 3 -3 -3 -3 M 13 8 H 6" fill="none" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round" /></svg>;
  // Small action icons for the Section A document rows.
  const sv = (d, w) => <svg width={w || 13} height={w || 13} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">{d}</svg>;
  const IconUpload = () => sv(<><path d="M12 16V4" /><path d="M7 9l5-5 5 5" /><path d="M4 16v3a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-3" /></>);
  const IconAddManual = () => sv(<><path d="M3 6h12M3 12h9M3 18h9" /><path d="M18 13v6M15 16h6" /></>);
  const IconKickoff = () => sv(<><rect x="3" y="4.5" width="18" height="16" rx="2" /><path d="M16 2.5v4M8 2.5v4M3 10h18" /></>);
  const IconNA = () => sv(<><circle cx="12" cy="12" r="9" /><path d="M5.6 5.6l12.8 12.8" /></>);
  const IconDescribe = () => sv(<><path d="M4 6h16M4 12h16M4 18h10" /></>);
  // Per-document header icons (Section A).
  const DOC_ICON = {
    org: () => sv(<><rect x="9" y="2.5" width="6" height="5" rx="1" /><rect x="2.5" y="16.5" width="6" height="5" rx="1" /><rect x="15.5" y="16.5" width="6" height="5" rx="1" /><path d="M12 7.5v4M5.5 16.5v-2.5h13v2.5M12 14v-2.5" /></>, 17),
    jobs: () => sv(<><circle cx="12" cy="8" r="3.5" /><path d="M5.5 20a6.5 6.5 0 0 1 13 0" /></>, 17),
    systems: () => sv(<><rect x="2.5" y="4" width="19" height="13" rx="2" /><path d="M8 21h8M12 17v4" /></>, 17),
    sops: () => sv(<><path d="M9 5.5h10M9 12h10M9 18.5h10" /><path d="M3.5 5l1 1 1.8-2M3.5 11.5l1 1 1.8-2M3.5 18l1 1 1.8-2" /></>, 17),
    report: () => sv(<><rect x="3" y="3" width="18" height="18" rx="2" /><path d="M7.5 15.5v-3M12 15.5v-7M16.5 15.5v-5" /></>, 17),
  };
  const LineaMark = ({ light }) => (
    <span style={{ display: 'inline-flex', alignItems: 'center', letterSpacing: '-0.02em', fontWeight: 600, fontSize: 12, color: light ? '#8b8d94' : C.meta, lineHeight: 1 }}>
      Linea<span style={{ display: 'block', width: 4, height: 4, borderRadius: '50%', background: C.blue, marginLeft: 2, marginTop: 2 }} />
    </span>
  );

  // ── serialization helpers ────────────────────────────────────────────────
  function blankUnit() { return { name: '', head: '', delivers: '', roles: [{ title: '', count: '' }], open: true }; }
  function blankSystem() { return { name: '', info: [], units: [], open: true }; }

  // A Section-A document row can now combine several inputs (upload + describe +
  // add-manually, etc.). `modes` holds the toggled non-upload choices; uploads
  // are tracked by `files`. These helpers also read the legacy single `choice`.
  function docModes(r) { if (!r) return []; if (Array.isArray(r.modes)) return r.modes; if (r.choice && r.choice !== 'upload') return [r.choice]; return []; }
  function docFiles(r) { return (r && r.files) || []; }
  function docHasUpload(r) { return docFiles(r).length > 0 || (r && r.choice === 'upload'); }
  function docAnswered(r) { return docHasUpload(r) || docModes(r).length > 0; }
  // The status chips for a doc row (upload / add-manually / described / N/A).
  // Shared by Section A's Org Chart row and Section B so they read identically.
  function docStatusParts(id, r, units, systems) {
    const out = [];
    const files = docFiles(r);
    if (docHasUpload(r)) out.push({ k: 'upload', l: files.length ? files.length + ' file' + (files.length === 1 ? '' : 's') + ' uploaded' : 'Uploaded', fg: '#1a8f59' });
    const modes = docModes(r);
    const builder = id === 'org' ? 'units' : (id === 'systems' ? 'systems' : null);
    if (builder) {
      const n = (builder === 'units' ? (units || []) : (systems || [])).filter(x => (x.name || '').trim()).length;
      if (modes.indexOf('select') >= 0 || n > 0) out.push({ k: 'select', l: n + ' added manually', fg: '#1c3db8' });
    }
    if (modes.indexOf('describe') >= 0) out.push({ k: 'describe', l: 'Described', fg: '#1c3db8' });
    if (modes.indexOf('none') >= 0) out.push({ k: 'none', l: 'N/A', fg: '#8b8d94' });
    return out;
  }

  // counts answered fields per section for the ledger spine
  function sectionCount(s, id) {
    if (id === 'A') {
      const named = s.units.filter(u => (u.name || '').trim()).length;
      const fields = [!!(s.oneliner || '').trim(), !!s.headcount, named > 0, !!(s.priorities || '').trim(), !!(s.oneThing || '').trim()];
      return { done: fields.filter(Boolean).length, total: 5 };
    }
    if (id === 'B') {
      const named = s.systems.filter(x => (x.name || '').trim()).length;
      const fields = [named > 0, !!(s.hideSheets || '').trim(), !!(s.hideEmail || '').trim(), !!(s.hideHead || '').trim()];
      return { done: fields.filter(Boolean).length, total: 4 };
    }
    if (id === 'C') {
      const fields = [!!(s.repetitive || '').trim(), !!(s.costly || '').trim(), !!(s.handoff || '').trim()];
      return { done: fields.filter(Boolean).length, total: 3 };
    }
    return { done: 0, total: 0 };
  }

  // ═══════════════════════════════════════════════════════════════════════════
  function IntakeApp({ client, initial, onOpenReport, onSignOut, onChangePassword }) {
    const init = initial || {};
    const ans = init.answers || {};

    // server-driven status
    const [status, setStatus] = useState(init.status || 'in_progress');
    const stage2Unlocked = ['stage2_unlocked', 'stage2_submitted', 'delivered'].indexOf(status) >= 0;
    const reportDelivered = !!init.reportDelivered;

    // editable answer state
    const [active, setActive] = useState(ans.active || init.activeSection || 'A');
    const [briefSeen, setBriefSeen] = useState(!!ans.briefSeen || status !== 'in_progress');
    const [docs, setDocs] = useState(ans.docs || {});
    const [oneliner, setOneliner] = useState(ans.oneliner || '');
    const [headcount, setHeadcount] = useState(ans.headcount || '');
    const [units, setUnits] = useState(ans.units || []);
    const [priorities, setPriorities] = useState(ans.priorities || '');
    const [oneThing, setOneThing] = useState(ans.oneThing || '');
    const [systems, setSystems] = useState(ans.systems || []);
    const [hideSheets, setHideSheets] = useState(ans.hideSheets || '');
    const [hideEmail, setHideEmail] = useState(ans.hideEmail || '');
    const [hideHead, setHideHead] = useState(ans.hideHead || '');
    const [repetitive, setRepetitive] = useState(ans.repetitive || '');
    const [costly, setCostly] = useState(ans.costly || '');
    const [costlyEst, setCostlyEst] = useState(ans.costlyEst || '');
    const [handoff, setHandoff] = useState(ans.handoff || '');
    const [aiExp, setAiExp] = useState(ans.aiExp || '');
    const [aiWhy, setAiWhy] = useState(ans.aiWhy || '');
    const [additional, setAdditional] = useState(ans.additional || '');

    // Stage 2 working copies — seed from prefill the first time it unlocks.
    const seedWf = ans.wfs || (init.stage2Prefill && init.stage2Prefill.workflows) || null;
    const seedSys = ans.sysd || (init.stage2Prefill && init.stage2Prefill.systems) || null;
    const [wfs, setWfs] = useState(seedWf);
    const [sysd, setSysd] = useState(seedSys);

    // questions + uploads (server-backed)
    const [questions, setQuestions] = useState(init.questions || []);
    const [uploads, setUploads] = useState(init.uploads || []);

    // transient UI
    const [savedAt, setSavedAt] = useState(null);
    const [saving, setSaving] = useState(false);
    const [saveError, setSaveError] = useState(false);
    const [tick, setTick] = useState(0);
    const [undo, setUndo] = useState(null);
    const [qOpen, setQOpen] = useState(false);
    const [qDraft, setQDraft] = useState('');
    const [finishLater, setFinishLater] = useState(false);

    // refresh "saved N min ago" label
    useEffect(() => { const t = setInterval(() => setTick(x => x + 1), 30000); return () => clearInterval(t); }, []);

    // ── serialize + autosave ──────────────────────────────────────────────────
    const serialize = useCallback(() => ({
      briefSeen, active, docs, oneliner, headcount, units, priorities, oneThing,
      systems, hideSheets, hideEmail, hideHead, repetitive, costly, costlyEst, handoff, aiExp, aiWhy,
      additional, wfs, sysd,
    }), [briefSeen, active, docs, oneliner, headcount, units, priorities, oneThing, systems, hideSheets, hideEmail, hideHead, repetitive, costly, costlyEst, handoff, aiExp, aiWhy, additional, wfs, sysd]);

    const saveTimer = useRef(null);
    const retryTimer = useRef(null);
    const saveGen = useRef(0);
    const firstRender = useRef(true);
    // Lightweight admin tracking: per-section "visited" and "last updated" stamps,
    // ridden along inside the saved answers under `_sectionMeta` (coarse by design).
    const _m = ans._sectionMeta || {};
    const metaRef = useRef({ visits: _m.visits || {}, updated: _m.updated || {} });
    const lastContentRef = useRef(null);
    const contentOf = (snap) => { const { active: _a, briefSeen: _b, ...rest } = snap; return JSON.stringify(rest); };
    // record the section the client lands on
    useEffect(() => { metaRef.current.visits[active] = new Date().toISOString(); }, []);

    // Persist one snapshot. On failure we keep retrying (the spinner flips to an
    // explicit "couldn't save" state) so a transient blip — server restart, network
    // drop, expired session refresh — never silently loses the client's edits. The
    // `gen` guard makes newer content win: once a fresh save starts, any older save
    // or pending retry abandons itself instead of clobbering newer answers.
    const performSave = useCallback((snapshot, gen) => {
      const content = contentOf(snapshot);
      if (lastContentRef.current !== null && content !== lastContentRef.current) metaRef.current.updated[snapshot.active] = new Date().toISOString();
      setSaving(true);
      window.API.intake.save(Object.assign({}, snapshot, { _sectionMeta: metaRef.current }), snapshot.active)
        .then(() => {
          if (gen !== saveGen.current) return;
          lastContentRef.current = content;
          setSavedAt(Date.now()); setSaving(false); setSaveError(false);
        })
        .catch(() => {
          if (gen !== saveGen.current) return;
          setSaving(false); setSaveError(true);
          clearTimeout(retryTimer.current);
          retryTimer.current = setTimeout(() => performSave(snapshot, gen), 4000);
        });
    }, []);

    useEffect(() => {
      if (firstRender.current) { firstRender.current = false; lastContentRef.current = contentOf(serialize()); return; }
      clearTimeout(saveTimer.current);
      setSaving(true);
      const snapshot = serialize();
      saveTimer.current = setTimeout(() => {
        clearTimeout(retryTimer.current); // supersede any pending retry of older content
        performSave(snapshot, ++saveGen.current);
      }, 600);
      return () => clearTimeout(saveTimer.current);
    }, [serialize, performSave]);

    // Flush the latest answers when the tab is hidden or closed, via a keepalive
    // request that outlives the page — this catches edits still inside the 600ms
    // debounce (or a save that was mid-retry) that would otherwise never reach the DB.
    const serializeRef = useRef(serialize);
    serializeRef.current = serialize;
    useEffect(() => {
      const flush = () => {
        if (!window.API.intake.saveBeacon) return;
        const snap = serializeRef.current();
        window.API.intake.saveBeacon(Object.assign({}, snap, { _sectionMeta: metaRef.current }), snap.active);
      };
      const onVis = () => { if (document.visibilityState === 'hidden') flush(); };
      window.addEventListener('pagehide', flush);
      document.addEventListener('visibilitychange', onVis);
      return () => { window.removeEventListener('pagehide', flush); document.removeEventListener('visibilitychange', onVis); };
    }, []);

    const savedLabel = useMemo(() => {
      if (saveError) return 'Couldn’t save — retrying…';
      if (saving) return 'Saving…';
      if (!savedAt) return 'Saves automatically as you type';
      const mins = Math.floor((Date.now() - savedAt) / 60000);
      if (mins < 1) return 'Saved just now';
      return 'Saved ' + mins + ' min ago';
    }, [saveError, saving, savedAt, tick]);

    // ── navigation ──────────────────────────────────────────────────────────
    const navSeq = ['A', 'B', 'C', 'review']
      .concat(stage2Unlocked ? ['E', 'F'] : [])
      .concat(reportDelivered ? ['R'] : []);
    const activeStage = (active === 'E' || active === 'F') ? 'Stage 2' : (active === 'R' ? 'Stage 3' : 'Stage 1');
    const go = useCallback((id) => {
      const main = document.querySelector('.intk-main');
      if (main) main.scrollTo({ top: 0, behavior: 'instant' });
      metaRef.current.visits[id] = new Date().toISOString();
      setActive(id);
    }, []);
    const idx = navSeq.indexOf(active);
    const prevId = idx > 0 ? navSeq[idx - 1] : (active === 'done' ? 'review' : null);
    const nextId = idx >= 0 && idx < navSeq.length - 1 ? navSeq[idx + 1] : null;

    const sectionLabel = (id) => {
      const m = { review: 'Review & Submit', done: 'Submitted', R: 'Readiness Report' };
      if (m[id]) return m[id];
      const sec = D.SECTIONS.find(s => s.id === id);
      return sec ? sec.label : id;
    };

    // ── questions ──────────────────────────────────────────────────────────────
    // Each question is sent to Linea the moment it's submitted — no draft list.
    const sendQuestion = () => {
      const text = qDraft.trim();
      if (!text) return;
      setQDraft('');
      window.API.questions.add(text, sectionLabel(active))
        .then(() => window.API.questions.send())
        .then(res => setQuestions(res.questions || []))
        .catch(() => {});
    };

    // ── undo toast ──────────────────────────────────────────────────────────
    const pushUndo = (label, restore) => {
      setUndo({ label, restore });
      setTimeout(() => setUndo(u => (u && u.restore === restore ? null : u)), 6000);
    };

    // ── stage submit ──────────────────────────────────────────────────────────
    const withMeta = () => Object.assign({}, serialize(), { _sectionMeta: metaRef.current });
    const submitStage1 = () => {
      window.API.intake.submitStage1(withMeta(), 'done').then(() => { setStatus('stage1_submitted'); go('done'); });
    };
    const finishStage2 = () => {
      window.API.intake.submitStage2(withMeta(), active).then(() => setStatus('stage2_submitted'));
    };

    // ════════════════════════ BRIEF ════════════════════════
    if (!briefSeen) {
      return <IntkBrief client={client} onBegin={() => { setBriefSeen(true); go('A'); }} onSignOut={onSignOut} />;
    }

    // ════════════════════════ WORKSPACE ════════════════════════
    return (
      <div className="intk-root" style={{ fontFamily: "'Outfit',sans-serif", color: C.ink1, background: C.paper, minHeight: '100vh', display: 'flex' }}>
        <datalist id="dl-units">{D.UNIT_SUGGESTIONS.map(o => <option key={o} value={o} />)}</datalist>
        <datalist id="dl-roles">{D.ROLE_SUGGESTIONS.map(o => <option key={o} value={o} />)}</datalist>
        <datalist id="dl-systems">{D.SYSTEM_SUGGESTIONS.map(o => <option key={o} value={o} />)}</datalist>

        <IntkSpine
          client={client} active={active} go={go} state={serialize()} status={status}
          stage2Unlocked={stage2Unlocked} reportDelivered={reportDelivered}
          sectionCount={(id) => sectionCount(serialize(), id)}
          onOpenReport={onOpenReport} onSignOut={onSignOut} onChangePassword={onChangePassword} onHome={() => setBriefSeen(false)}
          questionCount={questions.length} onQuestions={() => setQOpen(true)} />

        <main className="intk-main" style={{ flex: 1, minWidth: 0, overflow: 'auto', height: '100vh' }}>
          {/* top bar */}
          <div className="intk-topbar" style={{ position: 'sticky', top: 0, zIndex: 30, background: 'rgba(250,250,250,0.96)', backdropFilter: 'blur(8px)', borderBottom: '1px solid ' + C.rule, display: 'flex', alignItems: 'center', gap: 13, height: 56, padding: '0 24px 0 28px', boxSizing: 'border-box' }}>
            <span style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.06em', color: C.meta }}>{activeStage}</span>
            <span style={{ flex: 1 }} />
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7, fontSize: 12, color: saveError ? C.warn : C.meta }}>
              <span style={{ width: 6, height: 6, borderRadius: '50%', background: saveError ? C.warn : (saving ? C.dim : C.good) }} />{savedLabel}
            </span>
            <button className="intk-btn-ghost" onClick={() => setFinishLater(true)} style={{ display: 'inline-flex', alignItems: 'center', gap: 7, background: C.white, border: '1px solid rgba(10,10,10,0.16)', borderRadius: 8, height: 38, padding: '0 14px', fontFamily: "'Outfit',sans-serif", fontSize: 13, fontWeight: 500, color: C.ink1, cursor: 'pointer' }}>Save &amp; finish later</button>
            <span style={{ width: 1, height: 22, background: C.rule }} />
            <NavBtn dir="prev" label="Previous" disabled={!prevId} title={prevId ? 'Previous: ' + sectionLabel(prevId) : 'No previous section'} onClick={() => prevId && go(prevId)} />
            <NavBtn dir="next" label="Next" disabled={!nextId} title={nextId ? 'Next: ' + sectionLabel(nextId) : 'No further section'} onClick={() => nextId && go(nextId)} />
          </div>

          <div style={{ maxWidth: 660, margin: '0 auto', padding: '40px 24px 120px' }}>
            {active === 'A' && <SectionOrg
              {...{ oneliner, setOneliner, headcount, setHeadcount, units, setUnits, systems, setSystems, priorities, setPriorities, oneThing, setOneThing, docs, setDocs, uploads, setUploads, pushUndo, go }}
              onContinue={() => go('B')} />}
            {active === 'B' && <SectionData
              {...{ systems, setSystems, units, setUnits, hideSheets, setHideSheets, hideEmail, setHideEmail, hideHead, setHideHead, docs, setDocs, uploads, setUploads, pushUndo, go }}
              count={sectionCount(serialize(), 'B')} onContinue={() => go('C')} />}
            {active === 'C' && <SectionTime
              {...{ repetitive, setRepetitive, costly, setCostly, handoff, setHandoff, docs, setDocs, uploads, setUploads, pushUndo, go }}
              onContinue={() => go('review')} />}
            {active === 'review' && <SectionReview state={serialize()} sectionCount={(id) => sectionCount(serialize(), id)} go={go} onSubmit={submitStage1} additional={additional} setAdditional={setAdditional} />}
            {active === 'done' && <SectionDone />}
            {active === 'E' && <SectionE wfs={wfs} setWfs={setWfs} onContinue={() => go('F')} />}
            {active === 'F' && <SectionF sysd={sysd} setSysd={setSysd} submitted={status === 'stage2_submitted' || status === 'delivered'} onFinish={finishStage2} />}
            {active === 'R' && <SectionReport onOpenReport={onOpenReport} />}
          </div>
        </main>

        {/* overlays */}
        {undo && (
          <div style={{ position: 'fixed', left: '50%', bottom: 22, transform: 'translateX(-50%)', zIndex: 70, background: C.ink, color: C.white, borderRadius: 999, padding: '10px 16px', display: 'flex', alignItems: 'center', gap: 14, fontSize: 13, boxShadow: '0 8px 30px rgba(0,0,0,0.25)' }}>
            {undo.label}
            <button onClick={() => { undo.restore(); setUndo(null); }} style={{ background: 'none', border: 'none', color: '#9db4ff', fontWeight: 600, cursor: 'pointer', fontFamily: "'Outfit',sans-serif", fontSize: 13 }}>Undo</button>
          </div>
        )}
        {finishLater && (
          <div onClick={() => setFinishLater(false)} style={{ position: 'fixed', inset: 0, background: 'rgba(10,10,10,0.4)', zIndex: 80, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24 }}>
            <div onClick={e => e.stopPropagation()} style={{ background: C.white, borderRadius: 12, padding: '28px 28px 24px', maxWidth: 380, textAlign: 'center' }}>
              <div style={{ fontFamily: "'DM Serif Display',serif", fontSize: 24, color: C.ink, marginBottom: 8 }}>Your progress is saved</div>
              <p style={{ fontSize: 14, color: C.sec, lineHeight: 1.6, margin: '0 0 20px' }}>Everything you've entered is stored securely. You can close this window and pick up exactly where you left off whenever you sign back in.</p>
              <button onClick={() => setFinishLater(false)} style={{ border: 'none', background: C.ink, color: C.white, borderRadius: 8, height: 44, padding: '0 24px', fontFamily: "'Outfit',sans-serif", fontSize: 14, fontWeight: 600, cursor: 'pointer' }}>Continue</button>
            </div>
          </div>
        )}
        {qOpen && <QuestionsPanel
          questions={questions} qDraft={qDraft} setQDraft={setQDraft}
          sectionLabel={sectionLabel(active)} onSend={sendQuestion} onClose={() => setQOpen(false)} />}
      </div>
    );
  }

  // ── nav button ─────────────────────────────────────────────────────────────
  function NavBtn({ dir, label, disabled, title, onClick }) {
    return (
      <button onClick={onClick} disabled={disabled} title={title} aria-label={title}
        className="intk-nav"
        style={{
          display: 'inline-flex', alignItems: 'center', gap: 6, fontFamily: "'Outfit',sans-serif",
          fontSize: 13, fontWeight: 600, height: 38, padding: '0 13px', borderRadius: 8,
          border: '1px solid ' + (disabled ? 'rgba(10,10,10,0.08)' : 'rgba(10,10,10,0.16)'),
          background: C.white, color: disabled ? '#c8cad0' : C.ink1,
          opacity: disabled ? 0.55 : 1, cursor: disabled ? 'default' : 'pointer',
        }}>
        {dir === 'prev' && <span>←</span>}{label}{dir === 'next' && <span>→</span>}
      </button>
    );
  }

  // expose internal pieces defined below via hoisting (function declarations)
  // ── brief / orientation ─────────────────────────────────────────────────────
  function IntkBrief({ client, onBegin, onSignOut }) {
    const Stage = ({ n, on, dim, tag, title, body, chips }) => {
      const [hover, setHover] = useState(false);
      const active = on || (dim && hover);   // a dimmed stage brightens to "enabled" on hover
      const dimmed = dim && !hover;
      const RAIL = 38;
      return (
        <div onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)}
          style={{ paddingBottom: n < 3 ? 36 : 0 }}>
          {/* header row — the number is vertically centred against the eyebrow + title block */}
          <div style={{ display: 'flex', gap: 22, alignItems: 'center' }}>
            <div style={{ width: RAIL, flexShrink: 0, display: 'flex', justifyContent: 'center' }}>
              <div style={{ width: 38, height: 38, borderRadius: '50%', background: active ? C.ink : C.paper2, color: active ? C.white : C.dim, border: active ? 'none' : '1.5px ' + (n === 3 ? 'dashed' : 'solid') + ' rgba(10,10,10,0.16)', fontFamily: "'DM Serif Display',serif", fontSize: 17, display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'background .18s ease, color .18s ease, border-color .18s ease' }}>{n}</div>
            </div>
            <div>
              <div style={{ fontSize: 10.5, letterSpacing: '0.11em', textTransform: 'uppercase', color: dimmed ? C.dim : C.meta, fontWeight: 600, marginBottom: 5, transition: 'color .18s ease' }}>{tag}</div>
              <div style={{ fontSize: 18, fontWeight: 600, color: dimmed ? C.meta : C.ink, transition: 'color .18s ease' }}>{title}</div>
            </div>
          </div>
          {/* body row — connector runs under the number, body text aligns under the header text */}
          <div style={{ display: 'flex', gap: 22 }}>
            <div style={{ width: RAIL, flexShrink: 0, display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
              {n < 3 && <div style={{ width: 1, flex: 1, background: C.rule, minHeight: 52 }} />}
            </div>
            <div style={{ paddingTop: 8 }}>
              <div style={{ fontSize: 14, color: dimmed ? C.dim : C.sec, lineHeight: 1.65, maxWidth: '44ch', marginBottom: chips ? 14 : 0, transition: 'color .18s ease' }}>{body}</div>
              {chips && <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>{chips.map(c => <span key={c} style={{ fontSize: 11.5, background: C.paper2, border: '1px solid ' + C.rule, borderRadius: 4, padding: '4px 10px', color: C.sec }}>{c}</span>)}</div>}
            </div>
          </div>
        </div>
      );
    };
    return (
      <div style={{ fontFamily: "'Outfit',sans-serif", minHeight: '100vh', background: C.paper, display: 'flex', flexDirection: 'column' }}>
        <div style={{ background: C.white, borderBottom: '1px solid ' + C.rule, height: 52, display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '0 28px' }}>
          <span style={{ fontFamily: "'DM Serif Display',serif", fontSize: 16, color: C.ink }}>{client.name}</span>
          <LineaMark />
        </div>
        <div style={{ flex: 1, maxWidth: 640, margin: '0 auto', padding: '52px 24px 80px', width: '100%', boxSizing: 'border-box' }}>
          <span style={{ fontSize: 10.5, letterSpacing: '0.12em', textTransform: 'uppercase', color: C.blue, fontWeight: 600 }}>AI Readiness Program</span>
          <h1 style={{ fontFamily: "'DM Serif Display',serif", fontWeight: 400, fontSize: 36, color: C.ink, letterSpacing: '-0.01em', margin: '10px 0 14px', lineHeight: 1.1 }}>Before you begin</h1>
          <p style={{ fontSize: 15, lineHeight: 1.65, color: C.sec, margin: '0 0 52px', maxWidth: '52ch' }}>This questionnaire helps Linea understand how {client.name} operates: your teams, tools, and where time is spent. Your answers shape the assessment we build for you.</p>
          <Stage n={1} on tag="Stage 1 · Gather" title="Tell us how you work" body="Three short sections covering your teams, systems, and where time goes. Share whatever documents you already have, answer what you can, and flag anything you're unsure about." chips={['A · Your Organization', 'B · Where Your Data Lives', 'C · Where Time Goes']} />
          <Stage n={2} dim tag="Stage 2 · We prepare, you confirm" title="Review what you shared" body="We map out your systems and key processes from your answers. We will reach out with any questions or clarifications. Most of this can also be handled at your kickoff meeting." />
          <Stage n={3} dim tag="Stage 3 · Your assessment" title="Your readiness report" body="A live, personalised assessment: your AI readiness score, prioritised opportunities, and a recommended roadmap." />
          <div style={{ marginTop: 52, paddingTop: 28, borderTop: '1px solid ' + C.rule, display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 16 }}>
            <div>
              <div style={{ fontSize: 14, fontWeight: 500, color: C.ink }}>Start at your convenience</div>
              <div style={{ fontSize: 13, color: C.meta, marginTop: 3 }}>Your progress saves automatically. You can finish later at any time.</div>
            </div>
            <button onClick={onBegin} style={{ border: 'none', background: C.ink, color: C.white, borderRadius: 8, padding: '0 30px', height: 50, fontFamily: "'Outfit',sans-serif", fontSize: 14.5, fontWeight: 600, cursor: 'pointer' }}>Begin Stage 1</button>
          </div>
        </div>
      </div>
    );
  }

  // ── the left ledger spine ─────────────────────────────────────────────────
  function IntkSpine({ client, active, go, state, status, stage2Unlocked, reportDelivered, sectionCount, onOpenReport, onSignOut, onChangePassword, onHome, questionCount, onQuestions }) {
    const stage1 = ['A', 'B', 'C'];
    const s1Done = stage1.filter(id => { const c = sectionCount(id); return c.done >= c.total && c.total > 0; }).length;
    const stage1Submitted = ['stage1_submitted', 'stage2_unlocked', 'stage2_submitted', 'delivered'].indexOf(status) >= 0;

    const Node = ({ id, label, locked, dashed }) => {
      const c = id.length === 1 && 'ABCD'.indexOf(id) >= 0 ? sectionCount(id) : null;
      const isActive = active === id;
      const done = c ? (c.done >= c.total && c.total > 0) : false;
      const part = c ? (c.done > 0 && c.done < c.total) : false;
      // Empty/locked dots are filled with the nav background (not transparent) so
      // the vertical spine line never shows through the centre of a dot.
      const dotBg = locked ? C.paper2 : (done ? C.good : (isActive || part ? C.blue : C.paper2));
      const dotBd = locked ? '1.5px dashed ' + C.dim : (done || isActive || part ? 'none' : '1.5px solid ' + C.dim);
      const meta = locked ? null : (c ? (done ? 'Complete' : (part ? c.done + ' of ' + c.total + ' answered' : 'Not started')) : null);
      return (
        <div onClick={() => !locked && go(id)} style={{ display: 'flex', gap: 13, alignItems: 'flex-start', padding: '5px 0 11px', cursor: locked ? 'default' : 'pointer' }}>
          <span style={{ position: 'relative', zIndex: 1, width: 11, height: 11, borderRadius: '50%', background: dotBg, border: dotBd, boxShadow: isActive ? '0 0 0 3px rgba(46,93,255,0.15)' : 'none', boxSizing: 'border-box', flexShrink: 0, marginTop: 3 }} />
          <span style={{ display: 'flex', flexDirection: 'column', gap: 2, flex: 1, minWidth: 0 }}>
            <span style={{ fontSize: 13, color: locked ? C.dim : (isActive ? C.ink : C.ink1), fontWeight: isActive ? 600 : 400 }}>{label}</span>
            {meta && <span style={{ fontSize: 10.5, color: done ? C.good : C.meta }}>{meta}</span>}
            {c && part && <span style={{ display: 'block', height: 3, background: 'rgba(10,10,10,0.08)', borderRadius: 2, overflow: 'hidden', maxWidth: 140, marginTop: 3 }}><span style={{ display: 'block', height: '100%', width: (c.done / c.total * 100) + '%', background: C.blue }} /></span>}
          </span>
        </div>
      );
    };
    const Lock = () => <svg width="10" height="11" viewBox="0 0 11 12" aria-hidden="true"><rect x="1" y="5.5" width="9" height="6" rx="1.5" fill={C.dim} /><path d="M 3 5.5 V 3.6 a 2.5 2.5 0 0 1 5 0 V 5.5" fill="none" stroke={C.dim} strokeWidth="1.5" /></svg>;

    return (
      <nav className="intk-spine" aria-label="Journey map" style={{ width: 290, flexShrink: 0, position: 'sticky', top: 0, height: '100vh', display: 'flex', flexDirection: 'column', borderRight: '1px solid ' + C.rule, boxSizing: 'border-box', padding: '26px 20px 18px', background: C.paper2 }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 7, marginBottom: 14 }}>
          <span style={{ fontSize: 10.5, letterSpacing: '0.12em', textTransform: 'uppercase', color: C.meta, fontWeight: 500 }}>AI Readiness Program</span>
          <span style={{ fontFamily: "'DM Serif Display',serif", fontSize: 17, color: C.ink, lineHeight: 1.1 }}>{client.name}</span>
        </div>
        {onHome && (
          <button onClick={onHome} title="Back to the overview" className="intk-home-link" style={{ display: 'inline-flex', alignItems: 'center', gap: 7, alignSelf: 'flex-start', background: 'none', border: 'none', padding: '4px 0', marginBottom: 18, fontFamily: "'Outfit',sans-serif", fontSize: 12.5, fontWeight: 500, color: C.meta, cursor: 'pointer' }}>
            <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M4 11l8-7 8 7" /><path d="M6 10v9h12v-9" /></svg>
            Overview
          </button>
        )}

        <div style={{ flex: 1, overflow: 'auto', minHeight: 0 }}>
          <div style={{ position: 'relative' }}>
            <div style={{ position: 'absolute', left: 5, top: 30, bottom: 14, width: 1, background: 'rgba(10,10,10,0.12)' }} />
            {/* Stage 1 */}
            <div style={{ padding: '0 0 8px 24px', display: 'flex', flexDirection: 'column', gap: 7 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', gap: 8 }}>
                <span style={{ fontSize: 10.5, letterSpacing: '0.12em', textTransform: 'uppercase', color: C.meta, fontWeight: 500 }}>Stage 1 · Gather</span>
                <span style={{ fontSize: 10.5, color: C.meta, fontFamily: "'DM Serif Display',serif" }}>{s1Done}/{stage1.length}</span>
              </div>
              <span style={{ display: 'block', height: 3, background: 'rgba(10,10,10,0.08)', borderRadius: 2, overflow: 'hidden' }}><span style={{ display: 'block', height: '100%', width: (s1Done / stage1.length * 100) + '%', background: C.blue }} /></span>
            </div>
            <div style={{ paddingLeft: 0 }}>
              {D.SECTIONS.filter(s => s.stage === 1).map(s => <Node key={s.id} id={s.id} label={s.id + ' · ' + s.label} />)}
              <Node id="review" label="Review & Submit" />
            </div>

            {/* Stage 2 */}
            <div style={{ padding: '10px 0 12px 24px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 8 }}>
              <span style={{ fontSize: 10.5, letterSpacing: '0.12em', textTransform: 'uppercase', color: C.dim, fontWeight: 500 }}>Stage 2 · We prepare, you confirm</span>
              {!stage2Unlocked ? <Lock /> : (stage1Submitted && <span style={{ fontSize: 11, color: C.good }}>✓</span>)}
            </div>
            {stage2Unlocked
              ? <div>{D.SECTIONS.filter(s => s.stage === 2).map(s => <Node key={s.id} id={s.id} label={s.id + ' · ' + s.label} />)}</div>
              : <div style={{ paddingLeft: 24, fontSize: 11.5, color: C.meta, lineHeight: 1.5, paddingBottom: 8 }}>{D.LOCK_COPY}</div>}

            {/* Stage 3 */}
            <div style={{ padding: '10px 0 12px 24px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', gap: 8 }}>
              <span style={{ fontSize: 10.5, letterSpacing: '0.12em', textTransform: 'uppercase', color: C.dim, fontWeight: 500 }}>Stage 3 · Your assessment</span>
              {!reportDelivered && <span style={{ width: 9, height: 9, borderRadius: '50%', border: '1.5px dashed ' + C.dim, boxSizing: 'border-box' }} />}
            </div>
            <Node id="R" label="Readiness Report" locked={!reportDelivered} />
          </div>
        </div>

        <div style={{ paddingTop: 14, borderTop: '1px solid ' + C.rule, marginTop: 12, display: 'flex', flexDirection: 'column', gap: 12 }}>
          <button onClick={onQuestions} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8, width: '100%', boxSizing: 'border-box', border: '1px solid ' + C.rule2, background: C.white, color: C.ink1, borderRadius: 8, padding: '0 13px', height: 42, fontFamily: "'Outfit',sans-serif", fontSize: 13, fontWeight: 600, cursor: 'pointer' }}>
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 9 }}><span style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 17, height: 17, border: '1.5px solid currentColor', borderRadius: '50%', fontSize: 10.5, opacity: 0.8 }}>?</span>Questions for Linea</span>
            {questionCount > 0 && <span style={{ background: C.blue, color: C.white, borderRadius: 999, minWidth: 18, height: 18, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', fontSize: 11, fontWeight: 700, padding: '0 5px' }}>{questionCount}</span>}
          </button>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 8 }}>
            <div style={{ display: 'inline-flex', alignItems: 'center', gap: 16 }}>
              <button onClick={onSignOut} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, background: 'none', border: 'none', padding: '4px 0', fontFamily: "'Outfit',sans-serif", fontSize: 12, fontWeight: 500, color: C.meta, cursor: 'pointer' }}><SignOutIcon />Sign out</button>
              {onChangePassword && <button onClick={onChangePassword} style={{ background: 'none', border: 'none', padding: '4px 0', fontFamily: "'Outfit',sans-serif", fontSize: 12, fontWeight: 500, color: C.meta, cursor: 'pointer' }}>Change password</button>}
            </div>
            <LineaMark />
          </div>
        </div>
      </nav>
    );
  }

  // ─────────────────────────── SECTION HEADER ────────────────────────────────
  function SecHead({ eyebrow, title, intro, right }) {
    return (
      <div style={{ marginBottom: 28 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 16 }}>
          <span style={{ fontSize: 10.5, letterSpacing: '0.12em', textTransform: 'uppercase', color: C.blue, fontWeight: 600 }}>{eyebrow}</span>
          {right}
        </div>
        <h1 style={{ fontFamily: "'DM Serif Display',serif", fontWeight: 400, fontSize: 32, color: C.ink, letterSpacing: '-0.01em', margin: '8px 0 12px', lineHeight: 1.12 }}>{title}</h1>
        {intro && <p style={{ fontSize: 14.5, lineHeight: 1.6, color: C.sec, margin: 0, maxWidth: '56ch' }}>{intro}</p>}
      </div>
    );
  }
  const Label = ({ children }) => <label style={{ fontSize: 11, fontWeight: 600, color: C.meta, letterSpacing: '0.06em', textTransform: 'uppercase', display: 'block', marginBottom: 7 }}>{children}</label>;
  const ContinueBtn = ({ label, onClick }) => (
    <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 32 }}>
      <button onClick={onClick} style={{ border: 'none', background: C.ink, color: C.white, borderRadius: 8, padding: '0 22px', minHeight: 44, fontFamily: "'Outfit',sans-serif", fontSize: 14, fontWeight: 600, cursor: 'pointer' }}>{label}</button>
    </div>
  );
  const IconFileSm = () => sv(<><path d="M6 2.5h8l4 4V21.5H6z" /><path d="M14 2.5v4h4" /></>, 15);
  const Chevron = ({ size = 16, open }) => <span style={{ display: 'inline-flex', transition: 'transform .18s ease', transform: open ? 'rotate(180deg)' : 'none' }}>{sv(<><path d="M6 9l6 6 6-6" /></>, size)}</span>;
  // Click-to-open info popover — used to tuck the "shared list" explainer behind
  // a small (i) instead of an always-on callout.
  function InfoTip({ children }) {
    const [open, setOpen] = useState(false);
    return (
      <span style={{ position: 'relative', display: 'inline-flex' }}>
        <button onClick={(e) => { e.stopPropagation(); setOpen(o => !o); }} aria-label="More info"
          style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: 16, height: 16, borderRadius: '50%', border: '1.5px solid ' + (open ? C.blue : C.rule2), background: open ? C.blueTint : 'transparent', color: open ? C.blueDk : C.meta, fontSize: 10.5, fontWeight: 700, fontFamily: 'Georgia, serif', fontStyle: 'italic', cursor: 'pointer', lineHeight: 1 }}>i</button>
        {open && (
          <React.Fragment>
            <span onClick={(e) => { e.stopPropagation(); setOpen(false); }} style={{ position: 'fixed', inset: 0, zIndex: 40 }} />
            <span style={{ position: 'absolute', zIndex: 41, top: '150%', left: 0, width: 270, background: C.white, border: '1px solid ' + C.rule2, borderRadius: 8, boxShadow: '0 10px 30px rgba(0,0,0,0.14)', padding: '11px 13px', fontSize: 12, color: C.sec, lineHeight: 1.55, fontWeight: 400 }}>{children}</span>
          </React.Fragment>
        )}
      </span>
    );
  }

  // Reusable collapsible document card — the shared chrome behind the rows in
  // Your Documents and the Org Chart / Systems cards in Sections B and C, so
  // they all look and behave identically (header, status, file toggle, body).
  function CollapsibleDoc({ docIcon, title, hint, info, status, files, open, onToggle, filesOpen, onToggleFiles, onRemoveFile, fileFooter, onDropFiles, children }) {
    const dot = (c) => <span style={{ width: 6, height: 6, borderRadius: '50%', background: c, flexShrink: 0 }} />;
    return (
      <div
        onDragOver={onDropFiles ? (e) => e.preventDefault() : undefined}
        onDrop={onDropFiles ? (e) => { e.preventDefault(); onDropFiles(e.dataTransfer.files); } : undefined}
        style={{ background: C.white, border: '1px solid ' + C.rule, borderRadius: 6, padding: '14px 18px' }}>
        {/* header — click anywhere to expand/collapse */}
        <div onClick={onToggle} style={{ display: 'flex', justifyContent: 'space-between', gap: 12, alignItems: 'flex-start', cursor: 'pointer' }}>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 11 }}>
              <span style={{ color: C.sec, flexShrink: 0, display: 'inline-flex' }}>{docIcon}</span>
              <div style={{ fontSize: 14.5, fontWeight: 500, color: C.ink }}>{title}</div>
              {info}
            </div>
            <div style={{ paddingLeft: 28 }}>
              {hint && <div style={{ fontSize: 12.5, color: C.meta, marginTop: 2 }}>{hint}</div>}
              {status.length > 0 && (
                <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: '4px 12px', marginTop: 8 }}>
                  {status.map((s, si) => s.k === 'upload' ? (
                    <button key={si} onClick={(e) => { e.stopPropagation(); onToggleFiles(); }}
                      style={{ display: 'inline-flex', alignItems: 'center', gap: 6, background: 'none', border: 'none', padding: 0, fontFamily: "'Outfit',sans-serif", fontSize: 12, fontWeight: 600, color: s.fg, cursor: 'pointer' }}>
                      {dot(s.fg)}{s.l}{files.length > 0 && <Chevron size={13} open={filesOpen} />}
                    </button>
                  ) : (
                    <span key={si} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 12, fontWeight: 600, color: s.fg }}>{dot(s.fg)}{s.l}</span>
                  ))}
                </div>
              )}
            </div>
          </div>
          <span style={{ color: C.meta, marginTop: 1, flexShrink: 0 }}><Chevron open={open} /></span>
        </div>

        {/* uploaded files — toggled by the "N files uploaded" status (height-animated) */}
        <div style={{ display: 'grid', gridTemplateRows: (filesOpen && files.length > 0) ? '1fr' : '0fr', transition: 'grid-template-rows .24s ease' }}>
          <div style={{ overflow: 'hidden' }}>
            <div style={{ paddingLeft: 28, marginTop: 10, display: 'flex', flexDirection: 'column', gap: 7 }}>
              {files.map(f => (
                <div key={f.id} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, color: C.meta }}>
                  <span style={{ color: C.dim, flexShrink: 0, display: 'inline-flex' }}><IconFileSm /></span>
                  <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', flex: 1, minWidth: 0 }}>{f.name}</span>
                  {onRemoveFile && <button onClick={(e) => { e.stopPropagation(); onRemoveFile(f.id); }} title="Remove" style={{ background: 'none', border: 'none', color: C.meta, cursor: 'pointer', fontSize: 15, lineHeight: 1, flexShrink: 0 }}>×</button>}
                </div>
              ))}
              {fileFooter}
            </div>
          </div>
        </div>

        {/* body — height-animated on expand/collapse */}
        <div style={{ display: 'grid', gridTemplateRows: open ? '1fr' : '0fr', transition: 'grid-template-rows .28s ease' }}>
          <div style={{ overflow: 'hidden' }}>
            <div style={{ paddingLeft: 28, marginTop: 14 }}>{children}</div>
          </div>
        </div>
      </div>
    );
  }

  // ─────────────────────────── DOCUMENT CARD ─────────────────────────────────
  // A single collapsible document card with its hybrid inputs: upload, describe,
  // mark N/A, and — for the org chart / systems list — an "Add manually" builder.
  // Extracted so each Stage-1 section can drop in just the cards it owns. Reads
  // and writes the shared `docs` map; manages its own open / files-open state.
  function DocBlock({ doc, docs, setDocs, uploads, setUploads, units, setUnits, systems, setSystems, pushUndo, go }) {
    const BUILDER = { org: 'units', systems: 'systems' };
    const baseAlts = [{ k: 'describe', l: 'Describe it', Icon: IconDescribe }, { k: 'none', l: 'N/A', Icon: IconNA }];
    const [open, setOpen] = useState(false);
    const [filesOpen, setFilesOpen] = useState(false);
    const r = docs[doc.id] || { modes: [], files: [], desc: '' };
    // `patch` may be an object or a fn of the current row — always computed from
    // the freshest state so rapid toggles don't clobber each other.
    const setDoc = (patch) => setDocs(d => {
      const cur = d[doc.id] || { modes: [], files: [], desc: '' };
      const p = typeof patch === 'function' ? patch(cur) : patch;
      return Object.assign({}, d, { [doc.id]: Object.assign({}, cur, p) });
    });
    // Toggle a mode on/off — inputs are hybrid, so several can be active at once.
    // Selecting N/A is exclusive (it means "nothing here").
    const pick = (k) => setDoc((cur) => {
      const m = docModes(cur);
      const has = m.indexOf(k) >= 0;
      let next = has ? m.filter(x => x !== k) : m.concat([k]);
      if (!has && k === 'none') next = ['none'];
      else if (!has && k !== 'none') next = next.filter(x => x !== 'none');
      return { modes: next, choice: undefined };
    });
    const onFiles = (fileList) => {
      if (!fileList || !fileList.length) return;
      window.API.uploads.upload(fileList, doc.id).then(res => {
        const added = (res.uploads || []).map(u => ({ id: u.id, name: u.original_name }));
        setUploads(prev => prev.concat(res.uploads || []));
        // Uploading clears a prior "N/A"; it can coexist with describe / add manually.
        setDoc((cur) => ({ files: docFiles(cur).concat(added), modes: docModes(cur).filter(m => m !== 'none'), choice: undefined }));
        setOpen(true); setFilesOpen(true);
      });
    };
    const removeFile = (fileId) => {
      window.API.uploads.remove(fileId).then(() => {
        setUploads(prev => prev.filter(u => u.id !== fileId));
        setDoc((cur) => ({ files: docFiles(cur).filter(f => f.id !== fileId), choice: undefined }));
      });
    };
    const builder = BUILDER[doc.id];
    const alts = builder ? [{ k: 'select', l: 'Add manually', Icon: IconAddManual }].concat(baseAlts) : baseAlts;
    const status = docStatusParts(doc.id, r, units, systems);
    const modes = docModes(r);
    const files = docFiles(r);
    // Show the builder when "Add manually" is on OR entries already exist.
    const hasEntries = builder === 'units' ? (units || []).some(u => (u.name || '').trim()) : builder === 'systems' ? (systems || []).some(s => (s.name || '').trim()) : false;
    const showBuilder = !!builder && (modes.indexOf('select') >= 0 || hasEntries);
    const jobsUploaded = docHasUpload(docs.jobs);
    const unitNames = (units || []).map(u => (u.name || '').trim()).filter(Boolean);
    return (
      <CollapsibleDoc
        docIcon={(DOC_ICON[doc.id] || (() => null))()}
        title={doc.title} hint={doc.hint}
        status={status} files={files}
        open={open} onToggle={() => setOpen(o => !o)}
        filesOpen={filesOpen} onToggleFiles={() => setFilesOpen(o => !o)}
        onRemoveFile={removeFile}
        onDropFiles={onFiles}>
        <div style={{ display: 'flex', gap: 7, flexWrap: 'wrap', alignItems: 'center' }}>
          <label style={{ position: 'relative', display: 'inline-flex', alignItems: 'center', gap: 6, background: C.ink, color: C.white, borderRadius: 6, minHeight: 38, padding: '0 13px', fontSize: 13, fontWeight: 500, cursor: 'pointer' }}>
            <IconUpload />Upload
            <input type="file" multiple onChange={e => onFiles(e.target.files)} style={{ position: 'absolute', inset: 0, opacity: 0, cursor: 'pointer' }} />
          </label>
          {alts.map(a => { const on = a.k === 'select' ? showBuilder : modes.indexOf(a.k) >= 0; return (
            <button key={a.k} onClick={() => pick(a.k)} aria-pressed={on}
              style={{ display: 'inline-flex', alignItems: 'center', gap: 6, borderRadius: 6, minHeight: 38, padding: '0 12px', fontFamily: "'Outfit',sans-serif", fontSize: 13, cursor: 'pointer',
                border: '1px solid ' + (on ? 'rgba(46,93,255,0.4)' : C.rule2),
                background: on ? C.blueTint : C.white, color: on ? C.blueDk : C.sec }}><a.Icon />{a.l}</button>
          ); })}
        </div>
        {modes.indexOf('describe') >= 0 && (
          <textarea value={r.desc || ''} onChange={e => setDoc({ desc: e.target.value })} rows={2}
            placeholder={doc.describeEg || ('Briefly describe your ' + doc.title.toLowerCase() + '…')}
            style={Object.assign({}, TEXTAREA, { marginTop: 12 })} />
        )}
        {builder === 'units' && showBuilder && (
          <div style={{ marginTop: 16 }}>
            <div style={{ marginBottom: 10, fontSize: 11, fontWeight: 600, color: C.meta, letterSpacing: '0.06em', textTransform: 'uppercase' }}>Business units</div>
            <UnitsBuilder units={units} setUnits={setUnits} jobsUploaded={jobsUploaded} pushUndo={pushUndo} />
          </div>
        )}
        {builder === 'systems' && showBuilder && (
          <div style={{ marginTop: 16 }}>
            <div style={{ marginBottom: 10, fontSize: 11, fontWeight: 600, color: C.meta, letterSpacing: '0.06em', textTransform: 'uppercase' }}>Systems</div>
            <SystemsBuilder systems={systems} setSystems={setSystems} unitNames={unitNames} pushUndo={pushUndo} goB={() => go && go('A')} />
          </div>
        )}
      </CollapsibleDoc>
    );
  }

  // ─────────────────────────── SECTION A · YOUR ORGANIZATION ──────────────────
  // Org structure + the org-chart and job-description document cards.
  function SectionOrg({ oneliner, setOneliner, headcount, setHeadcount, units, setUnits, systems, setSystems, priorities, setPriorities, oneThing, setOneThing, docs, setDocs, uploads, setUploads, pushUndo, go, onContinue }) {
    const docProps = { docs, setDocs, uploads, setUploads, units, setUnits, systems, setSystems, pushUndo, go };
    return (
      <div>
        <SecHead eyebrow="Section A" title="Your Organization" intro="This is the backbone of our analysis. We use your structure to map where work and time actually go. Share whatever documents you already have — rough or outdated is fine." />

        <div style={{ marginBottom: 24 }}>
          <Label>What does your company do, in a sentence or two?</Label>
          <textarea value={oneliner} onChange={e => setOneliner(e.target.value)} rows={2} placeholder="e.g. We provide outsourced finance and bookkeeping services to growing businesses." style={TEXTAREA} />
        </div>
        <div style={{ marginBottom: 24 }}>
          <Label>Approximately how many employees in total?</Label>
          <ChipRow options={D.HEADCOUNT} value={headcount} onPick={setHeadcount} />
        </div>

        <div style={{ marginBottom: 8, fontSize: 11, fontWeight: 600, color: C.meta, letterSpacing: '0.06em', textTransform: 'uppercase' }}>Your organization</div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <DocBlock doc={DOC.org} {...docProps} />
          <DocBlock doc={DOC.jobs} {...docProps} />
        </div>

        <div style={{ marginTop: 28, marginBottom: 22 }}>
          <Label>What are your top 2–3 business priorities or pressures this year?</Label>
          <textarea value={priorities} onChange={e => setPriorities(e.target.value)} rows={2} placeholder="e.g. your quarterly or annual goals, rocks — grow revenue, improve cash flow, hire and onboard faster." style={TEXTAREA} />
        </div>
        <div>
          <Label>If this program does one thing for you, what should it be?</Label>
          <input value={oneThing} onChange={e => setOneThing(e.target.value)} placeholder="e.g. Cut the time we spend chasing invoices in half." style={INPUT} />
        </div>
        <ContinueBtn label="Continue: Where Your Data Lives" onClick={onContinue} />
      </div>
    );
  }

  // Shared business-units builder — used both in Your Documents (Add manually)
  // and in Your Organization. Operates on the same `units` state.
  function UnitsBuilder({ units, setUnits, jobsUploaded, pushUndo }) {
    const openOnly = (i) => setUnits(list => list.map((u, j) => Object.assign({}, u, { open: j === i ? !u.open : false })));
    const patch = (i, p) => setUnits(list => list.map((u, j) => j === i ? Object.assign({}, u, p) : u));
    const addUnit = () => setUnits(list => list.map(u => Object.assign({}, u, { open: false })).concat([blankUnit()]));
    const addNamed = (name) => setUnits(list => list.map(u => Object.assign({}, u, { open: false })).concat([Object.assign(blankUnit(), { name, open: false })]));
    const removeUnit = (i) => { const removed = units[i]; setUnits(list => list.filter((_, j) => j !== i)); pushUndo && pushUndo('Removed “' + (removed.name || 'unit') + '”', () => setUnits(list => { const c = list.slice(); c.splice(i, 0, removed); return c; })); };
    const usedNames = units.map(u => (u.name || '').trim().toLowerCase());
    const presets = D.UNIT_SUGGESTIONS.filter(p => usedNames.indexOf(p.toLowerCase()) < 0);
    return (
      <div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {units.map((u, i) => (
            <UnitCard key={i} u={u} num={i + 1} jobsUploaded={jobsUploaded}
              onToggle={() => openOnly(i)} onPatch={(p) => patch(i, p)} onRemove={() => removeUnit(i)} />
          ))}
        </div>
        {presets.length > 0 && (
          <div style={{ background: C.paper2, borderRadius: 8, padding: '12px 14px', marginTop: 10, display: 'flex', flexWrap: 'wrap', gap: 7, alignItems: 'center' }}>
            <span style={{ fontSize: 12, color: C.meta, fontWeight: 500 }}>Quick-add:</span>
            {presets.map(p => <button key={p} onClick={() => addNamed(p)} style={{ border: '1px solid ' + C.rule2, background: C.white, borderRadius: 999, padding: '5px 11px', fontSize: 12.5, color: C.ink1, cursor: 'pointer', fontFamily: "'Outfit',sans-serif" }}>+ {p}</button>)}
          </div>
        )}
        <button onClick={addUnit} style={{ width: '100%', marginTop: 10, border: '1.5px dashed ' + C.rule2, background: 'transparent', borderRadius: 8, height: 46, fontFamily: "'Outfit',sans-serif", fontSize: 13.5, fontWeight: 500, color: C.sec, cursor: 'pointer' }}>+ Add custom unit</button>
      </div>
    );
  }

  function UnitCard({ u, num, jobsUploaded, onToggle, onPatch, onRemove }) {
    const summary = [(u.head ? u.head + ' people' : 'headcount ?'), ((u.roles || []).filter(r => (r.title || '').trim()).length || 'no') + ' roles'].join(' · ');
    const setRole = (i, p) => onPatch({ roles: u.roles.map((r, j) => j === i ? Object.assign({}, r, p) : r) });
    const addRole = () => onPatch({ roles: (u.roles || []).concat([{ title: '', count: '' }]) });
    const removeRole = (i) => onPatch({ roles: u.roles.filter((_, j) => j !== i) });
    if (!u.open) {
      return (
        <button onClick={onToggle} style={{ width: '100%', textAlign: 'left', background: C.white, border: '1px solid ' + C.rule, borderRadius: 8, minHeight: 50, padding: '10px 14px', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 12 }}>
          <span style={{ width: 22, height: 22, borderRadius: '50%', background: C.paper3, color: C.sec, fontSize: 12, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>{num}</span>
          <span style={{ flex: 1, minWidth: 0 }}>
            <span style={{ display: 'block', fontSize: 14, fontWeight: 500, color: C.ink }}>{u.name || 'New unit'}</span>
            <span style={{ display: 'block', fontSize: 12, color: C.meta, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{summary}</span>
          </span>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: 12, color: C.blue }}><Pencil />Edit</span>
        </button>
      );
    }
    return (
      <div style={{ border: '1.5px solid ' + C.blue, borderRadius: 8, boxShadow: '0 0 0 3px rgba(46,93,255,0.08)', overflow: 'hidden', animation: 'intkExpand .26s ease both' }}>
        <div style={{ background: C.blueTint, padding: '10px 16px', display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{ width: 22, height: 22, borderRadius: '50%', background: C.blue, color: C.white, fontSize: 12, display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }}>{num}</span>
          <span style={{ fontSize: 11.5, textTransform: 'uppercase', letterSpacing: '0.06em', color: C.blueDk, fontWeight: 600 }}>{u.name ? 'Editing: ' + u.name : 'New unit: name it below'}</span>
        </div>
        <div style={{ padding: '16px 18px 18px', background: C.white }}>
          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', marginBottom: 14 }}>
            <div style={{ flex: 2, minWidth: 160 }}><Label>Unit name</Label><input value={u.name} onChange={e => onPatch({ name: e.target.value })} list="dl-units" placeholder="e.g. Finance" style={INPUT} /></div>
            <div style={{ width: 110 }}><Label>Headcount</Label><input value={u.head} onChange={e => onPatch({ head: e.target.value })} inputMode="numeric" placeholder="e.g. 6" style={INPUT} /></div>
          </div>
          <div style={{ background: C.paper2, borderRadius: 6, padding: '13px 15px', marginBottom: 14 }}>
            <Label>Roles in this unit (optional)</Label>
            {jobsUploaded && <div style={{ fontSize: 12, color: C.blueDk, marginBottom: 8 }}>Covered by your uploaded job descriptions. Add anything missing.</div>}
            <div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>
              {(u.roles || []).map((r, i) => (
                <div key={i} style={{ display: 'flex', gap: 7, animation: 'intkRowIn .24s ease both' }}>
                  <input value={r.title} onChange={e => setRole(i, { title: e.target.value })} list="dl-roles" placeholder="Role title, e.g. Account Manager" style={Object.assign({}, INPUT, { flex: 1 })} />
                  <input value={r.count} onChange={e => setRole(i, { count: e.target.value })} inputMode="numeric" placeholder="#" style={Object.assign({}, INPUT, { width: 54, textAlign: 'center', padding: 0 })} />
                  <button onClick={() => removeRole(i)} className="intk-trash" style={{ width: 38, flexShrink: 0, border: '1px solid ' + C.rule2, background: C.white, borderRadius: 6, color: C.meta, cursor: 'pointer', display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }}><Trash /></button>
                </div>
              ))}
            </div>
            <button onClick={addRole} style={{ marginTop: 9, background: 'none', border: 'none', color: C.blue, fontSize: 13, fontWeight: 500, cursor: 'pointer', fontFamily: "'Outfit',sans-serif", padding: 0 }}>+ Add role</button>
          </div>
          <div style={{ marginBottom: 16 }}>
            <Label>In one line, what does this unit produce or deliver? (optional)</Label>
            <input value={u.delivers} onChange={e => onPatch({ delivers: e.target.value })} placeholder="e.g. Gets new customers fully onboarded within their first week" style={INPUT} />
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between' }}>
            <button onClick={onRemove} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, border: '1px solid rgba(192,61,46,0.3)', background: C.white, color: '#c03d2e', borderRadius: 8, height: 40, padding: '0 14px', fontFamily: "'Outfit',sans-serif", fontSize: 13, cursor: 'pointer' }}><Trash />Remove unit</button>
            <button onClick={onToggle} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, border: 'none', background: C.blue, color: C.white, borderRadius: 8, height: 40, padding: '0 18px', fontFamily: "'Outfit',sans-serif", fontSize: 13, fontWeight: 600, cursor: 'pointer' }}><Check />Done</button>
          </div>
        </div>
      </div>
    );
  }

  // ─────────────────────────── SECTION B · WHERE YOUR DATA LIVES ──────────────
  // Systems + KPIs document cards, then the broader "where does info hide" map.
  function SectionData({ systems, setSystems, units, setUnits, hideSheets, setHideSheets, hideEmail, setHideEmail, hideHead, setHideHead, docs, setDocs, uploads, setUploads, pushUndo, go, count, onContinue }) {
    const docProps = { docs, setDocs, uploads, setUploads, units, setUnits, systems, setSystems, pushUndo, go };
    return (
      <div>
        <SecHead eyebrow="Section B" title="Where Your Data Lives"
          intro="A map of where information sits in your company: systems, spreadsheets, inboxes, and heads. Names and rough purpose are all we need right now."
          right={<div style={{ textAlign: 'right' }}>
            <div style={{ fontSize: 11, color: C.meta }}>{count.done} of {count.total} answered</div>
            <div style={{ width: 120, height: 4, background: 'rgba(10,10,10,0.08)', borderRadius: 2, marginTop: 5, overflow: 'hidden' }}><div style={{ height: '100%', width: (count.done / count.total * 100) + '%', background: C.blue }} /></div>
          </div>} />

        <div style={{ marginBottom: 8, fontSize: 11, fontWeight: 600, color: C.meta, letterSpacing: '0.06em', textTransform: 'uppercase' }}>Your systems</div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <DocBlock doc={DOC.systems} {...docProps} />
          <DocBlock doc={DOC.report} {...docProps} />
        </div>

        <h2 style={{ fontFamily: "'DM Serif Display',serif", fontWeight: 400, fontSize: 20, color: C.ink, margin: '32px 0 16px' }}>The broader picture</h2>
        <div style={{ marginBottom: 18 }}><Label>What important information lives in spreadsheets rather than a system?</Label><textarea value={hideSheets} onChange={e => setHideSheets(e.target.value)} rows={2} placeholder="e.g. our pricing model, the cash-flow forecast" style={TEXTAREA} /></div>
        <div style={{ marginBottom: 18 }}><Label>What lives mainly in email or chat threads?</Label><textarea value={hideEmail} onChange={e => setHideEmail(e.target.value)} rows={2} placeholder="e.g. vendor confirmations, customer approvals" style={TEXTAREA} /></div>
        <div><Label>What lives only in someone's head?</Label><textarea value={hideHead} onChange={e => setHideHead(e.target.value)} rows={2} placeholder="e.g. one person knows all the client account history" style={TEXTAREA} /></div>
        <ContinueBtn label="Continue: Where Time Goes" onClick={onContinue} />
      </div>
    );
  }

  // Shared systems builder — used both in Your Documents (Add manually) and in
  // Where Your Data Lives. Operates on the same `systems` state.
  function SystemsBuilder({ systems, setSystems, unitNames, pushUndo, goB }) {
    const openOnly = (i) => setSystems(list => list.map((u, j) => Object.assign({}, u, { open: j === i ? !u.open : false })));
    const patch = (i, p) => setSystems(list => list.map((u, j) => j === i ? Object.assign({}, u, p) : u));
    const addSystem = () => setSystems(list => list.map(u => Object.assign({}, u, { open: false })).concat([blankSystem()]));
    const addNamed = (name) => setSystems(list => list.map(u => Object.assign({}, u, { open: false })).concat([Object.assign(blankSystem(), { name, open: false })]));
    const removeSystem = (i) => { const removed = systems[i]; setSystems(list => list.filter((_, j) => j !== i)); pushUndo && pushUndo('Removed “' + (removed.name || 'system') + '”', () => setSystems(list => { const c = list.slice(); c.splice(i, 0, removed); return c; })); };
    const used = systems.map(s => (s.name || '').trim().toLowerCase());
    const presets = D.SYSTEM_SUGGESTIONS.filter(p => used.indexOf(p.toLowerCase()) < 0);
    return (
      <div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {systems.map((s, i) => <SystemCard key={i} s={s} num={i + 1} unitNames={unitNames} onToggle={() => openOnly(i)} onPatch={(p) => patch(i, p)} onRemove={() => removeSystem(i)} goB={goB} />)}
        </div>
        {presets.length > 0 && (
          <div style={{ background: C.paper2, borderRadius: 8, padding: '12px 14px', marginTop: 10, display: 'flex', flexWrap: 'wrap', gap: 7, alignItems: 'center' }}>
            <span style={{ fontSize: 12, color: C.meta, fontWeight: 500 }}>Quick-add:</span>
            {presets.map(p => <button key={p} onClick={() => addNamed(p)} style={{ border: '1px solid ' + C.rule2, background: C.white, borderRadius: 999, padding: '5px 11px', fontSize: 12.5, color: C.ink1, cursor: 'pointer', fontFamily: "'Outfit',sans-serif" }}>+ {p}</button>)}
          </div>
        )}
        <button onClick={addSystem} style={{ width: '100%', marginTop: 10, border: '1.5px dashed ' + C.rule2, background: 'transparent', borderRadius: 8, height: 46, fontFamily: "'Outfit',sans-serif", fontSize: 13.5, fontWeight: 500, color: C.sec, cursor: 'pointer' }}>+ Add custom system</button>
      </div>
    );
  }

  function SystemCard({ s, num, unitNames, onToggle, onPatch, onRemove, goB }) {
    const summary = [((s.info || []).length || 'no') + ' info types', (s.units || []).length ? 'used by ' + s.units.join(', ') : 'no units linked'].join(' · ');
    if (!s.open) {
      return (
        <button onClick={onToggle} style={{ width: '100%', textAlign: 'left', background: C.white, border: '1px solid ' + C.rule, borderRadius: 8, minHeight: 50, padding: '10px 14px', cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 12 }}>
          <span style={{ width: 22, height: 22, borderRadius: '50%', background: C.paper3, color: C.sec, fontSize: 12, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>{num}</span>
          <span style={{ flex: 1, minWidth: 0 }}>
            <span style={{ display: 'block', fontSize: 14, fontWeight: 500, color: C.ink }}>{s.name || 'New system'}</span>
            <span style={{ display: 'block', fontSize: 12, color: C.meta, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{summary}</span>
          </span>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: 12, color: C.blue }}><Pencil />Edit</span>
        </button>
      );
    }
    return (
      <div style={{ border: '1.5px solid ' + C.blue, borderRadius: 8, boxShadow: '0 0 0 3px rgba(46,93,255,0.08)', overflow: 'hidden', animation: 'intkExpand .26s ease both' }}>
        <div style={{ background: C.blueTint, padding: '10px 16px', display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{ width: 22, height: 22, borderRadius: '50%', background: C.blue, color: C.white, fontSize: 12, display: 'inline-flex', alignItems: 'center', justifyContent: 'center' }}>{num}</span>
          <span style={{ fontSize: 11.5, textTransform: 'uppercase', letterSpacing: '0.06em', color: C.blueDk, fontWeight: 600 }}>{s.name ? 'Editing: ' + s.name : 'New system: name it below'}</span>
        </div>
        <div style={{ padding: '16px 18px 18px', background: C.white }}>
          <div style={{ marginBottom: 14 }}><Label>System name</Label><input value={s.name} onChange={e => onPatch({ name: e.target.value })} list="dl-systems" placeholder="e.g. QuickBooks" style={INPUT} /></div>
          <div style={{ marginBottom: 14 }}><Label>What kind of information lives in it?</Label><ChipRow small options={D.INFO_CHIPS} value={s.info} multi onPick={(v) => onPatch({ info: v })} /></div>
          <div style={{ marginBottom: 16 }}>
            <Label>Which business units use it?</Label>
            {unitNames.length ? <ChipRow small options={unitNames} value={s.units} multi onPick={(v) => onPatch({ units: v })} />
              : <div style={{ fontSize: 13, color: C.sec }}>No business units named yet. Add them in <button onClick={goB} style={{ background: 'none', border: 'none', color: C.blue, cursor: 'pointer', padding: 0, fontSize: 13, fontFamily: "'Outfit',sans-serif" }}>Your Organization</button>, or continue.</div>}
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between' }}>
            <button onClick={onRemove} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, border: '1px solid rgba(192,61,46,0.3)', background: C.white, color: '#c03d2e', borderRadius: 8, height: 40, padding: '0 14px', fontFamily: "'Outfit',sans-serif", fontSize: 13, cursor: 'pointer' }}><Trash />Remove system</button>
            <button onClick={onToggle} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, border: 'none', background: C.blue, color: C.white, borderRadius: 8, height: 40, padding: '0 18px', fontFamily: "'Outfit',sans-serif", fontSize: 13, fontWeight: 600, cursor: 'pointer' }}><Check />Done</button>
          </div>
        </div>
      </div>
    );
  }

  // ─────────────────────────── SECTION C · WHERE TIME GOES ───────────────────
  // The SOPs document card, then a few open questions about repetition and friction.
  function SectionTime({ repetitive, setRepetitive, costly, setCostly, handoff, setHandoff, docs, setDocs, uploads, setUploads, pushUndo, go, onContinue }) {
    return (
      <div>
        <SecHead eyebrow="Section C" title="Where Time Goes" intro="A few open questions about repetition, friction, and the tasks you'd most like to hand off." />

        <div style={{ marginBottom: 8, fontSize: 11, fontWeight: 600, color: C.meta, letterSpacing: '0.06em', textTransform: 'uppercase' }}>Your processes</div>
        <DocBlock doc={DOC.sops} docs={docs} setDocs={setDocs} uploads={uploads} setUploads={setUploads} pushUndo={pushUndo} go={go} />

        <div style={{ marginTop: 28, marginBottom: 20 }}><Label>What are the most repetitive tasks your team does every week?</Label><textarea value={repetitive} onChange={e => setRepetitive(e.target.value)} rows={2} style={TEXTAREA} /></div>
        <div style={{ marginBottom: 20 }}><Label>Where do delays or errors cost you the most: money, clients, or time?</Label><textarea value={costly} onChange={e => setCostly(e.target.value)} rows={2} style={TEXTAREA} /></div>
        <div><Label>What tasks would you hand off to an assistant or intern tomorrow?</Label><textarea value={handoff} onChange={e => setHandoff(e.target.value)} rows={2} style={TEXTAREA} /></div>
        <ContinueBtn label="Review & Submit" onClick={onContinue} />
      </div>
    );
  }

  // ─────────────────────────── REVIEW ────────────────────────────────────────
  function SectionReview({ state, sectionCount, go, onSubmit, additional, setAdditional }) {
    const rows = D.SECTIONS.filter(s => s.stage === 1).map(s => {
      const c = sectionCount(s.id);
      const done = c.done >= c.total && c.total > 0;
      const part = c.done > 0 && !done;
      return { id: s.id, label: s.label, c, done, part };
    });
    const gaps = rows.some(r => !r.done);
    return (
      <div>
        <SecHead eyebrow="Stage 1 · Review & Submit" title="Here's what you've told us" intro="Gaps never block submission. Anything you skip we'll cover together at kickoff." />
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {rows.map(r => {
            const chip = r.done ? { l: 'Complete', bg: C.good + '22', fg: '#146b43' } : r.part ? { l: r.c.done + ' of ' + r.c.total + ' answered', bg: C.blueTint, fg: C.blueDk } : { l: 'Not started', bg: C.white, fg: C.meta };
            return (
              <div key={r.id} style={{ background: C.white, border: '1px solid ' + C.rule, borderRadius: 6, padding: '14px 18px', display: 'flex', alignItems: 'center', gap: 12 }}>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 14.5, fontWeight: 500, color: C.ink }}>{r.label}</div>
                </div>
                <span style={{ fontSize: 11.5, fontWeight: 600, padding: '4px 10px', borderRadius: 999, background: chip.bg, color: chip.fg, border: '1px solid ' + C.rule }}>{chip.l}</span>
                <button onClick={() => go(r.id)} style={{ display: 'inline-flex', alignItems: 'center', gap: 4, background: 'none', border: 'none', color: C.blue, cursor: 'pointer', fontSize: 12.5, fontFamily: "'Outfit',sans-serif" }}><Pencil />Edit</button>
              </div>
            );
          })}
        </div>
        <div style={{ marginTop: 24 }}>
          <Label>Additional comments</Label>
          <textarea value={additional || ''} onChange={e => setAdditional(e.target.value)} rows={3}
            placeholder="Anything else you'd like us to know before we begin our review."
            style={TEXTAREA} />
        </div>
        <div style={{ background: C.paper2, borderRadius: 10, padding: '24px', textAlign: 'center', marginTop: 24 }}>
          <p style={{ fontSize: 13.5, color: C.sec, margin: '0 0 16px' }}>{gaps ? 'Any gaps will be reviewed together at kickoff.' : 'All sections are complete.'}</p>
          <button onClick={onSubmit} style={{ border: 'none', background: C.blue, color: C.white, borderRadius: 8, padding: '0 26px', height: 48, fontFamily: "'Outfit',sans-serif", fontSize: 14, fontWeight: 600, cursor: 'pointer' }}>{gaps ? 'Submit Stage 1 with gaps' : 'Submit Stage 1'}</button>
          <div style={{ fontSize: 12, color: C.meta, marginTop: 12 }}>You can edit any answer until our review begins.</div>
        </div>
      </div>
    );
  }

  function SectionDone() {
    const Step = ({ n, blue, title, sub }) => (
      <div style={{ display: 'flex', gap: 14, alignItems: 'flex-start', padding: '8px 0' }}>
        <span style={{ width: 26, height: 26, borderRadius: '50%', background: blue ? C.blue : C.ink, color: C.white, fontSize: 13, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, fontFamily: "'DM Serif Display',serif" }}>{n}</span>
        <div><div style={{ fontSize: 14.5, fontWeight: 500, color: C.ink }}>{title}</div><div style={{ fontSize: 13, color: C.meta, marginTop: 2 }}>{sub}</div></div>
      </div>
    );
    return (
      <div style={{ textAlign: 'center', paddingTop: 20 }}>
        <div style={{ width: 52, height: 52, borderRadius: '50%', background: C.good, color: C.white, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', marginBottom: 18 }}><svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round"><path d="M20 6 9 17l-5-5" /></svg></div>
        <h1 style={{ fontFamily: "'DM Serif Display',serif", fontWeight: 400, fontSize: 32, color: C.ink, margin: '0 0 12px' }}>Thank you</h1>
        <p style={{ fontSize: 14.5, color: C.sec, lineHeight: 1.6, maxWidth: '46ch', margin: '0 auto 28px' }}>We'll review your answers and reach out if anything needs clarifying, then share your next steps. Expect to hear back within 3–4 days.</p>
        <div style={{ maxWidth: 420, margin: '0 auto', textAlign: 'left' }}>
          <div style={{ fontSize: 11, fontWeight: 600, color: C.meta, letterSpacing: '0.06em', textTransform: 'uppercase', marginBottom: 6 }}>Next Steps</div>
          <Step n="1" title="Linea reviews your answers" sub="We'll be in touch within 3–4 days." />
          <Step n="2" title="We will reach out with any questions or clarifications" sub="A short review of your systems — mostly handled at kickoff." />
          <Step n="3" blue title="Your readiness report lands here" sub="A live workspace: summary, data, workflows, roadmap." />
        </div>
      </div>
    );
  }

  // ─────────────────────────── STAGE 2: E ────────────────────────────────────
  function SectionE({ wfs, setWfs, onContinue }) {
    const groups = wfs || [];
    const patchItem = (gi, ii, p) => setWfs(list => list.map((g, j) => j !== gi ? g : Object.assign({}, g, { items: g.items.map((it, k) => k === ii ? Object.assign({}, it, p) : it) })));
    const addMissed = (gi) => setWfs(list => list.map((g, j) => j !== gi ? g : Object.assign({}, g, { items: g.items.concat([{ id: uid(), name: '', basis: 'Added by you', status: 'yes', custom: true }]) })));
    const confirmed = groups.reduce((n, g) => n + g.items.filter(i => i.status === 'yes').length, 0);
    if (!groups.length) {
      return <div><SecHead eyebrow="Stage 2 · Your Systems" title="Your Systems" /><p style={{ color: C.sec }}>Your draft workflow map will appear here once Linea has prepared it.</p></div>;
    }
    return (
      <div>
        <div style={{ background: C.ink, color: C.white, borderRadius: 10, padding: '18px 20px', marginBottom: 24 }}>
          <div style={{ fontSize: 10.5, letterSpacing: '0.12em', textTransform: 'uppercase', color: '#9db4ff', fontWeight: 600, marginBottom: 4 }}>Welcome back</div>
          <div style={{ fontFamily: "'DM Serif Display',serif", fontSize: 19 }}>Here is what we have drafted.</div>
          <p style={{ fontSize: 13, color: '#c8cad0', margin: '6px 0 0', lineHeight: 1.55 }}>From your answers we mapped the workflows below. Confirm the ones that fit, adjust the details, and add anything we missed.</p>
        </div>
        <SecHead eyebrow="Stage 2 · Your Systems" title="Confirm Your Workflows" />
        {groups.map((g, gi) => (
          <div key={gi} style={{ marginBottom: 26 }}>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, borderBottom: '1px solid ' + C.rule, paddingBottom: 8, marginBottom: 12 }}>
              <span style={{ fontFamily: "'DM Serif Display',serif", fontSize: 19, color: C.ink }}>{g.unit}</span>
              <span style={{ fontSize: 12, color: C.meta }}>from your organization</span>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              {g.items.map((w, ii) => <WorkflowCard key={w.id || ii} w={w} onPatch={(p) => patchItem(gi, ii, p)} />)}
            </div>
            <button onClick={() => addMissed(gi)} style={{ width: '100%', marginTop: 10, border: '1.5px dashed ' + C.rule2, background: 'transparent', borderRadius: 8, height: 44, fontFamily: "'Outfit',sans-serif", fontSize: 13, fontWeight: 500, color: C.sec, cursor: 'pointer' }}>+ Add a workflow we missed in {g.unit}</button>
          </div>
        ))}
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 8 }}>
          <span style={{ fontSize: 13, color: C.meta }}>{confirmed} confirmed. Any uncertain items can wait for kickoff.</span>
          <button onClick={onContinue} style={{ border: 'none', background: C.ink, color: C.white, borderRadius: 8, padding: '0 22px', height: 44, fontFamily: "'Outfit',sans-serif", fontSize: 14, fontWeight: 600, cursor: 'pointer' }}>Continue: System Details</button>
        </div>
      </div>
    );
  }
  function WorkflowCard({ w, onPatch }) {
    const dismissed = w.status === 'no';
    return (
      <div style={{ background: C.white, border: '1px solid ' + C.rule, borderRadius: 6, padding: '16px 18px', opacity: dismissed ? 0.55 : 1 }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap' }}>
          <div style={{ flex: 1, minWidth: 200 }}>
            {w.custom ? <input value={w.name} onChange={e => onPatch({ name: e.target.value })} placeholder="Name the workflow…" style={INPUT} />
              : <div><div style={{ fontSize: 14.5, fontWeight: 500, color: C.ink }}>{w.name}</div>{w.basis && <div style={{ fontSize: 12, color: C.meta, marginTop: 2 }}>{w.basis}</div>}</div>}
          </div>
          <div style={{ display: 'flex', gap: 7, alignItems: 'flex-start' }}>
            <button onClick={() => onPatch({ status: w.status === 'yes' ? '' : 'yes' })} aria-pressed={w.status === 'yes'}
              style={{ border: '1px solid ' + (w.status === 'yes' ? 'transparent' : C.rule2), background: w.status === 'yes' ? C.good : C.white, color: w.status === 'yes' ? C.white : C.ink1, borderRadius: 8, height: 38, padding: '0 14px', fontSize: 13, fontWeight: 600, cursor: 'pointer', fontFamily: "'Outfit',sans-serif" }}>{w.status === 'yes' ? '✓ Yes, we do this' : 'Yes, we do this'}</button>
            {!dismissed && <button onClick={() => onPatch({ status: 'no' })} style={{ border: '1px solid ' + C.rule2, background: C.white, color: C.sec, borderRadius: 8, height: 38, padding: '0 12px', fontSize: 13, cursor: 'pointer', fontFamily: "'Outfit',sans-serif" }}>Doesn't apply</button>}
          </div>
        </div>
        {dismissed && <div style={{ fontSize: 12.5, color: C.meta, marginTop: 10 }}>Marked as not applicable. <button onClick={() => onPatch({ status: '' })} style={{ background: 'none', border: 'none', color: C.blue, cursor: 'pointer', padding: 0, fontSize: 12.5, fontFamily: "'Outfit',sans-serif" }}>Undo</button></div>}
        {!dismissed && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 11, marginTop: 14 }}>
            <div><Label>How often?</Label><ChipRow small options={D.FREQ} value={w.freq} onPick={(v) => onPatch({ freq: v })} /></div>
            <div><Label>Rough total team time per week</Label><ChipRow small options={D.HOURS} value={w.hours} onPick={(v) => onPatch({ hours: v })} /></div>
            <div><Label>Written down anywhere?</Label><ChipRow small options={D.DOCD} value={w.doc} onPick={(v) => onPatch({ doc: v })} /></div>
            <div><Label>Routine vs. judgment</Label><ChipRow small options={D.ROUTINE} value={w.routine} onPick={(v) => onPatch({ routine: v })} /></div>
            <div><Label>What goes wrong most often? (optional)</Label><input value={w.notes || ''} onChange={e => onPatch({ notes: e.target.value })} style={INPUT} /></div>
          </div>
        )}
      </div>
    );
  }

  // ─────────────────────────── STAGE 2: F ────────────────────────────────────
  function SectionF({ sysd, setSysd, submitted, onFinish }) {
    const cards = sysd || [];
    const patch = (i, p) => setSysd(list => list.map((s, j) => j === i ? Object.assign({}, s, p) : s));
    return (
      <div>
        <SecHead eyebrow="Stage 2 · System Details" title="System Details" intro="A few specifics on the systems behind the workflows you confirmed. We've pre-filled what we could." />
        {!cards.length && <p style={{ color: C.sec }}>System details will appear here once Linea has prepared them.</p>}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          {cards.map((sd, i) => (
            <div key={sd.id || i} style={{ background: C.white, border: '1px solid ' + C.rule, borderRadius: 6, padding: '16px 18px' }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 14 }}>
                <span style={{ fontSize: 15, fontWeight: 600, color: C.ink }}>{sd.name}</span>
                <span style={{ fontSize: 11, color: C.blueDk, background: C.blueTint, borderRadius: 999, padding: '3px 9px' }}>Pre-filled by Linea</span>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 13 }}>
                <div><Label>Where does it run?</Label><ChipRow small options={D.RUNS} value={sd.runs} onPick={(v) => patch(i, { runs: v })} /></div>
                <div style={{ maxWidth: 340 }}><Label>Who owns it day to day? (name or role)</Label><input value={sd.owner || ''} onChange={e => patch(i, { owner: e.target.value })} placeholder="e.g. Maria, our bookkeeper" style={INPUT} /></div>
                <div><Label>How does information get in?</Label><ChipRow small options={D.DATA_IN} value={sd.dataIn} onPick={(v) => patch(i, { dataIn: v })} /></div>
                <div><Label>Could you export the data if needed?</Label><ChipRow small options={D.EXPORTABLE} value={sd.exportable} onPick={(v) => patch(i, { exportable: v })} /></div>
                <div><Label>Any privacy, security, or compliance rules around it?</Label><ChipRow small options={D.COMPLIANCE} value={sd.compliance} multi onPick={(v) => patch(i, { compliance: v })} /></div>
                <div><input value={sd.notes || ''} onChange={e => patch(i, { notes: e.target.value })} placeholder="Anything else we should know (optional)" style={INPUT} /></div>
              </div>
            </div>
          ))}
        </div>
        {submitted && <div style={{ background: C.good + '18', border: '1px solid ' + C.good + '55', borderRadius: 8, padding: '14px 16px', marginTop: 20, color: '#146b43', fontSize: 13.5 }}>All confirmed, thank you. Next: your readiness report will appear in Stage 3 once it's ready.</div>}
        <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 20 }}>
          <button onClick={onFinish} style={{ border: 'none', background: C.blue, color: C.white, borderRadius: 8, padding: '0 24px', height: 46, fontFamily: "'Outfit',sans-serif", fontSize: 14, fontWeight: 600, cursor: 'pointer' }}>Send confirmations to Linea</button>
        </div>
      </div>
    );
  }

  // ─────────────────────────── STAGE 3 ───────────────────────────────────────
  function SectionReport({ onOpenReport }) {
    const items = [
      ['01', 'Executive summary', 'Your composite readiness score, recommended phase, and headline findings.'],
      ['02', 'Data readiness', 'Every system you named, tiered: ready now, needs prep, longer-term.'],
      ['03', 'Workflow inventory', 'The workflows you confirmed, scored for value, effort, and build-readiness.'],
      ['04', 'Execution roadmap', 'What to build first, what it unlocks, and the recommended next step.'],
    ];
    return (
      <div>
        <SecHead eyebrow="Stage 3 · Your assessment" title="Your AI Readiness Assessment" intro="A live workspace, not a static PDF. Your full assessment is ready to explore." />
        <div style={{ borderTop: '1px solid ' + C.rule }}>
          {items.map(([n, t, d]) => (
            <div key={n} style={{ display: 'flex', gap: 16, alignItems: 'flex-start', padding: '16px 0', borderBottom: '1px solid ' + C.rule }}>
              <span style={{ fontFamily: "'DM Serif Display',serif", fontSize: 22, color: C.blue, minWidth: 34 }}>{n}</span>
              <div><div style={{ fontSize: 15, fontWeight: 600, color: C.ink }}>{t}</div><div style={{ fontSize: 13.5, color: C.sec, marginTop: 3 }}>{d}</div></div>
            </div>
          ))}
        </div>
        <div style={{ background: C.paper2, borderRadius: 10, padding: 24, marginTop: 24, textAlign: 'center' }}>
          <p style={{ fontSize: 14, color: C.sec, margin: '0 0 16px' }}>Your report is ready. Open it to explore the full interactive assessment.</p>
          <button onClick={onOpenReport} style={{ border: 'none', background: C.ink, color: C.white, borderRadius: 999, padding: '0 26px', height: 48, fontFamily: "'Outfit',sans-serif", fontSize: 14, fontWeight: 600, cursor: 'pointer' }}>Open the report</button>
        </div>
      </div>
    );
  }

  // ─────────────────────────── QUESTIONS PANEL ───────────────────────────────
  function QuestionsPanel({ questions, qDraft, setQDraft, sectionLabel, onSend, onClose }) {
    // Newest first — this is the running history of everything sent to Linea.
    const history = questions.slice().reverse();
    const onKey = (e) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); onSend(); } };
    return (
      <React.Fragment>
        <div onClick={onClose} style={{ position: 'fixed', inset: 0, zIndex: 55 }} />
        <div style={{ position: 'fixed', left: 18, bottom: 18, zIndex: 60, width: 344, background: C.paper, border: '1px solid ' + C.rule, borderRadius: 10, boxShadow: '0 16px 50px rgba(0,0,0,0.22)', overflow: 'hidden', animation: 'intkPanelIn .2s ease both' }}>
          <div style={{ background: C.ink, padding: '14px 16px', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 10 }}>
            <div>
              <div style={{ fontSize: 10.5, letterSpacing: '0.1em', textTransform: 'uppercase', color: '#9db4ff', fontWeight: 600 }}>Questions for Linea</div>
              <div style={{ fontSize: 12.5, color: '#c8cad0', marginTop: 3 }}>Send anything unclear and we'll answer before kickoff.</div>
            </div>
            <button onClick={onClose} style={{ background: 'none', border: 'none', color: '#c8cad0', cursor: 'pointer', fontSize: 18, lineHeight: 1, padding: 0 }}>×</button>
          </div>
          <div style={{ padding: '12px 14px' }}>
            <textarea value={qDraft} onChange={e => setQDraft(e.target.value)} onKeyDown={onKey} rows={2} placeholder={'Type a question about ' + sectionLabel + '…'} style={Object.assign({}, TEXTAREA, { background: C.white })} />
            <button onClick={onSend} disabled={!qDraft.trim()} style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 7, width: '100%', marginTop: 8, border: 'none', background: qDraft.trim() ? C.blue : C.dim, color: C.white, borderRadius: 8, height: 42, fontFamily: "'Outfit',sans-serif", fontSize: 13, fontWeight: 600, cursor: qDraft.trim() ? 'pointer' : 'default' }}>{sv(<><path d="M22 2L11 13M22 2l-7 20-4-9-9-4z" /></>)}Send to Linea</button>
          </div>
          <div style={{ borderTop: '1px solid ' + C.rule, padding: '12px 14px 14px' }}>
            <div style={{ fontSize: 11, letterSpacing: '0.06em', textTransform: 'uppercase', color: C.meta, fontWeight: 600, marginBottom: 9 }}>Sent history{history.length ? ' · ' + history.length : ''}</div>
            <div style={{ maxHeight: '38vh', overflow: 'auto', display: 'flex', flexDirection: 'column', gap: 8 }}>
              {history.map(q => (
                <div key={q.id} style={{ background: C.white, border: '1px solid ' + C.rule, borderRadius: 8, padding: '10px 12px' }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 5 }}>
                    {q.section && <span style={{ fontSize: 10, textTransform: 'uppercase', letterSpacing: '0.05em', color: C.blueDk, background: C.blueTint, borderRadius: 4, padding: '2px 6px' }}>{q.section}</span>}
                    <span style={{ flex: 1 }} />
                    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 4, fontSize: 11, color: q.sent ? C.good : C.meta }}>{q.sent ? <React.Fragment><Check />Sent</React.Fragment> : 'Sending…'}</span>
                  </div>
                  <div style={{ fontSize: 13, color: C.ink1 }}>{q.text}</div>
                  {q.createdAt && <div style={{ fontSize: 10.5, color: C.meta, marginTop: 4 }}>{q.createdAt}</div>}
                </div>
              ))}
              {!history.length && <div style={{ fontSize: 13, color: C.meta, textAlign: 'center', padding: '8px 0' }}>No questions sent yet.</div>}
            </div>
          </div>
        </div>
      </React.Fragment>
    );
  }

  window.IntakeApp = IntakeApp;
})();
