// PERSONA PLATFORM — Extra enterprise views: modals, compliance panels, analytics widgets.
(function () {
  const { useState, useMemo, useEffect } = React;
  const T = window.ArbiterTokens;

  // ── Modal primitive ─────────────────────────────────────────────────────
  function PnModal({ open, onClose, title, children, width = 560, footer }) {
    if (!open) return null;
    const pn = window.__pn;
    return (
      <div onClick={onClose}
        style={{ position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.55)', zIndex: 2000, display: 'flex', alignItems: 'flex-start', justifyContent: 'center', padding: '80px 16px', overflow: 'auto' }}>
        <div onClick={e => e.stopPropagation()}
          style={{ width: '100%', maxWidth: `${width}px`, background: T.color.bg.card, borderRadius: T.radius.lg, boxShadow: '0 20px 60px rgba(15,23,42,0.35)', overflow: 'hidden', border: `1px solid ${T.color.border.light}` }}>
          <div style={{ padding: '14px 20px', borderBottom: `1px solid ${T.color.border.light}`, display: 'flex', justifyContent: 'space-between', alignItems: 'center', background: pn.indigoBg }}>
            <div style={{ fontSize: '14px', fontWeight: 700, color: pn.indigo, letterSpacing: '-0.01em' }}>{title}</div>
            <button onClick={onClose} style={{ border: 'none', background: 'transparent', fontSize: '18px', cursor: 'pointer', color: T.color.text.tertiary, lineHeight: 1 }}>×</button>
          </div>
          <div style={{ padding: '18px 20px' }}>{children}</div>
          {footer && <div style={{ padding: '12px 20px', borderTop: `1px solid ${T.color.border.light}`, background: T.color.bg.secondary, display: 'flex', justifyContent: 'flex-end', gap: '8px' }}>{footer}</div>}
        </div>
      </div>
    );
  }

  const field = { display: 'flex', flexDirection: 'column', gap: '4px', marginBottom: '12px' };
  const lbl = { fontSize: '10px', fontWeight: 700, color: T.color.text.tertiary, textTransform: 'uppercase', letterSpacing: '0.06em' };
  const inp = { padding: '8px 10px', borderRadius: '6px', border: `1px solid ${T.color.border.light}`, fontSize: '12px', fontFamily: T.font.family, background: T.color.bg.secondary, color: T.color.text.primary, width: '100%' };

  // ── Modal: New Profile ──────────────────────────────────────────────────
  function PnNewProfileModal({ open, onClose, onCreated }) {
    const pn = window.__pn;
    const [name, setName] = useState('');
    const [type, setType] = useState('Defendant');
    const [risk, setRisk] = useState('Medium');
    const [org, setOrg]   = useState('');
    const [title, setTitle] = useState('');
    const [notes, setNotes] = useState('');
    const [matter, setMatter] = useState('');

    useEffect(() => { if (!open) { setName(''); setType('Defendant'); setRisk('Medium'); setOrg(''); setTitle(''); setNotes(''); setMatter(''); } }, [open]);

    const canSubmit = name.trim().length > 1;
    const submit = () => {
      if (!canSubmit) return;
      const p = window.PnStore.createProfile({
        name: name.trim(), type, risk, organization: org.trim(), title: title.trim(), notes: notes.trim(),
        matters: matter.trim() ? [matter.trim()] : [],
        tags: [],
      });
      onClose();
      onCreated && onCreated(p);
    };

    return (
      <PnModal open={open} onClose={onClose} title="◆ New Profile"
        footer={
          <>
            <button onClick={onClose} style={pn.btnSecondary}>Cancel</button>
            <button onClick={submit} disabled={!canSubmit}
              style={{ ...pn.btnPrimary, opacity: canSubmit ? 1 : 0.5, cursor: canSubmit ? 'pointer' : 'not-allowed' }}>
              Create profile
            </button>
          </>
        }>
        <div style={field}><label style={lbl}>Name</label>
          <input value={name} onChange={e => setName(e.target.value)} placeholder="Full legal name" style={inp} autoFocus />
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '12px' }}>
          <div style={field}><label style={lbl}>Classification</label>
            <select value={type} onChange={e => setType(e.target.value)} style={inp}>
              {['Defendant', 'Witness', 'Attorney', 'Judge', 'Agent', 'Expert'].map(t => <option key={t} value={t}>{t}</option>)}
            </select>
          </div>
          <div style={field}><label style={lbl}>Risk</label>
            <select value={risk} onChange={e => setRisk(e.target.value)} style={inp}>
              {['Low', 'Medium', 'High', 'Critical'].map(r => <option key={r} value={r}>{r}</option>)}
            </select>
          </div>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '12px' }}>
          <div style={field}><label style={lbl}>Organization</label>
            <input value={org} onChange={e => setOrg(e.target.value)} style={inp} />
          </div>
          <div style={field}><label style={lbl}>Title</label>
            <input value={title} onChange={e => setTitle(e.target.value)} style={inp} />
          </div>
        </div>
        <div style={field}><label style={lbl}>Primary Matter</label>
          <input value={matter} onChange={e => setMatter(e.target.value)} placeholder="e.g. US v. Harrell Jr." style={inp} />
        </div>
        <div style={field}><label style={lbl}>Intelligence summary</label>
          <textarea value={notes} onChange={e => setNotes(e.target.value)} rows={3} style={{ ...inp, resize: 'vertical' }} />
        </div>
      </PnModal>
    );
  }

  // ── Modal: Order Psych Assessment ───────────────────────────────────────
  function PnAssessmentModal({ open, onClose, personId }) {
    const pn = window.__pn;
    const data = window.usePnStore ? window.usePnStore(['profile.updated']) : window.PERSONA_DATA;
    const [pid, setPid] = useState(personId || '');
    const [assessedBy, setAssessedBy] = useState('Dr. H. Tomlinson, PhD');
    const [o, setO] = useState(50); const [c, setC] = useState(50); const [e, setE] = useState(50);
    const [a, setA] = useState(50); const [n, setN] = useState(50);
    const [vuln, setVuln] = useState('');
    const [bias, setBias] = useState('');
    const [strat, setStrat] = useState('');

    useEffect(() => { if (open) setPid(personId || ''); }, [open, personId]);

    const candidates = data.people.filter(p => !p.psych);
    const ok = pid && assessedBy.trim();
    const submit = () => {
      if (!ok) return;
      window.PnStore.logAssessment(pid, {
        assessedBy: assessedBy.trim(),
        ocean: { o: +o, c: +c, e: +e, a: +a, n: +n },
        vulnerabilities: vuln.split(',').map(s => s.trim()).filter(Boolean),
        biases: bias.split(',').map(s => s.trim()).filter(Boolean),
        deception: [],
        interrogation: strat.trim() || 'Standard cognitive-interview framework applicable. Defer confrontational questions to mid-session.',
      });
      onClose();
    };

    const slider = (lbl2, v, set, color) => (
      <div style={{ marginBottom: '10px' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '3px' }}>
          <span style={{ fontSize: '11px', fontWeight: 700 }}>{lbl2}</span>
          <span style={{ fontSize: '11px', fontFamily: T.font.mono, fontWeight: 800, color }}>{v}</span>
        </div>
        <input type="range" min={0} max={100} value={v} onChange={ev => set(+ev.target.value)}
          style={{ width: '100%', accentColor: color }} />
      </div>
    );

    return (
      <PnModal open={open} onClose={onClose} title="◆ Log Psychometric Assessment" width={640}
        footer={
          <>
            <button onClick={onClose} style={pn.btnSecondary}>Cancel</button>
            <button onClick={submit} disabled={!ok}
              style={{ ...pn.btnPrimary, opacity: ok ? 1 : 0.5, cursor: ok ? 'pointer' : 'not-allowed' }}>
              Save assessment
            </button>
          </>
        }>
        <div style={field}><label style={lbl}>Subject</label>
          <select value={pid} onChange={ev => setPid(ev.target.value)} style={inp}>
            <option value="">— Select subject —</option>
            {candidates.map(p => <option key={p.id} value={p.id}>{p.name} · {p.type}</option>)}
            {personId && !candidates.find(p => p.id === personId) &&
              <option value={personId}>{(data.people.find(p => p.id === personId) || {}).name} (re-assess)</option>}
          </select>
        </div>
        <div style={field}><label style={lbl}>Assessed by</label>
          <input value={assessedBy} onChange={ev => setAssessedBy(ev.target.value)} style={inp} />
        </div>
        <div style={{ padding: '10px 12px', background: pn.indigoBg, borderRadius: '6px', marginBottom: '12px' }}>
          <div style={{ fontSize: '10px', fontWeight: 700, color: pn.indigo, textTransform: 'uppercase', marginBottom: '8px' }}>O.C.E.A.N. Baseline</div>
          {slider('Openness', o, setO, '#4F46E5')}
          {slider('Conscientiousness', c, setC, '#059669')}
          {slider('Extraversion', e, setE, '#B45309')}
          {slider('Agreeableness', a, setA, '#7C3AED')}
          {slider('Neuroticism', n, setN, '#9F1239')}
        </div>
        <div style={field}><label style={lbl}>Vulnerabilities (comma-separated)</label>
          <input value={vuln} onChange={ev => setVuln(ev.target.value)} placeholder="sunk-cost, loss-aversion" style={inp} />
        </div>
        <div style={field}><label style={lbl}>Cognitive biases (comma-separated)</label>
          <input value={bias} onChange={ev => setBias(ev.target.value)} placeholder="anchoring, confirmation-bias" style={inp} />
        </div>
        <div style={field}><label style={lbl}>Examination strategy</label>
          <textarea value={strat} onChange={ev => setStrat(ev.target.value)} rows={3} style={{ ...inp, resize: 'vertical' }} />
        </div>
      </PnModal>
    );
  }

  // ── Modal: Log Touchpoint ───────────────────────────────────────────────
  function PnTouchpointModal({ open, onClose, personId }) {
    const pn = window.__pn;
    const data = window.usePnStore ? window.usePnStore(['profile.created']) : window.PERSONA_DATA;
    const [pid, setPid] = useState(personId || '');
    const [channel, setChannel] = useState('Call');
    const [direction, setDirection] = useState('outbound');
    const [subject, setSubject] = useState('');
    const [note, setNote] = useState('');

    useEffect(() => { if (open) { setPid(personId || ''); setSubject(''); setNote(''); } }, [open, personId]);
    const ok = pid && subject.trim().length > 1;
    const submit = () => {
      if (!ok) return;
      window.PnStore.logTouchpoint({ personId: pid, channel, direction, subject: subject.trim(), note: note.trim() });
      onClose();
    };

    return (
      <PnModal open={open} onClose={onClose} title=" Log Touchpoint"
        footer={
          <>
            <button onClick={onClose} style={pn.btnSecondary}>Cancel</button>
            <button onClick={submit} disabled={!ok} style={{ ...pn.btnPrimary, opacity: ok ? 1 : 0.5, cursor: ok ? 'pointer' : 'not-allowed' }}>Log</button>
          </>
        }>
        <div style={field}><label style={lbl}>Subject contact</label>
          <select value={pid} onChange={e => setPid(e.target.value)} style={inp}>
            <option value="">— Select —</option>
            {data.people.map(p => <option key={p.id} value={p.id}>{p.name} · {p.type}</option>)}
          </select>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '12px' }}>
          <div style={field}><label style={lbl}>Channel</label>
            <select value={channel} onChange={e => setChannel(e.target.value)} style={inp}>
              {['Call', 'Email', 'Meeting', 'SMS', 'eSignature', 'Document', 'In-person'].map(c => <option key={c}>{c}</option>)}
            </select>
          </div>
          <div style={field}><label style={lbl}>Direction</label>
            <select value={direction} onChange={e => setDirection(e.target.value)} style={inp}>
              <option value="outbound">Outbound</option><option value="inbound">Inbound</option>
            </select>
          </div>
        </div>
        <div style={field}><label style={lbl}>Subject / title</label>
          <input value={subject} onChange={e => setSubject(e.target.value)} style={inp} autoFocus />
        </div>
        <div style={field}><label style={lbl}>Notes</label>
          <textarea value={note} onChange={e => setNote(e.target.value)} rows={3} style={{ ...inp, resize: 'vertical' }} />
        </div>
      </PnModal>
    );
  }

  // ── Modal: New Task ─────────────────────────────────────────────────────
  function PnTaskModal({ open, onClose, personId }) {
    const pn = window.__pn;
    const data = window.usePnStore ? window.usePnStore(['profile.created']) : window.PERSONA_DATA;
    const [pid, setPid] = useState(personId || '');
    const [title, setTitle] = useState('');
    const [due, setDue] = useState('');
    const [priority, setPriority] = useState('Normal');

    useEffect(() => { if (open) { setPid(personId || ''); setTitle(''); setDue(''); setPriority('Normal'); } }, [open, personId]);
    const ok = pid && title.trim() && due;
    const submit = () => { if (!ok) return; window.PnStore.createTask({ personId: pid, title: title.trim(), due, priority }); onClose(); };

    return (
      <PnModal open={open} onClose={onClose} title=" New CRM Task"
        footer={
          <>
            <button onClick={onClose} style={pn.btnSecondary}>Cancel</button>
            <button onClick={submit} disabled={!ok} style={{ ...pn.btnPrimary, opacity: ok ? 1 : 0.5, cursor: ok ? 'pointer' : 'not-allowed' }}>Create</button>
          </>
        }>
        <div style={field}><label style={lbl}>Subject</label>
          <select value={pid} onChange={e => setPid(e.target.value)} style={inp}>
            <option value="">— Select —</option>
            {data.people.map(p => <option key={p.id} value={p.id}>{p.name} · {p.type}</option>)}
          </select>
        </div>
        <div style={field}><label style={lbl}>Task</label>
          <input value={title} onChange={e => setTitle(e.target.value)} style={inp} autoFocus />
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '12px' }}>
          <div style={field}><label style={lbl}>Due</label>
            <input type="date" value={due} onChange={e => setDue(e.target.value)} style={inp} />
          </div>
          <div style={field}><label style={lbl}>Priority</label>
            <select value={priority} onChange={e => setPriority(e.target.value)} style={inp}>
              {['Low', 'Normal', 'High', 'Urgent'].map(p => <option key={p}>{p}</option>)}
            </select>
          </div>
        </div>
      </PnModal>
    );
  }

  // ── Widget: Risk trend sparkline ────────────────────────────────────────
  function PnRiskSparkline({ personId, w = 100, h = 24, color = '#4F46E5' }) {
    const series = (window.PnStore && window.PnStore.data.riskTrend[personId]) || [];
    if (!series.length) return <span style={{ fontSize: '10px', color: T.color.text.tertiary }}>—</span>;
    const max = 100, min = 0;
    const pts = series.map((v, i) => {
      const x = (i / (series.length - 1)) * w;
      const y = h - ((v - min) / (max - min)) * h;
      return `${x},${y}`;
    }).join(' ');
    const last = series[series.length - 1];
    const first = series[0];
    const trend = last - first;
    const trendColor = trend > 5 ? '#9F1239' : trend < -5 ? '#059669' : T.color.text.tertiary;
    return (
      <div style={{ display: 'inline-flex', alignItems: 'center', gap: '6px' }}>
        <svg width={w} height={h} style={{ display: 'block' }}>
          <polyline points={pts} fill="none" stroke={color} strokeWidth="1.5" />
          <circle cx={w} cy={h - (last / max) * h} r="2.5" fill={color} />
        </svg>
        <span style={{ fontSize: '10px', fontFamily: T.font.mono, color: trendColor, fontWeight: 700 }}>
          {trend > 0 ? '↑' : trend < 0 ? '↓' : '→'}{Math.abs(trend)}
        </span>
      </div>
    );
  }

  // ── Panel: Audit timeline ───────────────────────────────────────────────
  function PnAuditTimeline({ personId = null, limit = 20 }) {
    const pn = window.__pn;
    const data = window.usePnStore ? window.usePnStore(['profile.created', 'profile.updated', 'psych.assessed', 'touchpoint.logged', 'task.created', 'task.updated', 'dossier.exported', 'doc.referenced']) : window.PERSONA_DATA;
    const rows = (data.auditLog || []).filter(r => !personId || r.personId === personId).slice(0, limit);
    return (
      <div style={{ ...pn.card, marginBottom: 0 }}>
        <div style={pn.cardH}><span> Chain-of-Custody</span><span style={{ fontSize: '10px', fontFamily: T.font.mono, color: T.color.text.tertiary }}>{rows.length} entries</span></div>
        <div style={{ padding: '6px 0', maxHeight: '280px', overflowY: 'auto' }}>
          {rows.length === 0 && <div style={{ padding: '20px', textAlign: 'center', color: T.color.text.tertiary, fontSize: '12px' }}>No audit entries yet.</div>}
          {rows.map(r => (
            <div key={r.id} style={{ padding: '8px 16px', borderBottom: `1px solid ${T.color.border.light}`, display: 'grid', gridTemplateColumns: '110px 1fr', gap: '12px' }}>
              <span style={{ fontSize: '10px', fontFamily: T.font.mono, color: T.color.text.tertiary, whiteSpace: 'nowrap' }}>{r.ts}</span>
              <div>
                <div style={{ fontSize: '12px', fontWeight: 700, color: pn.indigo }}>{r.action}</div>
                <div style={{ fontSize: '11px', color: T.color.text.secondary, marginTop: '2px' }}>{r.detail}</div>
                <div style={{ fontSize: '10px', color: T.color.text.tertiary, marginTop: '2px' }}>{r.actor}{r.personId ? ` · ${r.personId}` : ''}</div>
              </div>
            </div>
          ))}
        </div>
      </div>
    );
  }

  // ── Panel: Consent / Privacy ────────────────────────────────────────────
  function PnConsentPanel() {
    const pn = window.__pn;
    const data = window.usePnStore ? window.usePnStore(['profile.created']) : window.PERSONA_DATA;
    return (
      <div style={{ ...pn.card, marginBottom: 0 }}>
        <div style={pn.cardH}>
          <span>◈ Consent & Privacy Register</span>
          <span style={{ fontSize: '10px', fontFamily: T.font.mono, color: T.color.text.tertiary }}>{data.people.length} subjects</span>
        </div>
        <table style={{ width: '100%', borderCollapse: 'collapse' }}>
          <thead><tr>
            <th style={pn.th}>Subject</th>
            <th style={pn.th}>Scope</th>
            <th style={pn.th}>Retention</th>
            <th style={pn.th}>Privilege</th>
            <th style={pn.th}>Release</th>
            <th style={pn.th}>Last review</th>
          </tr></thead>
          <tbody>
            {data.people.map(p => {
              const c = data.consent[p.id] || {};
              return (
                <tr key={p.id}>
                  <td style={pn.td}><div style={{ fontWeight: 600 }}>{p.name}</div><span style={{ fontSize: '10px', color: T.color.text.tertiary, fontFamily: T.font.mono }}>{p.id}</span></td>
                  <td style={pn.td}><span style={{ ...pn.tag, background: T.color.bg.secondary, color: T.color.text.secondary }}>{c.piiScope || '—'}</span></td>
                  <td style={{ ...pn.td, fontFamily: T.font.mono, fontSize: '11px' }}>{c.retentionYears ? `${c.retentionYears}y` : '—'}</td>
                  <td style={pn.td}>
                    {(c.privilegeFlags || []).length === 0
                      ? <span style={{ fontSize: '11px', color: T.color.text.tertiary }}>—</span>
                      : c.privilegeFlags.map(f => <span key={f} style={{ ...pn.tag, background: pn.indigoBg, color: pn.indigo, marginRight: '3px' }}>{f}</span>)}
                  </td>
                  <td style={pn.td}>
                    {c.signedRelease
                      ? <span style={{ ...pn.tag, background: pn.emeraldBg, color: pn.emerald }}>Signed</span>
                      : <span style={{ ...pn.tag, background: pn.amberBg, color: pn.amber }}>Pending</span>}
                  </td>
                  <td style={{ ...pn.td, fontFamily: T.font.mono, fontSize: '11px', color: T.color.text.secondary }}>{c.lastReview || '—'}</td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    );
  }

  // ── Panel: Conflicts / Ethical Walls ────────────────────────────────────
  function PnConflictsPanel() {
    const pn = window.__pn;
    const data = window.usePnStore ? window.usePnStore(['conflict.resolved', 'profile.created']) : window.PERSONA_DATA;
    const rows = data.conflicts || [];
    const sev = (s) => s === 'Critical' ? { bg: pn.crimsonBg, color: pn.crimson } : s === 'High' ? { bg: pn.orangeBg, color: pn.orange } : { bg: pn.amberBg, color: pn.amber };
    return (
      <div style={{ ...pn.card, marginBottom: 0, borderTop: `2px solid ${pn.crimson}` }}>
        <div style={{ ...pn.cardH, color: pn.crimson }}>
          <span>flag Conflict-of-Interest · Ethical-Wall Register</span>
          <span style={{ fontSize: '10px', fontFamily: T.font.mono, color: T.color.text.tertiary }}>
            {rows.filter(r => r.status === 'Active').length} active / {rows.length} total
          </span>
        </div>
        {rows.length === 0 ? (
          <div style={{ padding: '32px', textAlign: 'center', color: T.color.text.tertiary, fontSize: '12px' }}>No conflicts detected.</div>
        ) : (
          <table style={{ width: '100%', borderCollapse: 'collapse' }}>
            <thead><tr>
              <th style={pn.th}>Severity</th>
              <th style={pn.th}>Category</th>
              <th style={pn.th}>Summary</th>
              <th style={pn.th}>Status</th>
              <th style={pn.th}></th>
            </tr></thead>
            <tbody>
              {rows.map(r => {
                const s = sev(r.severity);
                return (
                  <tr key={r.id}>
                    <td style={pn.td}><span style={{ ...pn.tag, background: s.bg, color: s.color }}>{r.severity}</span></td>
                    <td style={{ ...pn.td, fontSize: '11px', fontWeight: 600 }}>{r.category}</td>
                    <td style={{ ...pn.td, fontSize: '11px', color: T.color.text.secondary }}>{r.summary}</td>
                    <td style={pn.td}>
                      {r.status === 'Resolved'
                        ? <span style={{ ...pn.tag, background: pn.emeraldBg, color: pn.emerald }}>Resolved</span>
                        : <span style={{ ...pn.tag, background: pn.crimsonBg, color: pn.crimson }}>Active</span>}
                    </td>
                    <td style={{ ...pn.td, textAlign: 'right' }}>
                      {r.status === 'Active' && <button style={pn.btnGhost} onClick={() => window.PnStore.resolveConflict(r.id)}>Resolve</button>}
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        )}
      </div>
    );
  }

  // ── Panel: Centrality / Influence ───────────────────────────────────────
  function PnCentralityPanel({ onSelectPerson }) {
    const pn = window.__pn;
    window.usePnStore && window.usePnStore(['profile.created']);
    const scores = window.PnStore ? window.PnStore.influenceScores() : [];
    const max = Math.max(1, ...scores.map(s => s.influence));
    return (
      <div style={{ ...pn.card, marginBottom: 0 }}>
        <div style={pn.cardH}><span>◈ Influence Centrality</span><span style={{ fontSize: '10px', fontFamily: T.font.mono, color: T.color.text.tertiary }}>degree + 1-hop propagation</span></div>
        <div style={{ padding: '10px 16px', display: 'flex', flexDirection: 'column', gap: '6px' }}>
          {scores.slice(0, 12).map(s => {
            const tc = pn.typeColor(s.person.type);
            const pct = (s.influence / max) * 100;
            return (
              <div key={s.person.id} onClick={() => onSelectPerson && onSelectPerson(s.person.id)}
                style={{ cursor: onSelectPerson ? 'pointer' : 'default', padding: '6px 0' }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '3px' }}>
                  <span style={{ fontSize: '12px', fontWeight: 700 }}>{s.person.name}</span>
                  <span style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
                    <span style={{ ...pn.tag, background: tc.bg, color: tc.color, fontSize: '9px' }}>{s.person.type}</span>
                    <span style={{ fontSize: '11px', fontFamily: T.font.mono, color: pn.indigo, fontWeight: 700 }}>{s.influence}</span>
                    <span style={{ fontSize: '10px', color: T.color.text.tertiary }}>deg {s.degree}</span>
                  </span>
                </div>
                <div style={{ height: '4px', background: T.color.bg.secondary, borderRadius: '2px', overflow: 'hidden' }}>
                  <div style={{ width: `${pct}%`, height: '100%', background: `linear-gradient(90deg, ${pn.indigo}55, ${pn.indigo})` }} />
                </div>
              </div>
            );
          })}
        </div>
      </div>
    );
  }

  // ── Panel: Cohorts ──────────────────────────────────────────────────────
  function PnCohortsPanel({ onSelectPerson }) {
    const pn = window.__pn;
    const data = window.usePnStore ? window.usePnStore(['bulk.tagged', 'profile.created']) : window.PERSONA_DATA;
    return (
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '14px' }}>
        {data.cohorts.map(c => (
          <div key={c.id} style={{ ...pn.card, marginBottom: 0, borderLeft: `3px solid ${pn.indigo}` }}>
            <div style={pn.cardH}>
              <span>{c.name}</span>
              <div style={{ display: 'flex', gap: '6px', alignItems: 'center' }}>
                <span style={{ ...pn.tag, background: pn.indigoBg, color: pn.indigo }}>{c.members.length}</span>
                <button style={pn.btnGhost} onClick={() => window.PnStore.bulkTag(c.members, c.tag)}>Apply tag</button>
              </div>
            </div>
            <div style={{ padding: '10px 16px', display: 'flex', flexDirection: 'column', gap: '4px' }}>
              {c.members.length === 0 && <div style={{ fontSize: '12px', color: T.color.text.tertiary }}>No members.</div>}
              {c.members.map(id => {
                const p = data.people.find(x => x.id === id);
                if (!p) return null;
                const tc = pn.typeColor(p.type);
                return (
                  <div key={id} onClick={() => onSelectPerson && onSelectPerson(id)}
                    style={{ cursor: onSelectPerson ? 'pointer' : 'default', padding: '6px 8px', borderRadius: '5px', border: `1px solid ${T.color.border.light}`, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                    <span style={{ fontSize: '12px', fontWeight: 600 }}>{p.name}</span>
                    <span style={{ ...pn.tag, background: tc.bg, color: tc.color, fontSize: '9px' }}>{p.type}</span>
                  </div>
                );
              })}
            </div>
          </div>
        ))}
      </div>
    );
  }

  // ── Panel: Saved Views ──────────────────────────────────────────────────
  function PnSavedViewsPanel({ onApply }) {
    const pn = window.__pn;
    const data = window.usePnStore ? window.usePnStore(['view.saved', 'view.deleted']) : window.PERSONA_DATA;
    return (
      <div style={{ ...pn.card, marginBottom: 0 }}>
        <div style={pn.cardH}><span>* Saved Views</span><span style={{ fontSize: '10px', fontFamily: T.font.mono, color: T.color.text.tertiary }}>{data.savedViews.length}</span></div>
        <div style={{ padding: '10px 16px', display: 'flex', flexDirection: 'column', gap: '6px' }}>
          {data.savedViews.map(v => {
            const parts = Object.entries(v.filter).map(([k, val]) => `${k}=${val}`).join(' · ');
            return (
              <div key={v.id} style={{ padding: '8px 12px', borderRadius: '6px', border: `1px solid ${T.color.border.light}`, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <div>
                  <div style={{ fontSize: '12px', fontWeight: 700 }}>{v.name} {v.system && <span style={{ fontSize: '9px', color: T.color.text.tertiary, marginLeft: '4px' }}>(system)</span>}</div>
                  <div style={{ fontSize: '10px', fontFamily: T.font.mono, color: T.color.text.tertiary, marginTop: '2px' }}>{parts}</div>
                </div>
                <div style={{ display: 'flex', gap: '4px' }}>
                  <button style={pn.btnGhost} onClick={() => onApply && onApply(v.filter)}>Apply</button>
                  {!v.system && <button style={{ ...pn.btnGhost, color: pn.crimson }} onClick={() => window.PnStore.deleteView(v.id)}>Delete</button>}
                </div>
              </div>
            );
          })}
        </div>
      </div>
    );
  }

  // ── Widget: Witness Prep Checklist ──────────────────────────────────────
  function PnPrepChecklist({ personId }) {
    const pn = window.__pn;
    const [items, setItems] = useState(null);
    const [checked, setChecked] = useState({});
    useEffect(() => { if (personId) setItems(window.PnStore.prepChecklist(personId)); }, [personId]);
    if (!items) return null;
    if (!items.length) {
      return <div style={{ ...pn.card, marginBottom: 0, padding: '20px', textAlign: 'center', color: T.color.text.tertiary, fontSize: '12px' }}>No psych baseline — cannot generate checklist.</div>;
    }
    return (
      <div style={{ ...pn.card, marginBottom: 0, borderLeft: `3px solid ${pn.emerald}` }}>
        <div style={{ ...pn.cardH, background: pn.emeraldBg }}>
          <span style={{ color: pn.emerald, fontWeight: 700 }}>ok Witness/Subject Prep Checklist</span>
          <span style={{ fontSize: '10px', fontFamily: T.font.mono, color: T.color.text.tertiary }}>{items.length} items · auto-generated</span>
        </div>
        <div style={{ padding: '10px 16px', display: 'flex', flexDirection: 'column', gap: '6px' }}>
          {items.map((it, i) => (
            <label key={i} style={{ display: 'flex', gap: '10px', alignItems: 'flex-start', padding: '7px 10px', borderRadius: '5px', background: checked[i] ? pn.emeraldBg : 'transparent', cursor: 'pointer', border: `1px solid ${T.color.border.light}` }}>
              <input type="checkbox" checked={!!checked[i]} onChange={() => setChecked(c => ({ ...c, [i]: !c[i] }))}
                style={{ accentColor: pn.emerald, marginTop: '2px' }} />
              <div>
                <div style={{ fontSize: '12px', color: T.color.text.primary, fontWeight: 500, textDecoration: checked[i] ? 'line-through' : 'none' }}>{it.text}</div>
                <div style={{ fontSize: '10px', fontFamily: T.font.mono, color: T.color.text.tertiary, marginTop: '2px' }}>→ {it.source}</div>
              </div>
            </label>
          ))}
        </div>
      </div>
    );
  }

  // ── Widget: Dossier Export Button ───────────────────────────────────────
  function PnDossierButton({ personId, label = 'Export court-admissible dossier' }) {
    const pn = window.__pn;
    const [last, setLast] = useState(null);
    const go = () => {
      const pkg = window.PnStore.exportDossier(personId);
      setLast(pkg);
      setTimeout(() => setLast(null), 2200);
    };
    return (
      <button onClick={go} style={{ ...pn.btnPrimary, display: 'inline-flex', alignItems: 'center', gap: '6px' }}>
         {last ? 'Dossier packaged' : label}
      </button>
    );
  }

  // ── Compliance Hub (top-level tab) ──────────────────────────────────────
  function PnComplianceHub() {
    const pn = window.__pn;
    const data = window.usePnStore ? window.usePnStore(['conflict.resolved', 'dossier.exported', 'profile.updated']) : window.PERSONA_DATA;
    const activeConflicts = (data.conflicts || []).filter(c => c.status === 'Active').length;
    const privileged = Object.values(data.consent || {}).filter(c => (c.privilegeFlags || []).length).length;
    const unsigned = Object.values(data.consent || {}).filter(c => !c.signedRelease).length;
    const audits = (data.auditLog || []).length;

    return (
      <div>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '12px', marginBottom: '16px' }}>
          <div style={pn.stat}><span style={pn.statLabel}>Active Conflicts</span><span style={{ ...pn.statValue, color: pn.crimson }}>{activeConflicts}</span><span style={{ ...pn.statDelta, color: T.color.text.tertiary }}>ethical-wall review</span></div>
          <div style={pn.stat}><span style={pn.statLabel}>Privileged Subjects</span><span style={{ ...pn.statValue, color: pn.indigo }}>{privileged}</span><span style={{ ...pn.statDelta, color: T.color.text.tertiary }}>attorney-client · work-product</span></div>
          <div style={pn.stat}><span style={pn.statLabel}>Releases Pending</span><span style={{ ...pn.statValue, color: pn.amber }}>{unsigned}</span><span style={{ ...pn.statDelta, color: T.color.text.tertiary }}>signed consent missing</span></div>
          <div style={pn.stat}><span style={pn.statLabel}>Audit Entries</span><span style={{ ...pn.statValue }}>{audits}</span><span style={{ ...pn.statDelta, color: T.color.text.tertiary }}>chain-of-custody events</span></div>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '14px' }}>
          <PnConflictsPanel />
          <PnAuditTimeline limit={15} />
        </div>
        <div style={{ marginTop: '14px' }}>
          <PnConsentPanel />
        </div>
      </div>
    );
  }

  // ── Exports ─────────────────────────────────────────────────────────────
  window.PnModal            = PnModal;
  window.PnNewProfileModal  = PnNewProfileModal;
  window.PnAssessmentModal  = PnAssessmentModal;
  window.PnTouchpointModal  = PnTouchpointModal;
  window.PnTaskModal        = PnTaskModal;
  window.PnRiskSparkline    = PnRiskSparkline;
  window.PnAuditTimeline    = PnAuditTimeline;
  window.PnConsentPanel     = PnConsentPanel;
  window.PnConflictsPanel   = PnConflictsPanel;
  window.PnCentralityPanel  = PnCentralityPanel;
  window.PnCohortsPanel     = PnCohortsPanel;
  window.PnSavedViewsPanel  = PnSavedViewsPanel;
  window.PnPrepChecklist    = PnPrepChecklist;
  window.PnDossierButton    = PnDossierButton;
  window.PnComplianceHub    = PnComplianceHub;
})();
