/* ELEV8 ATS - screens: Clients (book of business) and Contacts (the people there). */

const DSx = window.Stand8DesignSystem_b5c975;

const TIER_TONES = { Strategic: 'accent', Growth: 'info', Core: 'neutral', Emerging: 'neutral' };

/* Square monogram for company rows - distinct from the round person avatar. */
function ClientMark({ name }) {
  return <span className="e8-clientmark" aria-hidden="true">{name.replace(/[^A-Za-z0-9]/g, '').slice(0, 2)}</span>;
}

/* Lightweight create dialog - the shared creation modal (R98: promoted to window.E8CreateDialog,
   used by New client / contact / job here plus the submission / engagement / candidate flows).
   `fields` = [{ key, label, placeholder, required, initial, type:'text'|'select', options:[{value,label}],
                 note (node|fn(vals) shown under the field), onPick(value, { set, vals }) }]
   or a FUNCTION of the current values, so pickers can re-derive options/notes as the user chooses.
   Optional: `extra(vals, set)` renders below the fields (previews, dedup warnings);
   `disabled(vals)` adds a create gate; `footnote` replaces the footer hint text.
   Styled by reusing .e8-overlay + .e8-reject. Create stays disabled until every required field is filled. */
function CrmCreateDialog({ title, fields, createLabel = 'Create', createIcon = 'add', onClose, onCreate, extra, disabled, footnote }) {
  const [vals, setVals] = React.useState(() => {
    const fl = typeof fields === 'function' ? fields({}) : fields;
    const init = {};
    fl.forEach((f) => { init[f.key] = f.initial != null ? f.initial : (f.type === 'select' ? (f.options && f.options[0] ? f.options[0].value : '') : ''); });
    return init;
  });
  const [touched, setTouched] = React.useState({});
  const fieldList = typeof fields === 'function' ? fields(vals) : fields;
  const set = (k, v) => setVals((p) => ({ ...p, [k]: v }));
  const pick = (f, v) => { set(f.key, v); if (f.onPick) f.onPick(v, { set, vals: { ...vals, [f.key]: v } }); };
  const canCreate = fieldList.every((f) => !f.required || String(vals[f.key] || '').trim()) && !(disabled && disabled(vals));
  const submit = () => { if (!canCreate) return; onCreate(vals); };
  return (
    <DSx.Modal title={title} ariaLabel={title} closeTitle="Cancel" onClose={onClose}>
      <div style={{ padding: '14px 16px', display: 'grid', gap: 12 }}>
        {fieldList.map((f, i) => {
            const invalid = f.required && touched[f.key] && !String(vals[f.key] || '').trim();
            const note = typeof f.note === 'function' ? f.note(vals) : f.note;
            return (
              <DSx.Field key={f.key} label={f.label + (f.required ? ' *' : '')} error={invalid ? f.label + ' is required' : undefined}>
                {f.type === 'select' ? (
                  <DSx.Select value={vals[f.key]} onChange={(e) => pick(f, e.target.value)} options={f.options} />
                ) : (
                  <DSx.Input
                    autoFocus={i === 0}
                    placeholder={f.placeholder || ''}
                    value={vals[f.key]}
                    onChange={(e) => pick(f, e.target ? e.target.value : e)}
                    onBlur={() => setTouched((t) => ({ ...t, [f.key]: true }))}
                    onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); submit(); } }}
                  />
                )}
                {note ? <div style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)', marginTop: 5, lineHeight: 1.45 }}>{note}</div> : null}
              </DSx.Field>
            );
          })}
          {extra ? extra(vals, set) : null}
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 2 }}>
            <span style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)', flex: 1 }}>{footnote || ''}</span>
            <DSx.Button variant="ghost" size="sm" onClick={onClose}>Cancel</DSx.Button>
            <DSx.Button variant="primary" size="sm" icon={createIcon} disabled={!canCreate} onClick={submit}>{createLabel}</DSx.Button>
          </div>
        </div>
    </DSx.Modal>
  );
}

/* ============================== CLIENTS ============================== */
function ClientsScreen() {
  const D = window.E8DATA;
  const { showToast, density } = React.useContext(E8Ctx);
  const [insights, setInsights] = React.useState(D.insights.clients);
  const [tier, setTier] = React.useState('all');
  const [creating, setCreating] = React.useState(false);

  const tiers = ['Strategic', 'Core', 'Growth', 'Emerging'];
  const [query, setQuery] = React.useState('');
  const q = query.trim().toLowerCase();
  const rows = D.clients.filter((c) => (tier === 'all' || c.tier === tier) && (!q || Object.values(c).some((v) => typeof v === 'string' && v.toLowerCase().includes(q))));
  const counts = Object.fromEntries(tiers.map((t) => [t, D.clients.filter((c) => c.tier === t).length]));

  return (
    <React.Fragment>
      <Topbar
        crumbs={[{ label: 'Clients' }]}
        actions={
          <React.Fragment>
            <DSx.InsightsButton
              items={insights.map((i) => ({
                id: i.id,
                text: <span><b>{i.strong}</b>{i.rest}</span>,
                action: { label: i.action, onClick: () => showToast(i.action + ' - drafted, review in Approvals', 'Open approvals', () => navigate('approvals')) },
              }))}
              onDismiss={(id) => setInsights(insights.filter((x) => x.id !== id))}
            />
            <DSx.Button variant="secondary" size="sm" icon="upload">Export</DSx.Button>
            <DSx.Button variant="primary" size="sm" icon="add" onClick={() => setCreating(true)}>New client</DSx.Button>
          </React.Fragment>
        }
      />
      {creating ? (
        <CrmCreateDialog
          title="New client"
          createLabel="Create client"
          fields={[
            { key: 'name', label: 'Company name', placeholder: 'e.g. Northwind Logistics', required: true },
            { key: 'industry', label: 'Industry', placeholder: 'e.g. Manufacturing' },
            { key: 'tier', label: 'Tier', type: 'select', options: tiers.map((t) => ({ value: t, label: t })) },
          ]}
          onClose={() => setCreating(false)}
          onCreate={(v) => {
            setCreating(false);
            /* R78: creates are real - the record persists via the E8Store overlay. */
            const name = v.name.trim();
            const slug = 'cl-' + name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 24);
            let id = slug, n = 2;
            while ((window.E8DATA.clients || []).some((r) => r.id === id)) id = slug + '-' + n++;
            window.E8Store.add('clients', {
              id, name, industry: v.industry || '-', tier: v.tier || 'Growth', since: '2026',
              health: { label: 'New', tone: 'info', note: 'Created just now - no activity yet' },
              openJobs: 0, consultants: 0, renewals: 0, ar: { label: 'Current', tone: 'success' },
              csm: 'Unassigned', lastTouch: 'Just now', terms: 'TBD', msa: 'Not signed',
            });
            if (window.E8Audit) window.E8Audit.log({ agent: 'You', prov: 'human', action: 'Created client', target: name, route: 'client/' + id });
            showToast('Created "' + name + '"', 'Open', () => navigate('client/' + id));
          }}
        />
      ) : null}
      <div className="e8-content">
        <div className="e8-page">
          <div style={{ display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap', margin: '0 0 14px' }}>
            <DSx.SubTabs
              items={[
                { id: 'all', label: 'All', count: D.clients.length },
                ...tiers.map((t) => ({ id: t, label: t, count: counts[t] })),
              ]}
              active={tier}
              onChange={setTier}
            />
            <div style={{ flex: 1, minWidth: 240, maxWidth: 440 }}>
              <DSx.Input icon="search" placeholder="Search clients - name, industry, CSM…" value={query} onChange={(e) => setQuery(e.target ? e.target.value : e)} />
            </div>
          </div>

          <ConfigurableTable
            listKey="clients"
            empty={<div style={{ maxWidth: 460, margin: '24px auto' }}><DSx.EmptyState icon="domain" title="No clients match" body="Try a different tier or clear your search." /></div>}
            density={density}
            onRowClick={(r) => navigate('client/' + r.id)}
            registry={[
              { key: 'name', label: 'Client', locked: true, sortable: true, sortValue: (r) => r.name, render: (r) => (
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 9 }}>
                  <ClientMark name={r.name} />
                  <span style={{ minWidth: 0 }}>
                    <span style={{ display: 'block', fontWeight: 500 }}>{r.name}</span>
                    <span style={{ display: 'block', fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-tertiary)' }}>{r.industry} · since {r.since}</span>
                  </span>
                </span>
              ) },
              { key: 'tier', label: 'Tier', sortable: true, sortValue: (r) => r.tier, render: (r) => <DSx.Badge tone={TIER_TONES[r.tier] || 'neutral'}>{r.tier}</DSx.Badge> },
              { key: 'health', label: 'Health', icon: 'monitor_heart', render: (r) => (
                <span title={r.health.note}>
                  <DSx.Badge tone={r.health.tone} dot={r.health.tone !== 'neutral'}>{r.health.label}</DSx.Badge>
                </span>
              ) },
              { key: 'signals', label: 'Signals', icon: 'sensors', render: (r) => {
                const ix = D.clientIntel && D.clientIntel[r.id];
                if (!ix) return <span style={{ color: 'var(--ui-text-tertiary)' }}>-</span>;
                const og = D.clientOrg && D.clientOrg[r.id];
                const hiringPeople = og ? og.nodes.filter((n) => n.hiring && n.hiring.count).length : 0;
                return (
                  <span style={{ display: 'inline-flex', flexDirection: 'column', gap: 1, maxWidth: 168 }} title={'Top buying-intent topic: ' + ix.intent[0][0]}>
                    <span style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-secondary)', display: 'inline-flex', alignItems: 'center', gap: 4, minWidth: 0 }}>
                      <span className="material-symbols-outlined" style={{ fontSize: 13, color: 'var(--ui-accent)', flexShrink: 0 }}>bolt</span>
                      <span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{ix.intent[0][0]}</span>
                    </span>
                    {hiringPeople ? <span style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)' }}>{hiringPeople} hiring · {ix.discovered.length} to add</span> : null}
                  </span>
                );
              } },
              { key: 'openJobs', label: 'Open jobs', num: true, sortable: true, sortValue: (r) => r.openJobs || 0, render: (r) => (
                r.openJobs
                  ? <a className="e8-link tnum" tabIndex={0} onKeyDown={window.keyActivate} onClick={(e) => { e.stopPropagation(); navigate('jobs'); }}>{r.openJobs}</a>
                  : <span style={{ color: 'var(--ui-text-tertiary)' }}>-</span>
              ) },
              { key: 'consultants', label: 'On billing', num: true, sortable: true, sortValue: (r) => r.consultants || 0 },
              { key: 'renewals', label: 'Renewals 90d', num: true, render: (r) => (
                r.renewals
                  ? <a className="e8-link tnum" tabIndex={0} onKeyDown={window.keyActivate} onClick={(e) => { e.stopPropagation(); navigate('renewals'); }}>{r.renewals}</a>
                  : <span style={{ color: 'var(--ui-text-tertiary)' }}>-</span>
              ) },
              { key: 'ar', label: 'Billing', render: (r) => <DSx.Badge tone={r.ar.tone} dot={r.ar.tone !== 'success'}>{r.ar.label}</DSx.Badge> },
              { key: 'csm', label: 'CSM', render: (r) => <ActorChip name={r.csm} /> },
              { key: 'lastTouch', label: 'Last touch', secondary: true, render: (r) => <span className="tnum">{r.lastTouch}</span> },
            ]}
            rows={rows}
            rowActions={(r) => (
              <React.Fragment>
                <DSx.Button variant="ghost" size="sm" icon="add" onClick={() => showToast('New job order started for ' + r.name)}>New job</DSx.Button>
                <DSx.MenuButton
                  items={[
                    { icon: 'forum', label: 'Draft check-in', onClick: () => showToast('Check-in drafted for ' + r.name + ' - review in Approvals') },
                    { icon: 'group', label: 'View contacts', onClick: () => navigate('contacts') },
                    { icon: 'badge', label: 'View engagements', onClick: () => navigate('engagements') },
                    { separator: true },
                    { icon: 'archive', label: 'Archive client', danger: true },
                  ]}
                />
              </React.Fragment>
            )}
          />
        </div>
      </div>
    </React.Fragment>
  );
}

/* ============================== CONTACTS ============================== */
const CHANNEL_ICONS = { call: 'call', email: 'mail' };

function ContactsScreen() {
  const D = window.E8DATA;
  const { showToast, density } = React.useContext(E8Ctx);
  const [insights, setInsights] = React.useState(D.insights.contacts);
  const [filter, setFilter] = React.useState('all');
  const [creating, setCreating] = React.useState(false);

  const buckets = {
    all: D.contacts,
    strong: D.contacts.filter((c) => c.strength.label === 'Strong'),
    cooling: D.contacts.filter((c) => c.strength.label === 'Cooling'),
    sponsors: D.contacts.filter((c) => c.owns.includes('sponsor')),
  };
  const [query, setQuery] = React.useState('');
  const q = query.trim().toLowerCase();
  const rows = (buckets[filter] || buckets.all).filter((c) => !q || Object.values(c).some((v) => typeof v === 'string' && v.toLowerCase().includes(q)));

  return (
    <React.Fragment>
      <Topbar
        crumbs={[{ label: 'Contacts' }]}
        actions={
          <React.Fragment>
            <DSx.InsightsButton
              items={insights.map((i) => ({
                id: i.id,
                text: <span><b>{i.strong}</b>{i.rest}</span>,
                action: { label: i.action, onClick: () => (i.id === 'ix2' ? navigate('approvals') : showToast(i.action + ' - drafted, review in Approvals', 'Open approvals', () => navigate('approvals'))) },
              }))}
              onDismiss={(id) => setInsights(insights.filter((x) => x.id !== id))}
            />
            <DSx.Button variant="secondary" size="sm" icon="download">Import</DSx.Button>
            <DSx.Button variant="primary" size="sm" icon="person_add" onClick={() => setCreating(true)}>New contact</DSx.Button>
          </React.Fragment>
        }
      />
      {creating ? (
        <CrmCreateDialog
          title="New contact"
          createLabel="Create contact"
          fields={[
            { key: 'name', label: 'Full name', placeholder: 'e.g. Dana Whitfield', required: true },
            { key: 'title', label: 'Title', placeholder: 'e.g. VP Engineering' },
            { key: 'client', label: 'Client', placeholder: 'e.g. Northwind Logistics' },
          ]}
          onClose={() => setCreating(false)}
          onCreate={(v) => {
            setCreating(false);
            /* R78: creates are real - the record persists via the E8Store overlay. */
            const name = v.name.trim();
            const slug = 'ct-' + name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 24);
            let id = slug, n = 2;
            while ((window.E8DATA.contacts || []).some((r) => r.id === id)) id = slug + '-' + n++;
            window.E8Store.add('contacts', {
              id, name, role: v.title || '-', client: v.client || '-',
              email: name.toLowerCase().replace(/[^a-z]+/g, '.') + '@' + (v.client || 'company').toLowerCase().replace(/[^a-z]+/g, '') + '.com',
              phone: '-', owns: '-', strength: { label: 'New', tone: 'info' }, lastTouch: 'Just now', channel: 'email',
              reply: 'No history yet', next: 'Introduce yourself',
            });
            if (window.E8Audit) window.E8Audit.log({ agent: 'You', prov: 'human', action: 'Created contact', target: name, route: 'contact/' + id });
            showToast('Created "' + name + '"', 'Open', () => navigate('contact/' + id));
          }}
        />
      ) : null}
      <div className="e8-content">
        <div className="e8-page">
          <div style={{ display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap', margin: '0 0 14px' }}>
            <DSx.SubTabs
              items={[
                { id: 'all', label: 'All', count: buckets.all.length },
                { id: 'sponsors', label: 'Sponsors', count: buckets.sponsors.length },
                { id: 'strong', label: 'Strong', count: buckets.strong.length },
                { id: 'cooling', label: 'Cooling', count: buckets.cooling.length },
              ]}
              active={filter}
              onChange={setFilter}
            />
            <div style={{ flex: 1, minWidth: 240, maxWidth: 440 }}>
              <DSx.Input icon="search" placeholder="Search contacts - name, title, client…" value={query} onChange={(e) => setQuery(e.target ? e.target.value : e)} />
            </div>
          </div>

          <ConfigurableTable
            listKey="contacts"
            empty={<div style={{ maxWidth: 460, margin: '24px auto' }}><DSx.EmptyState icon="contacts" title="No contacts match" body="Try a different filter or clear your search." /></div>}
            density={density}
            onRowClick={(r) => navigate('contact/' + r.id)}
            registry={[
              { key: 'name', label: 'Contact', locked: true, sortable: true, sortValue: (r) => r.name, render: (r) => <NameCell name={r.name} sub={r.role} /> },
              { key: 'client', label: 'Client', secondary: true, sortable: true, sortValue: (r) => r.client },
              { key: 'owns', label: 'Owns', icon: 'assignment_ind', render: (r) => (
                <span style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-secondary)' }}>{r.owns}</span>
              ) },
              { key: 'hiring', label: 'Hiring', icon: 'trending_up', render: (r) => <HiringChip hiring={r.hiring} /> },
              { key: 'strength', label: 'Relationship', icon: 'favorite', render: (r) => (
                <span title={r.reply}>
                  <DSx.Badge tone={r.strength.tone} dot={r.strength.tone !== 'neutral'}>{r.strength.label}</DSx.Badge>
                </span>
              ) },
              { key: 'lastTouch', label: 'Last touch', icon: 'schedule', render: (r) => (
                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
                  <span className="material-symbols-outlined" style={{ fontSize: 14, color: 'var(--ui-text-tertiary)' }}>{CHANNEL_ICONS[r.channel] || 'mail'}</span>
                  <span className="tnum" style={{ color: 'var(--ui-text-secondary)' }}>{r.lastTouch}</span>
                </span>
              ) },
              { key: 'next', label: 'Next step', icon: 'arrow_forward', render: (r) => (
                <a
                  className="e8-link"
                  style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-secondary)', borderBottom: '1px dashed var(--ui-border-strong)' }}
                  title="Suggested by ELEV8 - based on open work and reply patterns"
                  tabIndex={0} onKeyDown={window.keyActivate} onClick={(e) => { e.stopPropagation(); showToast(r.next + ' - drafted, review in Approvals', 'Open approvals', () => navigate('approvals')); }}
                >{r.next}</a>
              ) },
              { key: 'email', label: 'Email', icon: 'alternate_email', render: (r) => <CellChip icon="mail">{r.email}</CellChip> },
            ]}
            rows={rows}
            rowActions={(r) => (
              <React.Fragment>
                <DSx.Button variant="ghost" size="sm" icon="mail" onClick={() => showToast('Email drafted to ' + r.name + ' - review in Approvals')}>Draft email</DSx.Button>
                <DSx.MenuButton
                  items={[
                    { icon: 'call', label: 'Log a call' },
                    { icon: 'event', label: 'Schedule meeting' },
                    { separator: true },
                    { icon: 'archive', label: 'Archive contact', danger: true },
                  ]}
                />
              </React.Fragment>
            )}
          />
        </div>
      </div>
    </React.Fragment>
  );
}

/* ============================== COMPANY INTELLIGENCE ============================== */
/* The enriched dossier - synthesizes what an SEC EDGAR + ZoomInfo + news integration surfaces. */
const OWNERSHIP_TONES = { Public: 'info', Private: 'neutral', Nonprofit: 'accent' };
const FILING_TONES = { '10-K': 'info', '10-Q': 'neutral', '8-K': 'accent', 'DEF 14A': 'neutral', 'Form 990': 'accent', 'Annual report': 'neutral' };
const SIGNAL_DOT = { success: 'var(--ui-success)', warning: 'var(--ui-warning)', danger: 'var(--ui-danger)', info: 'var(--ui-accent)', neutral: 'var(--ui-text-tertiary)' };

function SourceChip({ children }) {
  return <span className="e8-srcchip"><span className="material-symbols-outlined" style={{ fontSize: 12 }}>database</span>{children}</span>;
}

function IntelTile({ label, value, sub, accent }) {
  return (
    <div className="e8-intel-tile">
      <div className="e8-intel-tile-k">{label}</div>
      <div className="e8-intel-tile-v tnum" style={accent ? { color: 'var(--ui-accent)' } : null}>{value}</div>
      {sub ? <div className="e8-intel-tile-sub">{sub}</div> : null}
    </div>
  );
}

/* People ZoomInfo/LinkedIn surfaced who aren't in our CRM yet. Reused on Company + Contacts tabs. */
function DiscoveredContacts({ intel, org, showToast }) {
  const DS = window.Stand8DesignSystem_b5c975;
  if (!intel.discovered || !intel.discovered.length) return null;
  const hiringFor = (name) => { if (!org || !org.nodes) return null; const n = org.nodes.find((x) => x.name === name); return n ? n.hiring : null; };
  return (
    <div className="e8-card e8-intel-card">
      <div className="e8-intel-cardhead">
        <span className="e8-sectionlabel">Decision-makers to add</span>
        <DS.ProvenanceBadge kind="advised" />
      </div>
      <div style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)', margin: '-2px 0 10px' }}>Surfaced by ELEV8 from ZoomInfo + LinkedIn - not yet in your CRM.</div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
        {intel.discovered.map((p, i) => (
          <div key={i} className="e8-disc-row">
            <DS.Avatar name={p.name} size="sm" />
            <div style={{ minWidth: 0, flex: 1 }}>
              <div style={{ fontSize: 'var(--ui-text-base)', fontWeight: 500 }}>{p.name}</div>
              <div style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)' }}>{p.role} · {p.dept}</div>
            </div>
            <HiringChip hiring={hiringFor(p.name)} />
            <span className="e8-disc-signal" title={p.tenure}>{p.signal}</span>
            <DS.Button variant="ghost" size="sm" icon="person_add" onClick={() => showToast(p.name + ' added to CRM - enriched from ZoomInfo')}>Add</DS.Button>
          </div>
        ))}
      </div>
    </div>
  );
}

function ClientCompanyTab({ c, intel, org, showToast }) {
  const DS = window.Stand8DesignSystem_b5c975;
  const E8C = window.E8Charts;
  if (!intel) {
    return <div style={{ maxWidth: 460, margin: '24px auto' }}><DS.EmptyState icon="domain" title="No company profile yet" body="Connect SEC EDGAR and ZoomInfo to enrich this account." /></div>;
  }
  const isPublic = intel.ownership === 'Public';
  const valTile = isPublic
    ? { label: 'Market cap', value: intel.fin.marketCap, sub: intel.ticker + ' · ' + intel.exchange }
    : { label: 'Ownership', value: intel.ownership, sub: intel.backer || (intel.ownership === 'Nonprofit' ? '501(c)(3)' : '') };

  return (
    <div className="e8-intel">
      {/* Snapshot band */}
      <div className="e8-intel-snap">
        <span className="e8-clientmark e8-clientmark-lg" aria-hidden="true">{c.name.replace(/[^A-Za-z0-9]/g, '').slice(0, 2)}</span>
        <div style={{ minWidth: 0, flex: 1 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
            <span style={{ fontSize: 'var(--ui-text-lg)', fontWeight: 600 }}>{c.name}</span>
            {intel.ticker ? <span className="e8-ticker">{intel.exchange}: {intel.ticker}</span> : null}
            <DS.Badge tone={OWNERSHIP_TONES[intel.ownership] || 'neutral'}>{intel.ownership}</DS.Badge>
          </div>
          <p className="e8-intel-desc">{intel.description}</p>
          <div className="e8-intel-meta">
            <a className="e8-link" href={'https://' + intel.website} target="_blank" rel="noreferrer" onClick={(e) => e.stopPropagation()}><span className="material-symbols-outlined" style={{ fontSize: 13 }}>language</span>{intel.website}</a>
            <span><span className="material-symbols-outlined" style={{ fontSize: 13 }}>location_on</span>{intel.hq}</span>
            <span><span className="material-symbols-outlined" style={{ fontSize: 13 }}>calendar_today</span>Founded {intel.founded}</span>
            <span><span className="material-symbols-outlined" style={{ fontSize: 13 }}>person</span>{intel.ceo}, CEO</span>
          </div>
        </div>
        <div className="e8-intel-sync">
          <span className="e8-srcchip"><span className="material-symbols-outlined" style={{ fontSize: 12 }}>sync</span>Synced {intel.synced}</span>
          <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap', justifyContent: 'flex-end', marginTop: 6, maxWidth: 200 }}>
            {intel.sources.map((s) => <span key={s} className="e8-srcpill">{s}</span>)}
          </div>
          <div style={{ display: 'inline-flex', alignItems: 'center', gap: 6, justifyContent: 'flex-end', marginTop: 6 }} title={isPublic ? 'Financials from SEC filings - verified' : 'Private-company figures are AI-estimated from ZoomInfo and news - treat as directional'}>
            <DS.ProvenanceBadge kind="advised" />
            <span style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)' }}>{isPublic ? 'SEC-verified · high' : 'AI-estimated · medium'} confidence</span>
          </div>
        </div>
      </div>

      {/* Stat tiles */}
      <div className="e8-intel-stats">
        <IntelTile label="Revenue" value={intel.fin.revenue} sub={intel.fin.revenueNote} />
        <IntelTile label="Employees" value={intel.employees} sub={(intel.employeeTrend >= 0 ? '▲ ' : '▼ ') + Math.abs(intel.employeeTrend) + '% YoY'} />
        <IntelTile label={valTile.label} value={valTile.value} sub={valTile.sub} />
        <IntelTile label="Our spend here" value={intel.wallet.ourSpend} sub={'Vendor #' + intel.wallet.vendorRank + ' of ' + intel.wallet.vendors} accent />
      </div>

      {/* Two-column body */}
      <div className="e8-intel-grid">
        {/* LEFT */}
        <div style={{ display: 'grid', gap: 16, minWidth: 0 }}>
          {/* Financial pulse */}
          <div className="e8-card e8-intel-card">
            <div className="e8-intel-cardhead">
              <span className="e8-sectionlabel">Financial pulse</span>
              <SourceChip>{intel.ownership === 'Nonprofit' ? 'IRS Form 990' : isPublic ? 'SEC EDGAR' : 'ZoomInfo est.'}</SourceChip>
            </div>
            <div style={{ display: 'flex', gap: 14, flexWrap: 'wrap', marginBottom: 6 }}>
              <div><div className="e8-mini-k">Revenue ({intel.fin.fyEnd} FY)</div><div className="e8-mini-v tnum">{intel.fin.revenue} <span style={{ fontSize: 'var(--ui-text-xs)', color: intel.fin.yoy >= 0 ? 'var(--ui-success-text)' : 'var(--ui-danger-text)' }}>{intel.fin.yoy >= 0 ? '▲' : '▼'} {Math.abs(intel.fin.yoy)}%</span></div></div>
              {intel.fin.netIncome && intel.fin.netIncome !== '-' ? <div><div className="e8-mini-k">Net income</div><div className="e8-mini-v tnum">{intel.fin.netIncome}</div></div> : null}
              {intel.fin.marketCap ? <div><div className="e8-mini-k">Market cap</div><div className="e8-mini-v tnum">{intel.fin.marketCap}</div></div> : null}
            </div>
            {E8C ? <E8C.AreaTrend series={intel.fin.revSeries} labels={intel.fin.revLabels} suffix={intel.fin.revUnit === '$B' ? 'B' : 'M'} height={132} /> : null}
            <div style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)', marginTop: 4 }}>Revenue by fiscal year ({intel.fin.revUnit}). {intel.fin.revenueNote}.</div>
          </div>

          {/* SEC filings + AI read */}
          <div className="e8-card e8-intel-card">
            <div className="e8-intel-cardhead">
              <span className="e8-sectionlabel">{intel.ownership === 'Nonprofit' ? 'Public filings (Form 990)' : isPublic ? 'SEC filings' : 'Filings'}</span>
              {isPublic ? <SourceChip>SEC EDGAR · CIK {intel.cik}</SourceChip> : intel.ownership === 'Nonprofit' ? <SourceChip>IRS · EIN {intel.ein}</SourceChip> : null}
            </div>
            {intel.filings.length ? (
              <div className="e8-filings">
                {intel.filings.map((f, i) => (
                  <button type="button" key={i} className="e8-filing" onClick={() => showToast('Opening ' + f.type + ' (' + f.date + ') - would deep-link to ' + (isPublic ? 'SEC EDGAR' : 'the source filing'))}>
                    <DS.Badge tone={FILING_TONES[f.type] || 'neutral'}>{f.type}</DS.Badge>
                    <div style={{ minWidth: 0, flex: 1 }}>
                      <div style={{ fontSize: 'var(--ui-text-sm)', fontWeight: 500 }}>{f.title}</div>
                      <div style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-secondary)', lineHeight: 1.5, marginTop: 2 }}>{f.summary}</div>
                    </div>
                    <span className="e8-filing-date tnum">{f.date}</span>
                  </button>
                ))}
              </div>
            ) : (
              <div className="e8-intel-note">{intel.filingNote}</div>
            )}
            {/* AI read */}
            <div className="e8-airead">
              <div className="e8-intel-cardhead" style={{ marginBottom: 8 }}>
                <span className="e8-sectionlabel">What this means for us</span>
                <DS.ProvenanceBadge kind="advised" />
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 7 }}>
                {intel.filingSignals.map((s, i) => (
                  <div key={i} style={{ display: 'flex', gap: 8, alignItems: 'flex-start' }}>
                    <span className="e8-signal-dot" style={{ background: SIGNAL_DOT[s.tone] || SIGNAL_DOT.neutral }}></span>
                    <span style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text)', lineHeight: 1.5 }}>{s.text}</span>
                  </div>
                ))}
              </div>
            </div>
          </div>

          {/* Tech stack */}
          <div className="e8-card e8-intel-card">
            <div className="e8-intel-cardhead">
              <span className="e8-sectionlabel">Detected tech stack</span>
              <SourceChip>ZoomInfo + BuiltWith</SourceChip>
            </div>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 8 }}>
              {intel.tech.map((t) => <span key={t} className="e8-techchip">{t}</span>)}
            </div>
            <div style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-secondary)' }}>
              <span className="material-symbols-outlined" style={{ fontSize: 13, color: 'var(--ui-success-text)', verticalAlign: '-2px' }}>check_circle</span> We actively staff <b>{intel.techStaffed} of {intel.tech.length}</b> detected technologies - strong overlap with our bench.
            </div>
          </div>
        </div>

        {/* RIGHT */}
        <div style={{ display: 'grid', gap: 16, minWidth: 0, alignContent: 'start' }}>
          {/* Buying intent */}
          <div className="e8-card e8-intel-card">
            <div className="e8-intel-cardhead">
              <span className="e8-sectionlabel">Buying intent</span>
              <SourceChip>ZoomInfo Intent</SourceChip>
            </div>
            <div style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)', margin: '-2px 0 10px' }}>Topics this company is actively researching (last 90 days).</div>
            {E8C ? <E8C.BarRow rows={intel.intent} max={100} color="var(--ui-accent)" /> : null}
          </div>

          {/* Our footprint */}
          <div className="e8-card e8-intel-card">
            <div className="e8-intel-cardhead"><span className="e8-sectionlabel">Our footprint here</span></div>
            <div className="e8-kv"><span className="e8-kv-k">Annual spend</span><span className="e8-kv-v tnum">{intel.wallet.ourSpend}</span></div>
            <div className="e8-kv"><span className="e8-kv-k">Share of spend</span><span className="e8-kv-v">{intel.wallet.shareLabel}</span></div>
            <div className="e8-kv"><span className="e8-kv-k">Vendor rank</span><span className="e8-kv-v tnum">#{intel.wallet.vendorRank} of {intel.wallet.vendors}</span></div>
            <div className="e8-kv"><span className="e8-kv-k">Trend</span><span className="e8-kv-v">{intel.wallet.trend === 'up' ? '▲ Growing' : intel.wallet.trend === 'down' ? '▼ Slipping' : '- Flat'}</span></div>
          </div>

          {/* Recent signals / news */}
          <div className="e8-card e8-intel-card">
            <div className="e8-intel-cardhead">
              <span className="e8-sectionlabel">Recent signals</span>
              <SourceChip>News + ZoomInfo Scoops</SourceChip>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              {intel.news.map((n, i) => (
                <div key={i} className="e8-news-row">
                  <span className="e8-signal-dot" style={{ background: SIGNAL_DOT[n.tone] || SIGNAL_DOT.neutral, marginTop: 5 }}></span>
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text)', lineHeight: 1.45 }}>{n.title}</div>
                    <div style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)', marginTop: 2 }}><span className="e8-news-tag">{n.tag}</span> · {n.when}</div>
                  </div>
                </div>
              ))}
            </div>
          </div>

          {/* Discovered contacts */}
          <DiscoveredContacts intel={intel} org={org} showToast={showToast} />
        </div>
      </div>
    </div>
  );
}

/* ---------- Hiring trend: what a person is actively hiring for ---------- */
const TREND_ICON = { up: 'trending_up', flat: 'trending_flat', down: 'trending_down' };
const TREND_COLOR = { up: 'var(--ui-success)', flat: 'var(--ui-text-tertiary)', down: 'var(--ui-danger)' };

function HiringChip({ hiring }) {
  if (!hiring) return null;
  if (!hiring.count) return <span className="e8-hire-chip e8-hire-zero" title={hiring.note || 'Does not hire directly'}>Gatekeeper</span>;
  const tip = (hiring.roles && hiring.roles.length ? 'Hiring: ' + hiring.roles.join(', ') : '') + (hiring.note ? ' - ' + hiring.note : '');
  return (
    <span className="e8-hire-chip" title={tip}>
      <span className="material-symbols-outlined" style={{ fontSize: 13, color: TREND_COLOR[hiring.trend] || TREND_COLOR.flat }}>{TREND_ICON[hiring.trend] || 'trending_flat'}</span>
      Hiring {hiring.count}{hiring.delta && hiring.trend === 'up' ? ' · ' + hiring.delta : ''}
    </span>
  );
}

/* Full hiring-trend panel for a person record. */
function HiringTrendPanel({ hiring }) {
  const DS = window.Stand8DesignSystem_b5c975;
  if (!hiring) return null;
  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
        <span className="e8-sectionlabel">Trending hiring</span>
        <DS.ProvenanceBadge kind="advised" />
      </div>
      <div className="e8-card e8-intel-card" style={{ padding: '13px 15px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: hiring.roles && hiring.roles.length ? 11 : 0, flexWrap: 'wrap' }}>
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 'var(--ui-text-lg)', fontWeight: 600 }}>
            <span className="material-symbols-outlined" style={{ fontSize: 19, color: TREND_COLOR[hiring.trend] || TREND_COLOR.flat }}>{TREND_ICON[hiring.trend] || 'trending_flat'}</span>
            {hiring.count ? hiring.count + ' open req' + (hiring.count === 1 ? '' : 's') : 'Not hiring directly'}
          </span>
          {hiring.delta ? <span className="e8-hire-delta">{hiring.delta}</span> : null}
          {hiring.note ? <span style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-tertiary)' }}>· {hiring.note}</span> : null}
        </div>
        {hiring.roles && hiring.roles.length ? (
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
            {hiring.roles.map((r) => <span key={r} className="e8-techchip">{r}</span>)}
          </div>
        ) : null}
      </div>
    </div>
  );
}

/* ============================== ORG CHART ============================== */
function OrgNode({ node, childrenOf, showToast }) {
  const DS = window.Stand8DesignSystem_b5c975;
  const kids = childrenOf(node.id);
  const click = () => node.crm && node.contactId ? navigate('contact/' + node.contactId) : showToast(node.name + ' added to CRM - enriched from ZoomInfo');
  return (
    <li className="e8-org-li">
      <div className={'e8-org-card ' + (node.crm ? 'is-crm' : 'is-gap')} onClick={click} onKeyDown={(ev) => { if (ev.key === 'Enter' || ev.key === ' ') { ev.preventDefault(); click(); } }} role="button" tabIndex={0}>
        <div className="e8-org-card-top">
          <DS.Avatar name={node.name} size="sm" />
          <div style={{ minWidth: 0, flex: 1, textAlign: 'left' }}>
            <div className="e8-org-name">{node.name}</div>
            <div className="e8-org-role">{node.role}</div>
          </div>
        </div>
        <div className="e8-org-card-foot">
          {node.crm
            ? <span className="e8-org-tag e8-org-tag-crm"><span className="material-symbols-outlined" style={{ fontSize: 12 }}>check_circle</span>{node.strength || 'In CRM'}</span>
            : <span className="e8-org-tag e8-org-tag-gap"><span className="material-symbols-outlined" style={{ fontSize: 12 }}>person_add</span>Add</span>}
          <HiringChip hiring={node.hiring} />
        </div>
      </div>
      {kids.length ? <ul className="e8-org-children">{kids.map((k) => <OrgNode key={k.id} node={k} childrenOf={childrenOf} showToast={showToast} />)}</ul> : null}
    </li>
  );
}

function ClientOrgTab({ c, org, showToast }) {
  const DS = window.Stand8DesignSystem_b5c975;
  if (!org || !org.nodes || !org.nodes.length) {
    return <div style={{ maxWidth: 460, margin: '24px auto' }}><DS.EmptyState icon="account_tree" title="No org chart yet" body="Connect ZoomInfo to map this account’s reporting lines." /></div>;
  }
  const childrenOf = (pid) => org.nodes.filter((n) => n.reportsTo === pid);
  const roots = childrenOf(null);
  const known = org.nodes.filter((n) => n.crm).length;
  const total = org.nodes.length;
  const hiringNodes = org.nodes.filter((n) => n.hiring && n.hiring.count).length;

  return (
    <div className="e8-intel">
      <div className="e8-org-head">
        <div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <span className="e8-sectionlabel">Org chart</span>
            <DS.ProvenanceBadge kind="advised" />
          </div>
          <div style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)', marginTop: 3 }}>{org.asOf}</div>
        </div>
        <div className="e8-org-legend">
          <span className="e8-org-cover">You know <b>{known}</b> of <b>{total}</b> · <b>{hiringNodes}</b> actively hiring</span>
          <span className="e8-org-key"><i className="e8-org-key-crm"></i>In your CRM</span>
          <span className="e8-org-key"><i className="e8-org-key-gap"></i>Gap - add</span>
        </div>
      </div>
      <div className="e8-org-scroll">
        <ul className="e8-org-tree">
          {roots.map((r) => <OrgNode key={r.id} node={r} childrenOf={childrenOf} showToast={showToast} />)}
        </ul>
      </div>
    </div>
  );
}

/* ============================== CLIENT RECORD ============================== */
const PO_TONES = { healthy: 'success', depleting: 'warning', expiring: 'warning', expired: 'danger' };
const CARE_TONES = { current: 'success', due: 'warning', overdue: 'danger' };

function ClientDetailScreen({ id, sub }) {
  const D = window.E8DATA;
  const { showToast, density } = React.useContext(E8Ctx);
  const cap = React.useContext(CaptureCtx);
  const [creatingJob, setCreatingJob] = React.useState(false);
  const cFound = D.clients.find((x) => x.id === id);
  const c = cFound || D.clients[0];
  const intel = D.clientIntel && D.clientIntel[c.id];
  const org = D.clientOrg && D.clientOrg[c.id];
  const tab = sub || 'overview';
  const setTab = (t) => navigate('client/' + c.id + '/' + t);
  const swt = useSwipeTabs(['overview', 'company', 'org', 'jobs', 'contacts', 'engagements', 'activity'], tab, setTab);

  const jobs = D.jobs.filter((j) => j.client === c.name);
  const contacts = D.contacts.filter((x) => x.client === c.name);
  const engagements = D.engagements.filter((e) => e.client === c.name);
  const programs = (D.managedEngagements || []).filter((mm) => mm.client === c.name);
  const soloEngagements = engagements.filter((e) => !e.projectId);
  const subs = D.submissions.filter((s) => s.client === c.name);
  const convo = D.conversations.find((v) => contacts.some((ct) => ct.name === v.name));

  /* "Needs attention" - derived live from this client's pipeline, not written copy. */
  const attention = [
    ...jobs.filter((j) => j.health.tone === 'warning' || j.health.tone === 'danger')
      .map((j) => ({ label: j.title + ' - ' + j.health.note, to: 'job/' + j.id + '/overview' })),
    ...subs.filter((s) => s.open && s.resp.tone === 'warning')
      .map((s) => ({ label: 'Feedback overdue on ' + s.cand + ' - ' + s.resp.label.toLowerCase(), to: 'submissions' })),
    ...engagements.filter((e) => e.renewal !== 'Not due')
      .map((e) => ({ label: e.consultant + ' renewal - ' + e.renewal.toLowerCase() + ', PO ' + e.poBurn + '% burned', to: 'renewals' })),
    ...engagements.filter((e) => e.care === 'overdue')
      .map((e) => ({ label: e.consultant + ' care touch overdue - last contact ' + e.lastTouch, to: 'engagements' })),
  ].slice(0, 4);

  const brief = c.name + ' has ' + jobs.length + ' open job' + (jobs.length === 1 ? '' : 's') + ', '
    + c.consultants + ' consultant' + (c.consultants === 1 ? '' : 's') + ' on billing and '
    + (c.renewals ? c.renewals + ' renewal' + (c.renewals === 1 ? '' : 's') + ' inside 90 days. ' : 'no renewals due. ')
    + c.health.note + '.';

  if (id && !cFound) {
    return (
      <React.Fragment>
        <Topbar crumbs={[{ label: 'Clients', to: 'clients' }, { label: 'Not found' }]} />
        <div className="e8-content"><div className="e8-page">
          <div style={{ maxWidth: 460, margin: '24px auto', textAlign: 'center' }}>
            <DSx.EmptyState icon="domain" title="Client not found" body="This account does not exist, or the link is out of date." />
            <div style={{ marginTop: 12 }}><DSx.Button variant="secondary" size="sm" icon="arrow_back" onClick={() => navigate('clients')}>Back to clients</DSx.Button></div>
          </div>
        </div></div>
      </React.Fragment>
    );
  }

  return (
    <React.Fragment>
      <Topbar
        crumbs={[{ label: 'Clients', to: 'clients' }, { label: c.name }]}
        actions={
          <React.Fragment>
            <DSx.Button variant="ghost" size="sm" icon="mic" onClick={() => cap.open({ target: 'note', entityLabel: c.name })}>Add note</DSx.Button>
            <DSx.Button variant="ghost" size="sm" icon="call" onClick={() => showToast('Touch logged for ' + c.name)}>Log touch</DSx.Button>
            <DSx.Button variant="secondary" size="sm" icon="forum" onClick={() => showToast('QBR agenda drafted from ' + c.name + '’s last quarter - review in Approvals', 'Open approvals', () => navigate('approvals'))}>Draft QBR agenda</DSx.Button>
            <DSx.Button variant="primary" size="sm" icon="add" onClick={() => setCreatingJob(true)}>New job</DSx.Button>
          </React.Fragment>
        }
      />
      {creatingJob ? (
        <CrmCreateDialog
          title={'New job · ' + c.name}
          createLabel="Create job"
          fields={[
            { key: 'title', label: 'Title', placeholder: 'e.g. Senior Platform Engineer', required: true },
            { key: 'client', label: 'Client', type: 'select', options: [{ value: c.name, label: c.name }] },
            { key: 'billRate', label: 'Bill rate', placeholder: 'e.g. $150/hr' },
          ]}
          extra={() => (
            /* R98: hand the job off to the intake agent instead - opens the capture sheet
               pre-filled with this client (still editable there). */
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
              <DSx.Button variant="ghost" size="sm" icon="graphic_eq" onClick={() => { setCreatingJob(false); cap.open({ target: 'req', prefill: { client: c.name } }); }}>Capture with agent instead</DSx.Button>
              <span style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)' }}>Talk or paste the brief - the agent fills the fields.</span>
            </div>
          )}
          onClose={() => setCreatingJob(false)}
          onCreate={(v) => {
            setCreatingJob(false);
            /* R78: creates are real - the record persists via the E8Store overlay. */
            const title = v.title.trim();
            let jn = 44900 + ((window.E8DATA.jobs || []).length);
            while ((window.E8DATA.jobs || []).some((r) => r.id === 'JO-' + jn)) jn++;
            const id = 'JO-' + jn;
            window.E8Store.add('jobs', {
              id, title, client: c.name, location: 'Memphis, TN', type: 'Contract', rate: v.billRate || 'TBD',
              day: 0, days: 30, openings: 1, filled: 0, priority: 2, owner: (window.E8DATA.user || {}).name || 'You',
              pipeline: Object.fromEntries((window.E8DATA.pipelineStages || []).map((s) => [s.key, 0])),
              health: { label: 'New', tone: 'info', note: 'Just opened - sourcing not started' },
              next: { label: 'Kick off sourcing', toast: 'Matching queued for ' + title },
            });
            if (window.E8Audit) window.E8Audit.log({ agent: 'You', prov: 'human', action: 'Created job order', target: title + ' · ' + c.name, route: 'jobs' });
            showToast('Created "' + title + '"', 'Open', () => navigate('jobs'));
          }}
        />
      ) : null}
      <div className="e8-content">
        <div className="e8-page">
          <RecordHeader
            mark={<ClientMark name={c.name} />}
            title={c.name}
            badges={<React.Fragment>
              <DSx.Badge tone={TIER_TONES[c.tier] || 'neutral'}>{c.tier}</DSx.Badge>
              <span title={c.health.note}><DSx.Badge tone={c.health.tone} dot={c.health.tone !== 'neutral'}>{c.health.label}</DSx.Badge></span>
            </React.Fragment>}
            meta={<React.Fragment>{c.industry} · client since {c.since} · CSM {c.csm} · last touch {c.lastTouch}</React.Fragment>}
          />

          <div className="e8-record-2col">
            <div style={{ flex: 1, minWidth: 0 }}>
              <DSx.Tabs
                items={[
                  { id: 'overview', label: 'Overview' },
                  { id: 'company', label: 'Company', icon: 'domain' },
                  { id: 'org', label: 'Org chart', icon: 'account_tree' },
                  { id: 'jobs', label: 'Jobs', count: jobs.length || undefined },
                  { id: 'contacts', label: 'Contacts', count: contacts.length || undefined },
                  { id: 'engagements', label: 'Engagements', count: (programs.length + soloEngagements.length) || undefined },
                  { id: 'activity', label: 'Activity' },
                ]}
                active={tab}
                onChange={setTab}
              />
              <div style={{ paddingTop: 16, minWidth: 0, ...(swt.style || {}) }} {...swt.bind}>
                {tab === 'overview' ? (
                  <div style={{ display: 'grid', gap: 20, maxWidth: 760 }}>
                    <div className="e8-card e8-aibrief">
                      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
                        <span className="e8-sectionlabel">Relationship brief</span>
                        <DSx.ProvenanceBadge kind="drafted" />
                        <span style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)' }}>built from live pipeline + activity</span>
                      </div>
                      <p style={{ margin: 0, fontSize: 'var(--ui-text-base)', lineHeight: 1.55, color: 'var(--ui-text)', textWrap: 'pretty' }}>{brief}</p>
                    </div>

                    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10 }}>
                      {[['Open jobs', String(jobs.length)], ['On billing', String(c.consultants)], ['Renewals 90d', String(c.renewals || '-')], ['Billing', c.ar.label]].map(([k, v]) => (
                        <div key={k} style={{ border: '1px solid var(--ui-border)', borderRadius: 'var(--ui-radius-lg)', padding: '10px 14px' }}>
                          <div style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-tertiary)' }}>{k}</div>
                          <div className="tnum" style={{ fontSize: 'var(--ui-text-lg)', fontWeight: 500, marginTop: 2 }}>{v}</div>
                        </div>
                      ))}
                    </div>

                    <EnrichDossierCard clientId={c.id} />

                    {intel ? (
                      <button type="button" className="e8-intel-strip" onClick={() => setTab('company')}>
                        <div className="e8-intel-strip-head">
                          <span className="material-symbols-outlined" style={{ fontSize: 16, color: 'var(--ui-accent)' }}>insights</span>
                          <span className="e8-sectionlabel">Company intelligence</span>
                          {intel.ticker ? <span className="e8-ticker">{intel.exchange}: {intel.ticker}</span> : <DSx.Badge tone={OWNERSHIP_TONES[intel.ownership] || 'neutral'}>{intel.ownership}</DSx.Badge>}
                          <span style={{ marginLeft: 'auto', fontSize: 'var(--ui-text-sm)', color: 'var(--ui-accent)', fontWeight: 500 }}>Full profile →</span>
                        </div>
                        <div className="e8-intel-strip-facts">
                          <span><b className="tnum">{intel.fin.revenue}</b> revenue</span>
                          <span><b className="tnum">{intel.employees}</b> employees</span>
                          <span><b className="tnum">{intel.tech.length}</b> tech detected · we staff {intel.techStaffed}</span>
                          <span>Top intent: <b>{intel.intent[0][0]}</b></span>
                        </div>
                      </button>
                    ) : null}

                    <div>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
                        <span className="e8-sectionlabel">Needs attention</span>
                        <DSx.ProvenanceBadge kind="advised" />
                      </div>
                      {attention.length ? (
                        <div style={{ display: 'flex', flexDirection: 'column', gap: 6, maxWidth: 560 }}>
                          {attention.map((a, i) => (
                            <button key={i} type="button" className="e8-nextaction" onClick={() => navigate(a.to)}>
                              <span className="material-symbols-outlined" style={{ fontSize: 14 }}>arrow_forward</span>
                              {a.label}
                            </button>
                          ))}
                        </div>
                      ) : (
                        <div style={{ fontSize: 'var(--ui-text-base)', color: 'var(--ui-text-secondary)' }}>Nothing flagged - pipeline and billing look healthy.</div>
                      )}
                    </div>
                  </div>
                ) : null}
                {tab === 'company' ? (
                  <ClientCompanyTab c={c} intel={intel} org={org} showToast={showToast} />
                ) : null}
                {tab === 'org' ? (
                  <ClientOrgTab c={c} org={org} showToast={showToast} />
                ) : null}
                {tab === 'jobs' ? (
                  jobs.length
                    ? <OpenJobsTab density={density} rows={jobs} group="none" />
                    : <div style={{ maxWidth: 460, margin: '24px auto' }}><DSx.EmptyState icon="work" title="No open jobs" body="New reqs start in Intake and open here once the sponsor approves." /></div>
                ) : null}
                {tab === 'contacts' ? (
                  <div style={{ display: 'grid', gap: 18, gridTemplateColumns: 'minmax(0, 1fr)' }}>
                    <div style={{ minWidth: 0 }}>
                      <div className="e8-sectionlabel" style={{ marginBottom: 8 }}>In your CRM</div>
                      <ConfigurableTable listKey="client-contacts"
                        primary={false}
                        density={density}
                        onRowClick={(r) => navigate('contact/' + r.id)}
                        registry={[
                          { key: 'name', label: 'Contact', render: (r) => <NameCell name={r.name} sub={r.role} /> },
                          { key: 'owns', label: 'Owns', render: (r) => <span style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-secondary)' }}>{r.owns}</span> },
                          { key: 'strength', label: 'Relationship', render: (r) => <span title={r.reply}><DSx.Badge tone={r.strength.tone} dot={r.strength.tone !== 'neutral'}>{r.strength.label}</DSx.Badge></span> },
                          { key: 'lastTouch', label: 'Last touch', secondary: true, render: (r) => <span className="tnum">{r.lastTouch}</span> },
                          { key: 'next', label: 'Next step', render: (r) => <span style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-secondary)' }}>{r.next}</span> },
                        ]}
                        rows={contacts}
                        rowActions={(r) => <DSx.Button variant="ghost" size="sm" icon="mail" onClick={() => showToast('Email drafted to ' + r.name + ' - review in Approvals')}>Draft email</DSx.Button>}
                      />
                    </div>
                    {intel ? <DiscoveredContacts intel={intel} org={org} showToast={showToast} /> : null}
                  </div>
                ) : null}
                {tab === 'engagements' ? (
                  (programs.length || soloEngagements.length) ? (
                    <React.Fragment>
                      {programs.length ? (
                        <div style={{ marginBottom: 18 }}>
                          <div className="e8-sectionlabel" style={{ marginBottom: 10 }}>Managed-service programs</div>
                          <div className="e8-prog-grid">
                            {programs.map((mm) => (
                              <div key={mm.id} className="e8-card e8-prog-card" role="button" tabIndex={0} onClick={() => navigate('engagement/' + mm.id)} onKeyDown={(ev) => { if (ev.key === 'Enter' || ev.key === ' ') { ev.preventDefault(); navigate('engagement/' + mm.id); } }}>
                                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10 }}>
                                  <span style={{ fontWeight: 600, fontSize: 'var(--ui-text-base)', flex: 1, minWidth: 0 }}>{mm.name}</span>
                                  <DSx.Badge tone={mm.health.tone} dot>{mm.health.tone === 'success' ? 'Healthy' : 'At risk'}</DSx.Badge>
                                </div>
                                <div className="e8-prog-stats">
                                  <div><b>{mm.team.length}</b><span>team</span></div>
                                  <div><b>{mm.contract.tcv}</b><span>TCV</span></div>
                                  <div><b>{mm.poBurn.pct}%</b><span>PO burn</span></div>
                                  <div><b>{mm.csat ? mm.csat.score : '-'}</b><span>CSAT</span></div>
                                </div>
                              </div>
                            ))}
                          </div>
                        </div>
                      ) : null}
                      {soloEngagements.length ? (
                        <React.Fragment>
                          {programs.length ? <div className="e8-sectionlabel" style={{ marginBottom: 10 }}>Staff-aug placements</div> : null}
                          <ConfigurableTable listKey="client-engagements"
                            primary={false}
                            density={density}
                            registry={[
                              { key: 'consultant', label: 'Consultant', render: (e) => <NameCell name={e.consultant} sub={e.role} /> },
                              { key: 'po', label: 'PO health', width: 200, render: (e) => (
                                <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8 }}>
                                  <DSx.Badge tone={PO_TONES[e.po]} dot>{e.po[0].toUpperCase() + e.po.slice(1)}</DSx.Badge>
                                  <span className="tnum" style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)' }}>{e.poBurn}%</span>
                                </span>
                              ) },
                              { key: 'ends', label: 'Ends', num: true },
                              { key: 'renewal', label: 'Renewal', render: (e) => (
                                e.renewal === 'Not due'
                                  ? <span style={{ color: 'var(--ui-text-tertiary)', fontSize: 'var(--ui-text-base)' }}>Not due</span>
                                  : <DSx.Badge tone={e.renewal === 'Escalated' ? 'danger' : 'accent'}>{e.renewal}</DSx.Badge>
                              ) },
                              { key: 'care', label: 'Care', render: (e) => <DSx.Badge tone={CARE_TONES[e.care]} dot>{e.care[0].toUpperCase() + e.care.slice(1)}</DSx.Badge> },
                            ]}
                            rows={soloEngagements}
                          />
                        </React.Fragment>
                      ) : null}
                    </React.Fragment>
                  ) : <div style={{ maxWidth: 460, margin: '24px auto' }}><DSx.EmptyState icon="badge" title="No consultants on billing" body="Placements convert to engagements here once a job order fills." /></div>
                ) : null}
                {tab === 'activity' ? (
                  <Timeline events={[
                    { id: 'ca1', when: c.lastTouch.replace(' ago', '') + ' ago', actor: c.csm, ai: false, prov: 'human', title: 'Client touch logged', body: 'Latest check-in with ' + (contacts[0] ? contacts[0].name : 'the client') + '.' },
                    { id: 'ca2', when: 'This week', actor: 'Matching', ai: true, prov: 'advised', title: 'Matching refreshed for ' + jobs.length + ' open job' + (jobs.length === 1 ? '' : 's'), body: 'Rankings updated against current requirements.' },
                    { id: 'ca3', when: 'Since ' + c.since, actor: 'ELEV8', ai: true, prov: 'qa', title: 'Relationship history synced', body: 'Placements, billing and contacts mirrored from Bullhorn.' },
                  ]} />
                ) : null}
              </div>
            </div>

            {/* Right rail - hidden on the full-width org chart */}
            {tab !== 'org' ? (
            <div className="e8-rail">
              {window.RecordTasksRail ? <window.RecordTasksRail refType="client" refId={c.id} /> : null}
              {intel ? (
                <div className="e8-rail-block">
                  <div className="e8-rail-title" style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                    <span>Company</span>
                    {intel.ticker ? <span className="e8-ticker">{intel.exchange}: {intel.ticker}</span> : <DSx.Badge tone={OWNERSHIP_TONES[intel.ownership] || 'neutral'}>{intel.ownership}</DSx.Badge>}
                  </div>
                  <div className="e8-kv"><span className="e8-kv-k">Revenue</span><span className="e8-kv-v tnum">{intel.fin.revenue}</span></div>
                  <div className="e8-kv"><span className="e8-kv-k">Employees</span><span className="e8-kv-v tnum">{intel.employees}</span></div>
                  <div className="e8-kv"><span className="e8-kv-k">HQ</span><span className="e8-kv-v">{intel.hq}</span></div>
                  <div className="e8-kv"><span className="e8-kv-k">Our spend</span><span className="e8-kv-v tnum">{intel.wallet.ourSpend}</span></div>
                  <a className="e8-link" style={{ fontSize: 'var(--ui-text-sm)', display: 'inline-block', marginTop: 4 }} tabIndex={0} onKeyDown={window.keyActivate} onClick={() => setTab('company')}>View full profile →</a>
                </div>
              ) : null}
              <div className="e8-rail-block">
                <div className="e8-rail-title">Health</div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
                  <DSx.Badge tone={c.health.tone} dot={c.health.tone !== 'neutral'}>{c.health.label}</DSx.Badge>
                </div>
                <div style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-secondary)', lineHeight: 1.5 }}>{c.health.note}</div>
              </div>
              <div className="e8-rail-block">
                <div className="e8-rail-title">Commercials</div>
                <div className="e8-kv"><span className="e8-kv-k">Billing</span><span className="e8-kv-v">{c.ar.label}</span></div>
                <div className="e8-kv"><span className="e8-kv-k">Terms</span><span className="e8-kv-v tnum">{c.terms}</span></div>
                <div className="e8-kv"><span className="e8-kv-k">MSA</span><span className="e8-kv-v">{c.msa}</span></div>
                <div className="e8-kv"><span className="e8-kv-k">Rate card</span><span className="e8-kv-v"><a className="e8-link" tabIndex={0} onKeyDown={window.keyActivate} onClick={() => navigate('rates')}>View</a></span></div>
              </div>
              <div className="e8-rail-block">
                <div className="e8-rail-title">Team</div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                  <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7 }}><ActorChip name={c.csm} /><span style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)' }}>CSM</span></span>
                  <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7 }}><ActorChip name="Sarah Kim" /><span style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)' }}>Delivery lead</span></span>
                </div>
              </div>
              {convo ? (
                <div className="e8-rail-block">
                  <div className="e8-rail-title">Latest thread</div>
                  <div style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-secondary)', marginBottom: 7 }}>{convo.name} · {convo.lastWhen}</div>
                  <DSx.Button variant="secondary" size="sm" icon="forum" onClick={() => navigate('inbox/' + convo.id)}>Open in Inbox</DSx.Button>
                </div>
              ) : null}
            </div>
            ) : null}
          </div>
        </div>
      </div>
    </React.Fragment>
  );
}

/* ============================== CONTACT RECORD ============================== */
/* Parse the job/req id a contact owns out of their `owns` string ("JO-44219 · hiring manager"). */
function ownedId(owns) {
  const m = (owns || '').match(/\b(JO-\d+|REQ-\d+)\b/);
  return m ? m[1] : null;
}

function ContactDetailScreen({ id, sub }) {
  const D = window.E8DATA;
  const { showToast, density } = React.useContext(E8Ctx);
  const cap = React.useContext(CaptureCtx);
  const ctFound = D.contacts.find((x) => x.id === id);
  const ct = ctFound || D.contacts[0];
  const tab = sub || 'overview';
  const setTab = (t) => navigate('contact/' + ct.id + '/' + t);
  const swtc = useSwipeTabs(['overview', 'reqs', 'activity'], tab, setTab);
  const isMobile = useIsMobile();

  const client = D.clients.find((cl) => cl.name === ct.client);
  const convo = D.conversations.find((v) => v.name === ct.name);
  const ownId = ownedId(ct.owns);
  const clientJobs = D.jobs.filter((j) => j.client === ct.client);
  const clientReqs = D.intake.filter((r) => r.client === ct.client);
  const clientSubs = D.submissions.filter((s) => s.client === ct.client && s.open);

  /* Reachable-on channels: from the live thread if one exists, else from the contact fields. */
  const channels = convo ? convo.identities : [
    { ch: 'email', label: ct.email },
    { ch: 'sms', label: ct.phone + ' · RingCentral' },
    { ch: 'linkedin', label: ct.name.toLowerCase().replace(/[^a-z]/g, '-') },
  ];

  const brief = `${ct.name.split(' ')[0]} is the ${ct.role.toLowerCase()} at ${ct.client} and your point of contact on ${ct.owns}. Relationship is ${ct.strength.label.toLowerCase()} - ${ct.reply.toLowerCase()}. Last touch ${ct.lastTouch}.`;

  /* Needs attention - derived from their owned work + relationship signals. */
  const attention = [
    ct.strength.tone === 'warning' ? { label: ct.next, to: 'approvals' } : null,
    ...clientSubs.filter((s) => s.resp && s.resp.tone === 'warning').map((s) => ({ label: 'Feedback overdue on ' + s.cand + ' - ' + s.resp.label.toLowerCase(), to: 'submissions' })),
    ...clientReqs.filter((r) => r.tone === 'danger' || r.tone === 'warning').map((r) => ({ label: r.title + ' (' + r.id + ') - ' + r.waiting.toLowerCase(), to: 'jobs/intake' })),
  ].filter(Boolean).slice(0, 4);

  const Dot = window.ChannelDot;

  if (id && !ctFound) {
    return (
      <React.Fragment>
        <Topbar crumbs={[{ label: 'Contacts', to: 'contacts' }, { label: 'Not found' }]} />
        <div className="e8-content"><div className="e8-page">
          <div style={{ maxWidth: 460, margin: '24px auto', textAlign: 'center' }}>
            <DSx.EmptyState icon="person_off" title="Contact not found" body="This contact does not exist, or the link is out of date." />
            <div style={{ marginTop: 12 }}><DSx.Button variant="secondary" size="sm" icon="arrow_back" onClick={() => navigate('contacts')}>Back to contacts</DSx.Button></div>
          </div>
        </div></div>
      </React.Fragment>
    );
  }

  return (
    <React.Fragment>
      <Topbar
        crumbs={[{ label: 'Contacts', to: 'contacts' }, { label: ct.name }]}
        actions={
          <React.Fragment>
            <DSx.Button variant="ghost" size="sm" icon="mic" onClick={() => cap.open({ target: 'note', entityLabel: ct.name })}>Add note</DSx.Button>
            <WorkspacePinButton type="contact" id={ct.id} compact />
            {!isMobile ? <DSx.Button variant="ghost" size="sm" icon="call" onClick={() => showToast('Call logged for ' + ct.name)}>Log call</DSx.Button> : null}
            <DSx.MenuButton
              label="Actions"
              icon="bolt"
              size="sm"
              variant="secondary"
              items={[
                { icon: 'event', label: 'Schedule meeting', onClick: () => showToast('Meeting invite drafted to ' + ct.name) },
                { icon: 'campaign', label: 'Add to sequence', onClick: () => showToast(ct.name + ' enrolled in “Quiet sponsors”', 'Open', () => navigate('sequences')) },
                { icon: 'person', label: 'Open client', onClick: () => (client ? navigate('client/' + client.id) : showToast('Client record not found')) },
                { separator: true },
                { icon: 'archive', label: 'Archive contact', danger: true, onClick: () => showToast(ct.name + ' archived', 'Undo') },
              ]}
            />
            <DSx.Button variant="primary" size="sm" icon="mail" onClick={() => (convo ? navigate('inbox/' + convo.id) : showToast('Email drafted to ' + ct.name + ' - review in Approvals', 'Open approvals', () => navigate('approvals')))}>Message</DSx.Button>
          </React.Fragment>
        }
      />
      <div className="e8-content">
        <div className="e8-page">
          <RecordHeader
            mark={<DSx.Avatar name={ct.name} size="xl" />}
            title={ct.name}
            badges={<span title={ct.reply}><DSx.Badge tone={ct.strength.tone} dot={ct.strength.tone !== 'neutral'}>{ct.strength.label}</DSx.Badge></span>}
            meta={<React.Fragment>{ct.role} · <a className="e8-link" tabIndex={0} onKeyDown={window.keyActivate} onClick={() => (client ? navigate('client/' + client.id) : null)}>{ct.client}</a></React.Fragment>}
          />

          <div className="e8-record-2col">
            <div style={{ flex: 1, minWidth: 0 }}>
              <DSx.Tabs
                items={[
                  { id: 'overview', label: 'Overview' },
                  { id: 'reqs', label: 'Reqs & jobs', count: (clientJobs.length + clientReqs.length) || undefined },
                  { id: 'activity', label: 'Activity' },
                ]}
                active={tab}
                onChange={setTab}
              />
              <div style={{ paddingTop: 16, minWidth: 0, ...(swtc.style || {}) }} {...swtc.bind}>
                {tab === 'overview' ? (
                  <div style={{ display: 'grid', gap: 20, maxWidth: 760 }}>
                    <div className="e8-card e8-aibrief">
                      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
                        <span className="e8-sectionlabel">Relationship brief</span>
                        <DSx.ProvenanceBadge kind="drafted" />
                      </div>
                      <p style={{ margin: 0, fontSize: 'var(--ui-text-base)', lineHeight: 1.55, color: 'var(--ui-text)', textWrap: 'pretty' }}>{brief}</p>
                    </div>

                    <div>
                      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
                        <span className="e8-sectionlabel">Needs attention</span>
                        <DSx.ProvenanceBadge kind="advised" />
                      </div>
                      {attention.length ? (
                        <div style={{ display: 'flex', flexDirection: 'column', gap: 6, maxWidth: 560 }}>
                          {attention.map((a, i) => (
                            <button key={i} type="button" className="e8-nextaction" onClick={() => navigate(a.to)}>
                              <span className="material-symbols-outlined" style={{ fontSize: 14 }}>arrow_forward</span>
                              {a.label}
                            </button>
                          ))}
                        </div>
                      ) : (
                        <div style={{ fontSize: 'var(--ui-text-base)', color: 'var(--ui-text-secondary)' }}>Nothing flagged - this relationship is in good shape.</div>
                      )}
                    </div>

                    {ct.hiring ? <HiringTrendPanel hiring={ct.hiring} /> : null}

                    <div>
                      <div className="e8-sectionlabel" style={{ marginBottom: 8 }}>Reachable on</div>
                      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
                        {channels.map((c2, i) => (
                          <span key={i} style={{ display: 'inline-flex', alignItems: 'center', gap: 7, fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-secondary)', border: '1px solid var(--ui-border)', borderRadius: 'var(--ui-radius)', padding: '5px 10px' }}>
                            {Dot ? <Dot ch={c2.ch} size={14} /> : null} {c2.label}
                          </span>
                        ))}
                      </div>
                      <div style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-tertiary)', marginTop: 8 }}>{ct.reply}</div>
                    </div>

                    <EnrichContactPanel contactId={ct.id} />
                  </div>
                ) : null}

                {tab === 'reqs' ? (
                  <div style={{ display: 'grid', gap: 18 }}>
                    {clientJobs.length ? (
                      <div>
                        <div className="e8-sectionlabel" style={{ marginBottom: 8 }}>Open jobs at {ct.client}</div>
                        <ConfigurableTable listKey="contact-open-jobs" primary={false}
                          density={density}
                          onRowClick={(r) => navigate('job/' + r.id + '/overview')}
                          registry={[
                            { key: 'title', label: 'Job', render: (r) => (
                              <span title={ownId === r.id ? 'Owned by ' + ct.name : ''}>
                                <span style={{ fontWeight: 500 }}>{r.title}</span>
                                {ownId === r.id ? <span style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-daybreak-text)' }}> · their req</span> : null}
                                <span style={{ display: 'block', fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-tertiary)' }}>{r.id}</span>
                              </span>
                            ) },
                            { key: 'health', label: 'Health', render: (r) => <span title={r.health.note}><DSx.Badge tone={r.health.tone} dot={r.health.tone !== 'neutral'}>{r.health.label}</DSx.Badge></span> },
                            { key: 'rate', label: 'Bill rate', num: true },
                          ]}
                          rows={clientJobs}
                        />
                      </div>
                    ) : null}
                    {clientReqs.length ? (
                      <div>
                        <div className="e8-sectionlabel" style={{ marginBottom: 8 }}>Intake reqs at {ct.client}</div>
                        <ConfigurableTable listKey="contact-intake-reqs" primary={false}
                          density={density}
                          onRowClick={() => navigate('jobs/intake')}
                          registry={[
                            { key: 'title', label: 'Req', render: (r) => (
                              <span>
                                <span style={{ fontWeight: 500 }}>{r.title}</span>
                                {ownId === r.id ? <span style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-daybreak-text)' }}> · their req</span> : null}
                                <span style={{ display: 'block', fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-tertiary)' }}>{r.id}</span>
                              </span>
                            ) },
                            { key: 'waiting', label: 'Status', render: (r) => <DSx.Badge tone={r.tone} dot={r.tone !== 'neutral'}>{r.waiting}</DSx.Badge> },
                            { key: 'rate', label: 'Est. rate', num: true },
                          ]}
                          rows={clientReqs}
                        />
                      </div>
                    ) : null}
                    {!clientJobs.length && !clientReqs.length ? (
                      <div style={{ maxWidth: 460, margin: '24px auto' }}>
                        <DSx.EmptyState icon="work_off" title="No open work at this client" body="Reqs this contact opens or sponsors will appear here." />
                      </div>
                    ) : null}
                  </div>
                ) : null}

                {tab === 'activity' ? (
                  <Timeline events={[
                    convo ? { id: 'cta1', when: convo.lastWhen + ' ago', actor: 'Sarah Kim', ai: false, prov: 'human', title: 'Latest message via the inbox', body: convo.thread[convo.thread.length - 1].text, link: 'Open thread', linkTo: 'inbox/' + convo.id } : null,
                    ct.strength.tone === 'warning' ? { id: 'cta2', when: 'Today', actor: 'Outreach & nudges', ai: true, prov: 'drafted', title: 'Suggested next step', body: ct.next } : null,
                    { id: 'cta3', when: ct.lastTouch, actor: 'Sarah Kim', ai: false, prov: 'human', title: 'Last logged touch', body: ct.reply },
                  ].filter(Boolean)} />
                ) : null}
              </div>
            </div>

            {/* Right rail */}
            <div className="e8-rail">
              <div className="e8-rail-block">
                <div className="e8-rail-title">Contact</div>
                <div className="e8-kv"><span className="e8-kv-k">Email</span><span className="e8-kv-v"><a className="e8-link" href={'mailto:' + ct.email}>{ct.email}</a></span></div>
                <div className="e8-kv"><span className="e8-kv-k">Phone</span><span className="e8-kv-v tnum"><a className="e8-link" href={'tel:' + (ct.phone || '').replace(/[^0-9+]/g, '')}>{ct.phone}</a></span></div>
                <div className="e8-kv"><span className="e8-kv-k">Replies</span><span className="e8-kv-v">{ct.reply}</span></div>
              </div>
              {ct.enrich ? (
                <div className="e8-rail-block">
                  <div className="e8-rail-title" style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                    <span>Enrichment</span>
                    <span className="e8-srcchip"><span className="material-symbols-outlined" style={{ fontSize: 12 }}>database</span>ZoomInfo</span>
                  </div>
                  <div className="e8-kv"><span className="e8-kv-k">Tenure</span><span className="e8-kv-v">{ct.enrich.tenure}</span></div>
                  {ct.enrich.priorAt ? <div className="e8-kv"><span className="e8-kv-k">Background</span><span className="e8-kv-v">{ct.enrich.priorAt}</span></div> : null}
                  <div className="e8-kv"><span className="e8-kv-k">Seniority</span><span className="e8-kv-v">{ct.enrich.seniority}</span></div>
                  <div className="e8-kv"><span className="e8-kv-k">Reports to</span><span className="e8-kv-v">{ct.enrich.reportsTo}</span></div>
                  <div className="e8-kv"><span className="e8-kv-k">Direct reports</span><span className="e8-kv-v tnum">{ct.enrich.directReports}</span></div>
                  <div className="e8-kv"><span className="e8-kv-k">Location</span><span className="e8-kv-v">{ct.enrich.location}</span></div>
                  {ct.enrich.mutuals && ct.enrich.mutuals.length ? (
                    <div style={{ marginTop: 9 }}>
                      <div style={{ fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)', marginBottom: 6 }}>Mutual connections</div>
                      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
                        {ct.enrich.mutuals.map((m) => <span key={m} className="e8-mutual"><DSx.Avatar name={m} size="sm" />{m}</span>)}
                      </div>
                    </div>
                  ) : null}
                  {client ? <a className="e8-link" style={{ fontSize: 'var(--ui-text-sm)', display: 'inline-block', marginTop: 10 }} tabIndex={0} onKeyDown={window.keyActivate} onClick={() => navigate('client/' + client.id + '/org')}>View in org chart →</a> : null}
                </div>
              ) : null}
              <div className="e8-rail-block">
                <div className="e8-rail-title">Owns</div>
                <div style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-secondary)', marginBottom: 6 }}>{ct.owns}</div>
                {ownId ? <a className="e8-link" style={{ fontSize: 'var(--ui-text-sm)' }} tabIndex={0} onKeyDown={window.keyActivate} onClick={() => navigate(ownId.startsWith('JO') ? 'job/' + ownId + '/overview' : 'jobs/intake')}>Open {ownId} →</a> : null}
              </div>
              <div className="e8-rail-block">
                <div className="e8-rail-title">Client</div>
                <button type="button" className="e8-applrow" onClick={() => (client ? navigate('client/' + client.id) : null)}>
                  <ClientMark name={ct.client} />
                  <span style={{ minWidth: 0 }}>
                    <span style={{ display: 'block', fontSize: 'var(--ui-text-sm)', fontWeight: 500 }}>{ct.client}</span>
                    {client ? <span style={{ display: 'block', fontSize: 'var(--ui-text-xs)', color: 'var(--ui-text-tertiary)' }}>{client.tier} · {client.openJobs} open job{client.openJobs === 1 ? '' : 's'}</span> : null}
                  </span>
                </button>
              </div>
              {convo ? (
                <div className="e8-rail-block">
                  <div className="e8-rail-title">Latest thread</div>
                  <div style={{ fontSize: 'var(--ui-text-sm)', color: 'var(--ui-text-secondary)', marginBottom: 7 }}>{ct.name} · {convo.lastWhen}</div>
                  <DSx.Button variant="secondary" size="sm" icon="forum" onClick={() => navigate('inbox/' + convo.id)}>Open in Inbox</DSx.Button>
                </div>
              ) : null}
            </div>
          </div>
        </div>
      </div>
    </React.Fragment>
  );
}

Object.assign(window, { ClientsScreen, ContactsScreen, ClientDetailScreen, ContactDetailScreen, E8CreateDialog: CrmCreateDialog });
