// ESIGN PLATFORM — enterprise extension views (improvements #1-#18)
// Additive components wired to EsStore via useEsStore; rendered by patched hubs.
(function () {
  const { useState, useMemo, useEffect } = React;
  const Tx = window.ArbiterTokens;

  // ──────────────────────────────────────────────────────────────────────────────
  // Small utility components
  // ──────────────────────────────────────────────────────────────────────────────

  function EsModal({ open, title, onClose, width = 720, children }) {
    if (!open) return null;
    const es = window.__es;
    return (
      <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(15,23,42,0.56)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <div onClick={e => e.stopPropagation()} style={{ width, maxWidth: '92vw', maxHeight: '86vh', overflow: 'auto', background: Tx.color.bg.card, borderRadius: '12px', boxShadow: '0 20px 60px rgba(0,0,0,0.35)', border: `1px solid ${Tx.color.border.light}` }}>
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '14px 20px', borderBottom: `1px solid ${Tx.color.border.light}` }}>
            <div style={{ fontSize: '14px', fontWeight: 700, color: Tx.color.text.primary }}>{title}</div>
            <button onClick={onClose} style={{ ...es.btnIcon, fontSize: '16px' }}>×</button>
          </div>
          <div style={{ padding: '18px 20px' }}>{children}</div>
        </div>
      </div>
    );
  }
  window.EsModal = EsModal;

  function EsActionButton({ onClick, label, variant = 'secondary', icon = null, disabled = false }) {
    const es = window.__es;
    const style = variant === 'primary' ? es.btnPrimary : variant === 'ghost' ? es.btnGhost : es.btnSecondary;
    return (
      <button onClick={onClick} disabled={disabled} style={{ ...style, opacity: disabled ? 0.45 : 1, cursor: disabled ? 'not-allowed' : 'pointer' }}>
        {icon}{label}
      </button>
    );
  }
  window.EsActionButton = EsActionButton;

  // ──────────────────────────────────────────────────────────────────────────────
  // #1 — Signer Flow Preview (end-to-end signer experience)
  // ──────────────────────────────────────────────────────────────────────────────

  function EsSignerPreview({ envelopeId, onClose }) {
    const es = window.__es;
    const s = window.useEsStore(['envelope.created', 'envelope.sent']);
    const env = s.envelopes.find(e => e.id === envelopeId);
    const [step, setStep] = useState(0);
    const steps = ['Consent (ESIGN Act)', 'Identity Check (KBA)', 'Review Document', 'Sign Fields', 'Confirm & Submit'];
    if (!env) return null;

    return (
      <EsModal open onClose={onClose} title={`Signer Flow Preview · ${env.subject}`} width={780}>
        <div style={{ display: 'flex', gap: '8px', marginBottom: '18px' }}>
          {steps.map((name, i) => (
            <div key={i} style={{ flex: 1, padding: '10px 12px', borderRadius: '8px', background: i === step ? es.indigoBg : Tx.color.bg.secondary, border: `1px solid ${i === step ? es.indigo : Tx.color.border.light}`, textAlign: 'center', cursor: 'pointer' }} onClick={() => setStep(i)}>
              <div style={{ fontSize: '10px', fontWeight: 600, color: i === step ? es.indigo : Tx.color.text.tertiary, marginBottom: '3px' }}>STEP {i + 1}</div>
              <div style={{ fontSize: '11px', fontWeight: 600, color: Tx.color.text.primary }}>{name}</div>
            </div>
          ))}
        </div>
        <div style={{ padding: '20px', background: Tx.color.bg.secondary, borderRadius: '10px', border: `1px solid ${Tx.color.border.light}`, minHeight: '200px' }}>
          {step === 0 && (
            <div>
              <div style={{ fontSize: '13px', fontWeight: 700, color: Tx.color.text.primary, marginBottom: '10px' }}>Electronic Signature Consent</div>
              <div style={{ fontSize: '12px', color: Tx.color.text.secondary, lineHeight: 1.6, marginBottom: '12px' }}>By clicking <strong>I Agree</strong>, you consent to use electronic records and signatures under the ESIGN Act (15 U.S.C. §7001) and UETA where applicable. System records your consent, IP, user agent, and timestamp.</div>
              <div style={{ padding: '10px 14px', background: es.emeraldBg, borderRadius: '6px', fontSize: '11px', color: es.emerald, fontWeight: 600 }}>ok Consent captured · logged to audit trail</div>
            </div>
          )}
          {step === 1 && (
            <div>
              <div style={{ fontSize: '13px', fontWeight: 700, color: Tx.color.text.primary, marginBottom: '10px' }}>Knowledge-Based Authentication</div>
              <div style={{ fontSize: '12px', color: Tx.color.text.secondary, marginBottom: '12px' }}>5 identity questions sourced from credit bureau. Score ≥ 4/5 required.</div>
              {[1,2,3,4,5].map(q => (
                <div key={q} style={{ padding: '8px 12px', background: Tx.color.bg.card, borderRadius: '6px', border: `1px solid ${Tx.color.border.light}`, marginBottom: '6px', fontSize: '11px', display: 'flex', justifyContent: 'space-between' }}>
                  <span style={{ color: Tx.color.text.secondary }}>Q{q}: Public-records identity question</span>
                  <span style={{ color: es.emerald, fontWeight: 600 }}>ok Correct</span>
                </div>
              ))}
            </div>
          )}
          {step === 2 && (
            <div>
              <div style={{ fontSize: '13px', fontWeight: 700, color: Tx.color.text.primary, marginBottom: '10px' }}>Document Review</div>
              <div style={{ padding: '24px', background: '#fff', border: `1px dashed ${Tx.color.border.medium}`, borderRadius: '6px', textAlign: 'center', color: Tx.color.text.tertiary, fontSize: '12px' }}>
                 {env.subject}<br /><span style={{ fontSize: '10px' }}>{env.pages} pages · {env.fields} required fields</span>
              </div>
            </div>
          )}
          {step === 3 && <EsFieldCanvas envelopeId={envelopeId} />}
          {step === 4 && (
            <div>
              <div style={{ fontSize: '13px', fontWeight: 700, color: Tx.color.text.primary, marginBottom: '10px' }}>Confirm & Submit</div>
              <div style={{ padding: '14px 16px', background: es.indigoBg, borderRadius: '8px', border: `1px solid ${es.indigoBorder}`, fontSize: '12px', color: Tx.color.text.primary }}>
                <div style={{ marginBottom: '6px' }}><strong>Signer:</strong> {(env.recipients[0] || {}).name || 'Current User'}</div>
                <div style={{ marginBottom: '6px' }}><strong>Envelope:</strong> {env.id}</div>
                <div style={{ marginBottom: '6px' }}><strong>Pages:</strong> {env.pages}</div>
                <div><strong>Hash:</strong> <span style={{ fontFamily: Tx.font.mono, fontSize: '10px' }}>sha256 · locked on submit</span></div>
              </div>
              <div style={{ marginTop: '12px', padding: '10px 14px', background: es.emeraldBg, borderRadius: '6px', fontSize: '11px', color: es.emerald, fontWeight: 600 }}>ok Signature bound · Certificate enqueued</div>
            </div>
          )}
        </div>
      </EsModal>
    );
  }
  window.EsSignerPreview = EsSignerPreview;

  // ──────────────────────────────────────────────────────────────────────────────
  // #2 — Field Placement Canvas
  // ──────────────────────────────────────────────────────────────────────────────

  function EsFieldCanvas({ envelopeId, readOnly = false }) {
    const es = window.__es;
    const s = window.useEsStore();
    const fields = (s.fieldPlacements && s.fieldPlacements[envelopeId]) || [];
    const env = s.envelopes.find(e => e.id === envelopeId);
    const [page, setPage] = useState(fields[0] ? fields[0].page : 1);
    const pages = Array.from(new Set(fields.map(f => f.page))).sort((a, b) => a - b);
    const visible = fields.filter(f => f.page === page);
    const fieldColor = { signature: es.indigo, date: es.teal, initials: es.violet, text: es.slate, checkbox: es.amber };

    if (!env) return <div style={{ fontSize: '12px', color: Tx.color.text.tertiary, textAlign: 'center', padding: '40px' }}>Envelope not found.</div>;
    if (fields.length === 0) return <div style={{ fontSize: '12px', color: Tx.color.text.tertiary, textAlign: 'center', padding: '40px' }}>No field placements recorded for this envelope.</div>;

    return (
      <div>
        <div style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '12px' }}>
          <span style={{ fontSize: '11px', color: Tx.color.text.tertiary }}>Page:</span>
          {pages.map(p => (
            <button key={p} onClick={() => setPage(p)} style={{ ...es.filterBtn, ...(p === page ? es.filterBtnActive : {}) }}>{p}</button>
          ))}
          <span style={{ fontSize: '11px', color: Tx.color.text.tertiary, marginLeft: 'auto' }}>{visible.length} field(s) on page {page}</span>
        </div>
        <div style={{ position: 'relative', width: '100%', aspectRatio: '8.5/11', background: '#fff', border: `1px solid ${Tx.color.border.light}`, borderRadius: '6px', boxShadow: 'inset 0 0 0 1px rgba(0,0,0,0.02)' }}>
          <div style={{ position: 'absolute', top: '12px', left: '20px', right: '20px', fontSize: '10px', color: Tx.color.text.tertiary, fontFamily: Tx.font.mono }}>PAGE {page} OF {env.pages}</div>
          {visible.map(f => {
            const rec = (env.recipients.find(r => r.id === f.recipient) || {});
            return (
              <div key={f.id} title={`${f.label} · ${rec.name || f.recipient} · ${f.type}`}
                style={{
                  position: 'absolute',
                  left: `${f.x * 100}%`, top: `${f.y * 100}%`,
                  width: `${f.w * 100}%`, height: `${f.h * 100}%`,
                  background: (fieldColor[f.type] || es.slate) + '22',
                  border: `2px dashed ${fieldColor[f.type] || es.slate}`,
                  borderRadius: '3px',
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  fontSize: '9px', fontWeight: 700, color: fieldColor[f.type] || es.slate,
                  textTransform: 'uppercase', letterSpacing: '0.04em',
                }}>
                {f.type}
              </div>
            );
          })}
        </div>
        <div style={{ display: 'flex', gap: '10px', marginTop: '12px', flexWrap: 'wrap' }}>
          {Object.keys(fieldColor).map(k => (
            <div key={k} style={{ display: 'flex', alignItems: 'center', gap: '5px', fontSize: '10px', color: Tx.color.text.tertiary }}>
              <span style={{ width: '10px', height: '10px', background: fieldColor[k] + '33', border: `1.5px dashed ${fieldColor[k]}`, borderRadius: '2px' }}></span>{k}
            </div>
          ))}
        </div>
      </div>
    );
  }
  window.EsFieldCanvas = EsFieldCanvas;

  // ──────────────────────────────────────────────────────────────────────────────
  // #3 — Routing Visualizer (signer order graph)
  // ──────────────────────────────────────────────────────────────────────────────

  function EsRoutingVisualizer({ envelopeId }) {
    const es = window.__es;
    const s = window.useEsStore();
    const env = s.envelopes.find(e => e.id === envelopeId);
    if (!env) return null;
    const byOrder = [...env.recipients].sort((a, b) => (a.order || 0) - (b.order || 0));

    return (
      <div style={{ ...es.card, padding: '16px' }}>
        <div style={{ fontSize: '12px', fontWeight: 600, color: Tx.color.text.primary, marginBottom: '12px' }}>Routing Order</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: '8px', flexWrap: 'wrap' }}>
          {byOrder.map((r, i) => {
            const st = es.signerStatus(r.status);
            return (
              <React.Fragment key={r.id}>
                <div style={{ padding: '8px 12px', borderRadius: '8px', background: st.bg, border: `1px solid ${st.color}33`, minWidth: '140px' }}>
                  <div style={{ fontSize: '10px', fontWeight: 700, color: st.color, letterSpacing: '0.06em', marginBottom: '2px' }}>#{r.order} · {r.role.toUpperCase()}</div>
                  <div style={{ fontSize: '12px', fontWeight: 600, color: Tx.color.text.primary }}>{r.name}</div>
                  <div style={{ fontSize: '10px', color: Tx.color.text.tertiary, marginTop: '2px' }}>{r.status}{r.signedAt ? ' · ' + new Date(r.signedAt).toLocaleDateString() : ''}</div>
                </div>
                {i < byOrder.length - 1 && <span style={{ fontSize: '18px', color: Tx.color.text.tertiary }}>→</span>}
              </React.Fragment>
            );
          })}
        </div>
      </div>
    );
  }
  window.EsRoutingVisualizer = EsRoutingVisualizer;

  // ──────────────────────────────────────────────────────────────────────────────
  // #4 — Redline Queue (Accept/Reject/Counter workflow)
  // ──────────────────────────────────────────────────────────────────────────────

  function EsRedlineQueue() {
    const es = window.__es;
    const s = window.useEsStore(['redline.proposed', 'redline.decided']);
    const [editing, setEditing] = useState(null);
    const [counter, setCounter] = useState('');

    return (
      <div style={es.card}>
        <div style={es.cardH}>
          <span>Redline Workflow Queue</span>
          <span style={{ fontSize: '11px', color: Tx.color.text.tertiary }}>{s.redlines.length} proposals · {s.redlines.filter(r => r.status === 'Pending Review').length} pending</span>
        </div>
        <div style={{ padding: '0' }}>
          <table style={{ width: '100%', borderCollapse: 'collapse' }}>
            <thead><tr>
              <th style={es.th}>Clause</th>
              <th style={es.th}>Envelope</th>
              <th style={es.th}>Proposer</th>
              <th style={es.th}>Summary</th>
              <th style={es.th}>Status</th>
              <th style={es.th}>Actions</th>
            </tr></thead>
            <tbody>
              {s.redlines.map(r => {
                const env = s.envelopes.find(e => e.id === r.envelopeId);
                const pending = r.status === 'Pending Review';
                return (
                  <tr key={r.id}>
                    <td style={es.td}><strong>{r.clause}</strong></td>
                    <td style={es.td}><span style={{ color: es.indigo, fontWeight: 600 }}>{env ? env.subject : r.envelopeId}</span></td>
                    <td style={es.td}>{r.proposer}</td>
                    <td style={es.td} title={r.summary}>{r.summary.length > 60 ? r.summary.slice(0, 60) + '…' : r.summary}</td>
                    <td style={es.td}>
                      <span style={{ ...es.tag, background: pending ? es.amberBg : r.status === 'Accepted' ? es.emeraldBg : es.crimsonBg, color: pending ? es.amber : r.status === 'Accepted' ? es.emerald : es.crimson }}>{r.status}</span>
                    </td>
                    <td style={es.td}>
                      {pending ? (
                        <span style={{ display: 'inline-flex', gap: '6px' }}>
                          <button style={{ ...es.btnSecondary, color: es.emerald, borderColor: es.emerald + '55' }} onClick={() => window.EsStore.decideRedline(r.id, 'Accepted')}>Accept</button>
                          <button style={{ ...es.btnSecondary, color: es.crimson, borderColor: es.crimson + '55' }} onClick={() => window.EsStore.decideRedline(r.id, 'Rejected')}>Reject</button>
                          <button style={es.btnSecondary} onClick={() => { setEditing(r); setCounter(''); }}>Counter</button>
                        </span>
                      ) : <span style={{ fontSize: '10px', color: Tx.color.text.tertiary }}>{r.decidedBy || '—'}</span>}
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>

        <EsModal open={!!editing} title={editing ? `Counter-propose · ${editing.clause}` : ''} onClose={() => setEditing(null)} width={600}>
          {editing && (
            <div>
              <div style={{ fontSize: '11px', color: Tx.color.text.tertiary, marginBottom: '4px' }}>Original proposer summary</div>
              <div style={{ fontSize: '12px', color: Tx.color.text.primary, background: Tx.color.bg.secondary, padding: '10px', borderRadius: '6px', marginBottom: '14px' }}>{editing.summary}</div>
              <div style={{ fontSize: '11px', color: Tx.color.text.tertiary, marginBottom: '4px' }}>Counter-text</div>
              <textarea value={counter} onChange={e => setCounter(e.target.value)} rows={5} style={{ width: '100%', padding: '10px', border: `1px solid ${Tx.color.border.light}`, borderRadius: '6px', fontSize: '12px', fontFamily: Tx.font.family, resize: 'vertical' }} placeholder="Proposed alternate language…" />
              <div style={{ display: 'flex', justifyContent: 'flex-end', gap: '8px', marginTop: '14px' }}>
                <button style={es.btnSecondary} onClick={() => setEditing(null)}>Cancel</button>
                <button style={es.btnPrimary} onClick={() => { window.EsStore.decideRedline(editing.id, 'Counter-Proposed', 'M. Kirkland', counter); setEditing(null); }}>Send Counter</button>
              </div>
            </div>
          )}
        </EsModal>
      </div>
    );
  }
  window.EsRedlineQueue = EsRedlineQueue;

  // ──────────────────────────────────────────────────────────────────────────────
  // #6 — Clause Version Compare
  // ──────────────────────────────────────────────────────────────────────────────

  function EsClauseVersionCompare({ clauseId, onClose }) {
    const es = window.__es;
    const s = window.useEsStore();
    const versions = (s.clauseVersions && s.clauseVersions[clauseId]) || [];
    const [left, setLeft] = useState(versions[0] ? versions[0].version : null);
    const [right, setRight] = useState(versions[versions.length - 1] ? versions[versions.length - 1].version : null);
    const lv = versions.find(v => v.version === left);
    const rv = versions.find(v => v.version === right);

    return (
      <EsModal open onClose={onClose} title={`Clause Version Compare · ${clauseId}`} width={920}>
        {versions.length === 0 ? (
          <div style={{ fontSize: '12px', color: Tx.color.text.tertiary, padding: '20px', textAlign: 'center' }}>No version history available for this clause.</div>
        ) : (
          <div>
            <div style={{ display: 'flex', gap: '12px', marginBottom: '14px' }}>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: '10px', color: Tx.color.text.tertiary, marginBottom: '4px', fontWeight: 600 }}>LEFT VERSION</div>
                <select value={left || ''} onChange={e => setLeft(e.target.value)} style={{ width: '100%', padding: '6px 10px', fontSize: '12px', border: `1px solid ${Tx.color.border.light}`, borderRadius: '6px' }}>
                  {versions.map(v => <option key={v.version} value={v.version}>v{v.version} · {v.date}</option>)}
                </select>
              </div>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: '10px', color: Tx.color.text.tertiary, marginBottom: '4px', fontWeight: 600 }}>RIGHT VERSION</div>
                <select value={right || ''} onChange={e => setRight(e.target.value)} style={{ width: '100%', padding: '6px 10px', fontSize: '12px', border: `1px solid ${Tx.color.border.light}`, borderRadius: '6px' }}>
                  {versions.map(v => <option key={v.version} value={v.version}>v{v.version} · {v.date}</option>)}
                </select>
              </div>
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '12px' }}>
              <div style={{ padding: '14px', background: es.crimsonBg, border: `1px solid ${es.crimson}33`, borderRadius: '6px' }}>
                <div style={{ fontSize: '10px', color: es.crimson, fontWeight: 700, marginBottom: '6px' }}>− v{left}</div>
                <div style={{ fontSize: '11px', color: Tx.color.text.tertiary, marginBottom: '8px' }}>Approved by {lv?.approvedBy} · {lv?.date}</div>
                <div style={{ fontSize: '12px', color: Tx.color.text.primary, lineHeight: 1.6 }}>{lv?.text}</div>
              </div>
              <div style={{ padding: '14px', background: es.emeraldBg, border: `1px solid ${es.emerald}33`, borderRadius: '6px' }}>
                <div style={{ fontSize: '10px', color: es.emerald, fontWeight: 700, marginBottom: '6px' }}>+ v{right}</div>
                <div style={{ fontSize: '11px', color: Tx.color.text.tertiary, marginBottom: '8px' }}>Approved by {rv?.approvedBy} · {rv?.date}</div>
                <div style={{ fontSize: '12px', color: Tx.color.text.primary, lineHeight: 1.6 }}>{rv?.text}</div>
              </div>
            </div>
          </div>
        )}
      </EsModal>
    );
  }
  window.EsClauseVersionCompare = EsClauseVersionCompare;

  // ──────────────────────────────────────────────────────────────────────────────
  // #7 — Nudge Ladder Editor
  // ──────────────────────────────────────────────────────────────────────────────

  function EsNudgeEditor() {
    const es = window.__es;
    const s = window.useEsStore(['nudge.updated', 'nudge.triggered']);

    return (
      <div style={es.card}>
        <div style={es.cardH}>
          <span>Nudge Ladders</span>
          <span style={{ fontSize: '11px', color: Tx.color.text.tertiary }}>{s.nudgeLadders.length} active</span>
        </div>
        <table style={{ width: '100%', borderCollapse: 'collapse' }}>
          <thead><tr>
            <th style={es.th}>Envelope</th>
            <th style={es.th}>Signer</th>
            <th style={es.th}>Channel</th>
            <th style={es.th}>Cadence</th>
            <th style={es.th}>Attempts</th>
            <th style={es.th}>Escalate To</th>
            <th style={es.th}></th>
          </tr></thead>
          <tbody>
            {s.nudgeLadders.map(n => (
              <tr key={n.envelopeId + n.signer}>
                <td style={es.td}><span style={{ color: es.indigo, fontWeight: 600 }}>{n.envelopeId}</span></td>
                <td style={es.td}>{n.signer}</td>
                <td style={es.td}>
                  <select value={n.channel || 'Email'} onChange={e => window.EsStore.updateNudgeLadder(n.envelopeId, n.signer, { channel: e.target.value })} style={{ fontSize: '11px', padding: '3px 6px', border: `1px solid ${Tx.color.border.light}`, borderRadius: '4px' }}>
                    <option>Email</option><option>SMS</option><option>Both</option>
                  </select>
                </td>
                <td style={es.td}>
                  <select value={n.cadence || '24h'} onChange={e => window.EsStore.updateNudgeLadder(n.envelopeId, n.signer, { cadence: e.target.value })} style={{ fontSize: '11px', padding: '3px 6px', border: `1px solid ${Tx.color.border.light}`, borderRadius: '4px' }}>
                    <option>12h</option><option>24h</option><option>48h</option><option>72h</option>
                  </select>
                </td>
                <td style={es.td}><span style={{ fontFamily: Tx.font.mono, fontSize: '11px' }}>{n.attempts || 0}</span></td>
                <td style={es.td}>{n.escalateTo || '—'}</td>
                <td style={es.td}>
                  <button style={es.btnSecondary} onClick={() => window.EsStore.triggerNudge(n.envelopeId, n.signer)}>Nudge now</button>
                </td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    );
  }
  window.EsNudgeEditor = EsNudgeEditor;

  // ──────────────────────────────────────────────────────────────────────────────
  // #8 — Workflow Runtime Overlay
  // ──────────────────────────────────────────────────────────────────────────────

  function EsWorkflowRuntime() {
    const es = window.__es;
    const s = window.useEsStore(['workflow.advanced']);

    return (
      <div style={es.card}>
        <div style={es.cardH}>
          <span>Live Workflow Runtime</span>
          <span style={{ fontSize: '11px', color: Tx.color.text.tertiary }}>{s.wfRuntime.length} in flight</span>
        </div>
        <div style={{ padding: '14px 16px' }}>
          {s.wfRuntime.map(rt => {
            const wf = s.workflows.find(w => w.id === rt.workflowId);
            if (!wf) return null;
            const env = s.envelopes.find(e => e.id === rt.envelopeId) || { subject: rt.envelopeId };
            return (
              <div key={rt.envelopeId} style={{ padding: '12px', background: Tx.color.bg.secondary, borderRadius: '8px', marginBottom: '10px', border: `1px solid ${Tx.color.border.light}` }}>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '10px' }}>
                  <div>
                    <div style={{ fontSize: '12px', fontWeight: 700, color: Tx.color.text.primary }}>{env.subject}</div>
                    <div style={{ fontSize: '11px', color: Tx.color.text.tertiary }}>{wf.name} · started {new Date(rt.startedAt).toLocaleDateString()}</div>
                  </div>
                  <span style={{ ...es.tag, background: rt.status === 'Breached' ? es.crimsonBg : rt.status === 'At Risk' ? es.amberBg : es.emeraldBg, color: rt.status === 'Breached' ? es.crimson : rt.status === 'At Risk' ? es.amber : es.emerald }}>{rt.status}</span>
                </div>
                <div style={{ display: 'flex', gap: '6px', alignItems: 'center', flexWrap: 'wrap' }}>
                  {wf.nodes.map((n, i) => {
                    const done = wf.nodes.findIndex(x => x.id === rt.currentNode) > i;
                    const current = n.id === rt.currentNode;
                    return (
                      <React.Fragment key={n.id}>
                        <div style={{ padding: '6px 10px', borderRadius: '6px', fontSize: '11px', fontWeight: current ? 700 : 500, background: current ? es.indigoBg : done ? es.emeraldBg : Tx.color.bg.card, color: current ? es.indigo : done ? es.emerald : Tx.color.text.tertiary, border: `1px solid ${current ? es.indigo : done ? es.emerald + '55' : Tx.color.border.light}` }}>
                          {done ? 'ok ' : current ? '▸ ' : ''}{n.label}
                        </div>
                        {i < wf.nodes.length - 1 && <span style={{ color: Tx.color.text.tertiary }}>›</span>}
                      </React.Fragment>
                    );
                  })}
                  <button style={{ ...es.btnGhost, marginLeft: 'auto' }} onClick={() => window.EsStore.advanceWorkflow(rt.envelopeId)}>Advance →</button>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    );
  }
  window.EsWorkflowRuntime = EsWorkflowRuntime;

  // ──────────────────────────────────────────────────────────────────────────────
  // #9 — Extend Expiry Modal
  // ──────────────────────────────────────────────────────────────────────────────

  function EsExtendExpiryModal({ envelopeId, onClose }) {
    const es = window.__es;
    const [days, setDays] = useState(14);
    const [reason, setReason] = useState('');
    return (
      <EsModal open onClose={onClose} title="Extend envelope expiry" width={500}>
        <div style={{ fontSize: '11px', color: Tx.color.text.tertiary, marginBottom: '4px' }}>Extension length</div>
        <select value={days} onChange={e => setDays(Number(e.target.value))} style={{ width: '100%', padding: '8px 10px', fontSize: '12px', border: `1px solid ${Tx.color.border.light}`, borderRadius: '6px', marginBottom: '12px' }}>
          <option value={7}>+7 days</option><option value={14}>+14 days</option><option value={30}>+30 days</option><option value={60}>+60 days</option>
        </select>
        <div style={{ fontSize: '11px', color: Tx.color.text.tertiary, marginBottom: '4px' }}>Reason (audit log)</div>
        <textarea rows={3} value={reason} onChange={e => setReason(e.target.value)} style={{ width: '100%', padding: '8px 10px', fontSize: '12px', border: `1px solid ${Tx.color.border.light}`, borderRadius: '6px', fontFamily: Tx.font.family, resize: 'vertical', marginBottom: '14px' }} placeholder="e.g. Awaiting counterparty counsel review" />
        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: '8px' }}>
          <button style={es.btnSecondary} onClick={onClose}>Cancel</button>
          <button style={es.btnPrimary} onClick={() => { window.EsStore.extendExpiry(envelopeId, days, reason); onClose(); }}>Extend</button>
        </div>
      </EsModal>
    );
  }
  window.EsExtendExpiryModal = EsExtendExpiryModal;

  // ──────────────────────────────────────────────────────────────────────────────
  // #10 & #11 — Court Cert + Hash Chain Tree
  // ──────────────────────────────────────────────────────────────────────────────

  function EsCourtCertView({ envelopeId, onClose }) {
    const es = window.__es;
    const s = window.useEsStore();
    const cert = window.EsStore.getCert(envelopeId);
    const env = s.envelopes.find(e => e.id === envelopeId);
    if (!env) return null;

    return (
      <EsModal open onClose={onClose} title={`Court-Admissible Certificate · ${env.id}`} width={860}>
        {!cert ? (
          <div style={{ fontSize: '12px', color: Tx.color.text.tertiary, padding: '30px', textAlign: 'center' }}>
            Certificate available only for <strong>Completed</strong> envelopes. Current status: <EsStatusBadgeInline status={env.status} />
          </div>
        ) : (
          <div>
            <div style={{ padding: '14px', background: es.indigoBg, border: `1px solid ${es.indigoBorder}`, borderRadius: '8px', marginBottom: '14px' }}>
              <div style={{ fontSize: '11px', color: Tx.color.text.tertiary, marginBottom: '4px' }}>CERTIFICATE ID</div>
              <div style={{ fontFamily: Tx.font.mono, fontSize: '12px', fontWeight: 700, color: Tx.color.text.primary }}>{cert.id}</div>
              <div style={{ fontSize: '11px', color: Tx.color.text.tertiary, marginTop: '8px' }}>Generated {new Date(cert.generatedAt).toLocaleString()}</div>
            </div>

            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '12px', marginBottom: '14px' }}>
              <div style={{ ...es.card, marginBottom: 0, padding: '12px' }}>
                <div style={{ fontSize: '10px', color: Tx.color.text.tertiary, marginBottom: '4px', fontWeight: 600 }}>SHA-256 (ENVELOPE)</div>
                <div style={{ fontFamily: Tx.font.mono, fontSize: '10px', color: Tx.color.text.primary, wordBreak: 'break-all' }}>{cert.sha256}</div>
              </div>
              <div style={{ ...es.card, marginBottom: 0, padding: '12px' }}>
                <div style={{ fontSize: '10px', color: Tx.color.text.tertiary, marginBottom: '4px', fontWeight: 600 }}>SIGNING KEY</div>
                <div style={{ fontFamily: Tx.font.mono, fontSize: '10px', color: Tx.color.text.primary }}>{cert.signingKeyFingerprint}</div>
              </div>
              <div style={{ ...es.card, marginBottom: 0, padding: '12px' }}>
                <div style={{ fontSize: '10px', color: Tx.color.text.tertiary, marginBottom: '4px', fontWeight: 600 }}>TLS CIPHER</div>
                <div style={{ fontFamily: Tx.font.mono, fontSize: '11px', color: Tx.color.text.primary }}>{cert.tlsCipher}</div>
              </div>
              <div style={{ ...es.card, marginBottom: 0, padding: '12px' }}>
                <div style={{ fontSize: '10px', color: Tx.color.text.tertiary, marginBottom: '4px', fontWeight: 600 }}>EVIDENTIARY</div>
                <div style={{ fontSize: '11px', color: Tx.color.text.primary }}>{cert.evidentiary.admissibility}</div>
                <div style={{ fontSize: '10px', color: Tx.color.text.tertiary, marginTop: '2px' }}>Retention: {cert.evidentiary.retention}</div>
              </div>
            </div>

            <div style={{ fontSize: '11px', fontWeight: 700, color: Tx.color.text.primary, marginBottom: '8px', letterSpacing: '0.06em' }}>HASH CHAIN · {cert.hashChain.length} EVENTS</div>
            <div style={{ maxHeight: '260px', overflow: 'auto', border: `1px solid ${Tx.color.border.light}`, borderRadius: '6px' }}>
              <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: '10px' }}>
                <thead><tr>
                  <th style={{ ...es.th, padding: '6px 10px' }}>#</th>
                  <th style={{ ...es.th, padding: '6px 10px' }}>Time</th>
                  <th style={{ ...es.th, padding: '6px 10px' }}>Event</th>
                  <th style={{ ...es.th, padding: '6px 10px' }}>Actor</th>
                  <th style={{ ...es.th, padding: '6px 10px' }}>Hash</th>
                </tr></thead>
                <tbody>
                  {cert.hashChain.map(h => (
                    <tr key={h.seq}>
                      <td style={{ ...es.td, padding: '6px 10px', fontFamily: Tx.font.mono }}>{h.seq}</td>
                      <td style={{ ...es.td, padding: '6px 10px' }}>{new Date(h.ts).toLocaleString()}</td>
                      <td style={{ ...es.td, padding: '6px 10px' }}>{h.event}</td>
                      <td style={{ ...es.td, padding: '6px 10px' }}>{h.actor}</td>
                      <td style={{ ...es.td, padding: '6px 10px', fontFamily: Tx.font.mono, color: es.indigo }}>{h.hash}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>

            <div style={{ display: 'flex', justifyContent: 'flex-end', gap: '8px', marginTop: '14px' }}>
              <button style={es.btnSecondary} onClick={onClose}>Close</button>
              <button style={es.btnPrimary} onClick={() => { window.EsStore.exportEvidentiaryPackage(envelopeId); onClose(); }}>Export Package</button>
            </div>
          </div>
        )}
      </EsModal>
    );
  }
  // Inline mini-badge (avoid import-cycle with EsStatusBadge)
  function EsStatusBadgeInline({ status }) {
    const es = window.__es;
    const s = es.envelopeStatus(status);
    return <span style={{ ...es.tag, background: s.bg, color: s.color }}>{s.label}</span>;
  }
  window.EsCourtCertView = EsCourtCertView;

  // ──────────────────────────────────────────────────────────────────────────────
  // #12 — Notary Journal & Commission Expiry
  // ──────────────────────────────────────────────────────────────────────────────

  function EsNotaryJournal() {
    const es = window.__es;
    const s = window.useEsStore(['notary.journalAdded']);
    const [query, setQuery] = useState('');
    const [filter, setFilter] = useState('all');
    const filtered = s.notaryJournal.filter(j => {
      if (filter !== 'all' && j.method !== filter) return false;
      if (!query) return true;
      const q = query.toLowerCase();
      return [j.id, j.notary, j.act, j.state].some(v => (v || '').toLowerCase().includes(q));
    });

    return (
      <div>
        <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: '14px', marginBottom: '14px' }}>
          <div style={es.card}>
            <div style={es.cardH}>
              <span>Notary Journal ({s.notaryJournal.length})</span>
              <span style={{ display: 'inline-flex', gap: '6px' }}>
                <input value={query} onChange={e => setQuery(e.target.value)} placeholder="Search…" style={{ fontSize: '11px', padding: '4px 8px', border: `1px solid ${Tx.color.border.light}`, borderRadius: '4px', width: '140px' }} />
                <select value={filter} onChange={e => setFilter(e.target.value)} style={{ fontSize: '11px', padding: '4px 6px', border: `1px solid ${Tx.color.border.light}`, borderRadius: '4px' }}>
                  <option value="all">All methods</option><option>RON</option><option>IPEN</option><option>IPEN+Witness</option><option>In-Person</option>
                </select>
              </span>
            </div>
            <div style={{ maxHeight: '360px', overflow: 'auto' }}>
              <table style={{ width: '100%', borderCollapse: 'collapse' }}>
                <thead><tr>
                  <th style={es.th}>Journal #</th>
                  <th style={es.th}>Date</th>
                  <th style={es.th}>Notary</th>
                  <th style={es.th}>State</th>
                  <th style={es.th}>Act</th>
                  <th style={es.th}>Signers</th>
                  <th style={es.th}>Method</th>
                  <th style={es.th}>Fee</th>
                </tr></thead>
                <tbody>
                  {filtered.map(j => (
                    <tr key={j.id}>
                      <td style={es.td}><span style={{ fontFamily: Tx.font.mono, color: es.indigo }}>{j.id}</span></td>
                      <td style={es.td}>{j.date}</td>
                      <td style={es.td}>{j.notary}</td>
                      <td style={es.td}>{j.state}</td>
                      <td style={es.td}>{j.act}</td>
                      <td style={es.td}>{j.signers}</td>
                      <td style={es.td}><span style={{ ...es.tag, background: es.indigoBg, color: es.indigo }}>{j.method}</span></td>
                      <td style={es.td}><span style={{ fontFamily: Tx.font.mono }}>${j.fee.toFixed(2)}</span></td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>

          <div style={es.card}>
            <div style={es.cardH}><span>Commission Expiry</span><span style={{ fontSize: '11px', color: Tx.color.text.tertiary }}>{s.commissions.filter(c => c.daysLeft <= 90).length} expiring ≤90d</span></div>
            <div style={{ padding: '10px 14px' }}>
              {s.commissions.map(c => {
                const crit = c.daysLeft <= 30;
                const warn = c.daysLeft <= 90 && !crit;
                const color = crit ? es.crimson : warn ? es.amber : es.emerald;
                const bg = crit ? es.crimsonBg : warn ? es.amberBg : es.emeraldBg;
                return (
                  <div key={c.id} style={{ padding: '10px 12px', background: Tx.color.bg.secondary, borderRadius: '6px', marginBottom: '8px', border: `1px solid ${color}22` }}>
                    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '3px' }}>
                      <div style={{ fontSize: '12px', fontWeight: 600, color: Tx.color.text.primary }}>{c.notary}</div>
                      <span style={{ ...es.tag, background: bg, color }}>{c.daysLeft}d left</span>
                    </div>
                    <div style={{ fontSize: '11px', color: Tx.color.text.tertiary, fontFamily: Tx.font.mono }}>{c.state} · {c.number}</div>
                    <div style={{ fontSize: '10px', color: Tx.color.text.tertiary, marginTop: '2px' }}>Expires {c.expires}</div>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
      </div>
    );
  }
  window.EsNotaryJournal = EsNotaryJournal;

  // ──────────────────────────────────────────────────────────────────────────────
  // #16 — Recipient Funnel (per-envelope & field drop-off)
  // ──────────────────────────────────────────────────────────────────────────────

  function EsSignerFunnel() {
    const es = window.__es;
    const s = window.useEsStore();
    const [env, setEnv] = useState(Object.keys(s.signerFunnel)[0]);
    const f = s.signerFunnel[env] || { sent: 0, opened: 0, started: 0, completed: 0, declined: 0 };
    const stages = [
      { label: 'Sent', n: f.sent }, { label: 'Opened', n: f.opened }, { label: 'Started', n: f.started }, { label: 'Completed', n: f.completed }
    ];
    const max = Math.max(f.sent, 1);

    return (
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '14px' }}>
        <div style={es.card}>
          <div style={es.cardH}>
            <span>Recipient Funnel</span>
            <select value={env} onChange={e => setEnv(e.target.value)} style={{ fontSize: '11px', padding: '4px 6px', border: `1px solid ${Tx.color.border.light}`, borderRadius: '4px' }}>
              {Object.keys(s.signerFunnel).map(id => <option key={id}>{id}</option>)}
            </select>
          </div>
          <div style={{ padding: '14px 18px' }}>
            {stages.map((st, i) => (
              <div key={st.label} style={{ marginBottom: '10px' }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '4px' }}>
                  <span style={{ fontSize: '11px', fontWeight: 600, color: Tx.color.text.primary }}>{st.label}</span>
                  <span style={{ fontSize: '11px', color: Tx.color.text.tertiary, fontFamily: Tx.font.mono }}>{st.n} / {f.sent}</span>
                </div>
                <div style={{ height: '10px', background: Tx.color.bg.secondary, borderRadius: '5px', overflow: 'hidden' }}>
                  <div style={{ width: `${(st.n / max) * 100}%`, height: '100%', background: `linear-gradient(90deg, ${es.indigo}, ${es.indigoLight})`, transition: 'width 0.3s' }} />
                </div>
              </div>
            ))}
            <div style={{ marginTop: '10px', padding: '8px 10px', background: Tx.color.bg.secondary, borderRadius: '6px', display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '8px' }}>
              <div><div style={{ fontSize: '10px', color: Tx.color.text.tertiary }}>AVG TIME TO OPEN</div><div style={{ fontSize: '12px', fontWeight: 700 }}>{f.avgTimeToOpen || '—'}</div></div>
              <div><div style={{ fontSize: '10px', color: Tx.color.text.tertiary }}>AVG TIME TO COMPLETE</div><div style={{ fontSize: '12px', fontWeight: 700 }}>{f.avgTimeToComplete || '—'}</div></div>
            </div>
          </div>
        </div>

        <div style={es.card}>
          <div style={es.cardH}><span>Field-Level Drop-off</span><span style={{ fontSize: '11px', color: Tx.color.text.tertiary }}>{s.fieldDropoff.length} field types</span></div>
          <div style={{ padding: '14px 18px' }}>
            {s.fieldDropoff.map(fd => {
              const warn = fd.dropOffRate > 15;
              return (
                <div key={fd.field} style={{ marginBottom: '10px' }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '3px' }}>
                    <span style={{ fontSize: '11px', fontWeight: 600, color: Tx.color.text.primary }}>{fd.field}</span>
                    <span style={{ fontSize: '11px', color: warn ? es.crimson : es.emerald, fontFamily: Tx.font.mono, fontWeight: 600 }}>{fd.completion}%</span>
                  </div>
                  <div style={{ height: '8px', background: Tx.color.bg.secondary, borderRadius: '4px', overflow: 'hidden' }}>
                    <div style={{ width: `${fd.completion}%`, height: '100%', background: warn ? es.crimson : es.emerald }} />
                  </div>
                  <div style={{ fontSize: '10px', color: Tx.color.text.tertiary, marginTop: '2px' }}>Avg {fd.avgTime} · drop-off {fd.dropOffRate}%</div>
                </div>
              );
            })}
          </div>
        </div>
      </div>
    );
  }
  window.EsSignerFunnel = EsSignerFunnel;

  // ──────────────────────────────────────────────────────────────────────────────
  // #17 — Risk Trend + Batch Scan
  // ──────────────────────────────────────────────────────────────────────────────

  function EsRiskTrend() {
    const es = window.__es;
    const s = window.useEsStore(['risk.batchScanned']);
    const trend = s.riskTrend;
    const maxRisk = Math.max(...trend.map(t => t.avgRisk), 40);
    const [scanning, setScanning] = useState(false);

    function runBatch() {
      setScanning(true);
      setTimeout(() => {
        const ids = s.envelopes.filter(e => e.status !== 'Draft' && e.status !== 'Voided').slice(0, 5).map(e => e.id);
        window.EsStore.runRiskScanBatch(ids);
        setScanning(false);
      }, 600);
    }

    return (
      <div style={es.card}>
        <div style={es.cardH}>
          <span>Risk Score Trend (6 months)</span>
          <button style={{ ...es.btnPrimary, opacity: scanning ? 0.6 : 1 }} onClick={runBatch} disabled={scanning}>{scanning ? 'Scanning…' : 'Run batch scan'}</button>
        </div>
        <div style={{ padding: '16px 20px' }}>
          <div style={{ display: 'flex', alignItems: 'flex-end', gap: '14px', height: '160px', borderBottom: `1px solid ${Tx.color.border.light}`, paddingBottom: '8px' }}>
            {trend.map(t => {
              const h = (t.avgRisk / maxRisk) * 140;
              const color = t.avgRisk > 28 ? es.crimson : t.avgRisk > 24 ? es.amber : es.emerald;
              return (
                <div key={t.month} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '6px' }}>
                  <span style={{ fontSize: '11px', fontWeight: 700, color, fontFamily: Tx.font.mono }}>{t.avgRisk}</span>
                  <div style={{ width: '100%', maxWidth: '40px', height: `${h}px`, background: color + '99', borderRadius: '4px 4px 0 0' }}></div>
                  <span style={{ fontSize: '10px', color: Tx.color.text.tertiary }}>{t.month}</span>
                </div>
              );
            })}
          </div>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: '10px', marginTop: '14px' }}>
            <div style={{ padding: '10px', background: es.crimsonBg, borderRadius: '6px' }}>
              <div style={{ fontSize: '10px', color: es.crimson, fontWeight: 700, marginBottom: '2px' }}>HIGH</div>
              <div style={{ fontSize: '18px', fontWeight: 700 }}>{trend.reduce((a, t) => a + t.high, 0)}</div>
            </div>
            <div style={{ padding: '10px', background: es.amberBg, borderRadius: '6px' }}>
              <div style={{ fontSize: '10px', color: es.amber, fontWeight: 700, marginBottom: '2px' }}>MEDIUM</div>
              <div style={{ fontSize: '18px', fontWeight: 700 }}>{trend.reduce((a, t) => a + t.medium, 0)}</div>
            </div>
            <div style={{ padding: '10px', background: es.emeraldBg, borderRadius: '6px' }}>
              <div style={{ fontSize: '10px', color: es.emerald, fontWeight: 700, marginBottom: '2px' }}>LOW</div>
              <div style={{ fontSize: '18px', fontWeight: 700 }}>{trend.reduce((a, t) => a + t.low, 0)}</div>
            </div>
          </div>
        </div>
      </div>
    );
  }
  window.EsRiskTrend = EsRiskTrend;

  // ──────────────────────────────────────────────────────────────────────────────
  // #18 — Delegation Alerts & Revocation
  // ──────────────────────────────────────────────────────────────────────────────

  function EsDelegationPanel() {
    const es = window.__es;
    const s = window.useEsStore(['delegation.revoked']);
    const active = s.delegations.filter(d => d.status !== 'Revoked');
    function daysLeft(d) {
      if (!d.expires) return null;
      return Math.ceil((new Date(d.expires) - new Date()) / 86400000);
    }

    return (
      <div style={es.card}>
        <div style={es.cardH}>
          <span>Active Delegations / Power of Attorney</span>
          <span style={{ fontSize: '11px', color: Tx.color.text.tertiary }}>{active.length} active · {s.delegations.filter(d => d.status === 'Revoked').length} revoked</span>
        </div>
        <table style={{ width: '100%', borderCollapse: 'collapse' }}>
          <thead><tr>
            <th style={es.th}>Delegator</th>
            <th style={es.th}>Delegatee</th>
            <th style={es.th}>Scope</th>
            <th style={es.th}>Granted</th>
            <th style={es.th}>Expires</th>
            <th style={es.th}>Status</th>
            <th style={es.th}>Actions</th>
          </tr></thead>
          <tbody>
            {s.delegations.map(d => {
              const dl = daysLeft(d);
              const expiring = dl != null && dl <= 14 && dl >= 0;
              const expired = dl != null && dl < 0;
              const isRevoked = d.status === 'Revoked';
              return (
                <tr key={d.id}>
                  <td style={es.td}>{d.delegator}</td>
                  <td style={es.td}>{d.delegatee}</td>
                  <td style={es.td}>{d.scope}</td>
                  <td style={es.td}>{d.granted || '—'}</td>
                  <td style={es.td}>
                    <div style={{ display: 'flex', flexDirection: 'column', gap: '2px' }}>
                      <span>{d.expires || '—'}</span>
                      {dl != null && !isRevoked && (
                        <span style={{ fontSize: '10px', color: expired ? es.crimson : expiring ? es.amber : Tx.color.text.tertiary, fontWeight: 600 }}>
                          {expired ? 'EXPIRED' : expiring ? `! ${dl}d left` : `${dl}d left`}
                        </span>
                      )}
                    </div>
                  </td>
                  <td style={es.td}><span style={{ ...es.tag, background: isRevoked ? es.crimsonBg : expired ? es.slateBg : expiring ? es.amberBg : es.emeraldBg, color: isRevoked ? es.crimson : expired ? es.slate : expiring ? es.amber : es.emerald }}>{isRevoked ? 'Revoked' : expired ? 'Expired' : d.status || 'Active'}</span></td>
                  <td style={es.td}>
                    {!isRevoked && !expired ? (
                      <button style={{ ...es.btnSecondary, color: es.crimson, borderColor: es.crimson + '55' }} onClick={() => { const r = prompt('Reason for revocation?'); if (r != null) window.EsStore.revokeDelegation(d.id, r); }}>Revoke</button>
                    ) : <span style={{ fontSize: '10px', color: Tx.color.text.tertiary }}>{d.revokedAt ? 'Revoked ' + new Date(d.revokedAt).toLocaleDateString() : '—'}</span>}
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
    );
  }
  window.EsDelegationPanel = EsDelegationPanel;

  // ──────────────────────────────────────────────────────────────────────────────
  // Envelope Action Bar — extend/void/resend/cert/preview (improvements #1, #9, #10)
  // ──────────────────────────────────────────────────────────────────────────────

  function EsEnvelopeActions({ envelopeId }) {
    const es = window.__es;
    const s = window.useEsStore();
    const env = s.envelopes.find(e => e.id === envelopeId);
    const [preview, setPreview] = useState(false);
    const [extend, setExtend] = useState(false);
    const [cert, setCert] = useState(false);
    if (!env) return null;
    const canVoid = ['Draft','Sent','Waiting','Viewed'].includes(env.status);
    const canExtend = ['Sent','Waiting','Viewed','Expired'].includes(env.status);
    const canSend = env.status === 'Draft';
    const canComplete = ['Sent','Waiting','Viewed'].includes(env.status);
    const canCert = env.status === 'Completed';

    return (
      <div style={{ display: 'flex', flexWrap: 'wrap', gap: '6px', alignItems: 'center' }}>
        <button style={es.btnSecondary} onClick={() => setPreview(true)}>Preview signer flow</button>
        {canSend && <button style={es.btnPrimary} onClick={() => window.EsStore.sendEnvelope(env.id)}>Send</button>}
        {canComplete && <button style={es.btnSecondary} onClick={() => window.EsStore.completeEnvelope(env.id)}>Mark complete</button>}
        {canExtend && <button style={es.btnSecondary} onClick={() => setExtend(true)}>Extend expiry</button>}
        {canCert && <button style={{ ...es.btnPrimary, background: es.indigo }} onClick={() => setCert(true)}>Court certificate</button>}
        {canVoid && <button style={{ ...es.btnSecondary, color: es.crimson, borderColor: es.crimson + '55' }} onClick={() => { const r = prompt('Reason for voiding?'); if (r != null) window.EsStore.voidEnvelope(env.id, r); }}>Void</button>}
        {preview && <EsSignerPreview envelopeId={env.id} onClose={() => setPreview(false)} />}
        {extend && <EsExtendExpiryModal envelopeId={env.id} onClose={() => setExtend(false)} />}
        {cert && <EsCourtCertView envelopeId={env.id} onClose={() => setCert(false)} />}
      </div>
    );
  }
  window.EsEnvelopeActions = EsEnvelopeActions;

  // ──────────────────────────────────────────────────────────────────────────────
  // New Envelope modal (improvement #5 — compose scaffolding with clauses)
  // ──────────────────────────────────────────────────────────────────────────────

  function EsNewEnvelopeModal({ open, onClose }) {
    const es = window.__es;
    const s = window.useEsStore(['compose.updated', 'compose.clauseInserted', 'compose.reset']);
    const [subject, setSubject] = useState('');
    const [recipients, setRecipients] = useState('');
    if (!open) return null;

    function create() {
      const env = window.EsStore.createEnvelope({
        subject: subject || 'Untitled envelope',
        recipients: recipients.split(',').map(n => n.trim()).filter(Boolean).map(n => ({ name: n, email: n.toLowerCase().replace(/\s+/g, '.') + '@example.com', role: 'Signer' })),
        pages: 1, fields: [],
      });
      window.EsStore.sendEnvelope(env.id);
      window.EsStore.resetDraft();
      setSubject(''); setRecipients('');
      onClose();
    }

    return (
      <EsModal open title="New Envelope" onClose={onClose} width={720}>
        <div style={{ display: 'grid', gridTemplateColumns: '1.2fr 1fr', gap: '16px' }}>
          <div>
            <div style={{ fontSize: '11px', color: Tx.color.text.tertiary, marginBottom: '4px' }}>Subject</div>
            <input value={subject} onChange={e => setSubject(e.target.value)} placeholder="e.g. NDA — Acme Corp" style={{ width: '100%', padding: '8px 10px', fontSize: '12px', border: `1px solid ${Tx.color.border.light}`, borderRadius: '6px', marginBottom: '12px' }} />
            <div style={{ fontSize: '11px', color: Tx.color.text.tertiary, marginBottom: '4px' }}>Recipients (comma-separated names)</div>
            <input value={recipients} onChange={e => setRecipients(e.target.value)} placeholder="Jane Doe, John Roe" style={{ width: '100%', padding: '8px 10px', fontSize: '12px', border: `1px solid ${Tx.color.border.light}`, borderRadius: '6px', marginBottom: '12px' }} />
            <div style={{ fontSize: '11px', color: Tx.color.text.tertiary, marginBottom: '4px' }}>Inserted clauses</div>
            <div style={{ padding: '8px', background: Tx.color.bg.secondary, borderRadius: '6px', minHeight: '60px' }}>
              {(s.composeDraft.clauses || []).length === 0 ? <span style={{ fontSize: '11px', color: Tx.color.text.tertiary }}>No clauses yet — insert from right panel</span> :
                s.composeDraft.clauses.map(c => <span key={c.id} style={{ ...es.tag, background: es.indigoBg, color: es.indigo, marginRight: '4px', marginBottom: '4px', display: 'inline-block' }}>{c.name} v{c.version}</span>)}
            </div>
            <div style={{ display: 'flex', justifyContent: 'flex-end', gap: '8px', marginTop: '14px' }}>
              <button style={es.btnSecondary} onClick={() => { window.EsStore.resetDraft(); onClose(); }}>Cancel</button>
              <button style={es.btnPrimary} onClick={create} disabled={!subject.trim() || !recipients.trim()}>Create & Send</button>
            </div>
          </div>
          <div style={{ borderLeft: `1px solid ${Tx.color.border.light}`, paddingLeft: '14px' }}>
            <div style={{ fontSize: '11px', fontWeight: 700, color: Tx.color.text.primary, marginBottom: '8px', letterSpacing: '0.06em' }}>CLAUSE LIBRARY</div>
            <div style={{ maxHeight: '300px', overflow: 'auto' }}>
              {s.clauseLibrary.map(c => (
                <div key={c.id} style={{ padding: '8px 10px', background: Tx.color.bg.secondary, borderRadius: '6px', marginBottom: '6px' }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '3px' }}>
                    <span style={{ fontSize: '11px', fontWeight: 600, color: Tx.color.text.primary }}>{c.name}</span>
                    <button style={es.btnGhost} onClick={() => window.EsStore.insertClauseIntoDraft(c.id)}>+ Insert</button>
                  </div>
                  <div style={{ fontSize: '10px', color: Tx.color.text.tertiary }}>v{c.version} · {c.category}</div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </EsModal>
    );
  }
  window.EsNewEnvelopeModal = EsNewEnvelopeModal;

})();
