// ════════════ SIGNATURES · e-sign command center ════════════
// Own secondary sidebar (like Marketing/Money). Covers the full surface:
// dashboard, document list, upload + field placement, send-to-sign flow,
// audit trail, and a reusable template library. Local state only — this
// is a visual prototype, no backend calls. Documents, templates and the
// signing ceremony share module-level stores so created docs join the
// list and the ceremony's progress is reflected everywhere.
// NB: Modal lives in px-overlays.jsx which loads AFTER this file, so it is
// referenced as window.Modal (not destructured) to avoid an eval-time undefined.
const { Icon, Spark, Pex, Avatar, Card, Btn, Pill, Label, Num, Toggle, Field, TextArea, Tabs, money } = window;

// NB: these babel-in-browser scripts share one global scope, so top-level
// names must be unique ACROSS files. px-orders.jsx also declares `STAGES`,
// so ours is namespaced (SIG_*) to avoid the collision that crashes render.
const SIG_STATUS_TONE = { Draft: 'neutral', Sent: 'amber', Viewed: 'sky', Signed: 'sage', Countersigned: 'spark', Declined: 'rose', Expired: 'neutral' };
const SIG_STAGES = ['Draft', 'Invite sent', 'Viewed', 'Signed', 'Countersigned'];

// ── shared stores ────────────────────────────────────────────
// Docs carry their placed fields, recipients (+ per-signer status),
// message and a `sent` flag so the ceremony survives navigation.
const DOCS_SEED = [
  { id: 'd1', n: 'Consulting Agreement · Marcus T.', st: 'Countersigned', who: 'Marcus T.', when: 'Mar 12', pages: 4, sent: true, fields: [{ id: 'a', type: 'signature', label: 'Sign here' }, { id: 'b', type: 'date', label: 'Date' }], recipients: [{ id: 1, name: 'Marcus T.', email: 'marcus@cafelumen.com', status: 'signed' }, { id: 2, name: 'Amara (you)', email: 'amara@honestloaves.com', status: 'signed' }], message: '' },
  { id: 'd2', n: 'NDA · Priya S.', st: 'Signed', who: 'Priya S.', when: 'Mar 10', pages: 2, sent: true, fields: [{ id: 'a', type: 'signature', label: 'Sign here' }], recipients: [{ id: 1, name: 'Priya S.', email: 'priya@sunroom.design', status: 'signed' }], message: '' },
  { id: 'd3', n: 'Wholesale Supply Contract', st: 'Viewed', who: 'Café Lumen', when: 'Mar 9', pages: 6, sent: true, fields: [{ id: 'a', type: 'signature', label: 'Sign here' }, { id: 'b', type: 'initial', label: 'Initial' }], recipients: [{ id: 1, name: 'Café Lumen', email: 'orders@cafelumen.com', status: 'viewed' }], message: '' },
  { id: 'd4', n: 'W-9 · Daniel R.', st: 'Sent', who: 'Daniel R.', when: 'Mar 8', pages: 1, sent: true, fields: [{ id: 'a', type: 'signature', label: 'Sign here' }], recipients: [{ id: 1, name: 'Daniel R.', email: 'daniel.ruiz@gmail.com', status: 'invited' }], message: '' },
  { id: 'd5', n: 'Lease Amendment', st: 'Draft', who: '—', when: '—', pages: 3, sent: false, fields: [], recipients: [{ id: 1, name: '', email: '' }], message: '' },
  { id: 'd6', n: 'Vendor NDA · Milled & Co.', st: 'Declined', who: 'Milled & Co.', when: 'Mar 2', pages: 2, sent: true, fields: [{ id: 'a', type: 'signature', label: 'Sign here' }], recipients: [{ id: 1, name: 'Milled & Co.', email: 'legal@milledco.com', status: 'declined' }], message: '' },
  { id: 'd7', n: 'Class Waiver · March cohort', st: 'Expired', who: 'Group · 6', when: 'Feb 20', pages: 1, sent: true, fields: [{ id: 'a', type: 'signature', label: 'Sign here' }], recipients: [{ id: 1, name: 'March cohort', email: 'group@honestloaves.com', status: 'invited' }], message: '' },
];

const SigStore = (function () {
  const store = window.makeStore({ docs: DOCS_SEED });
  const list = () => store.get().docs;
  return Object.assign(store, {
    list,
    byId: (id) => list().find(d => d.id === id),
    createDraft: (over = {}) => {
      const id = window.pxid('doc');
      const doc = {
        id, n: 'Untitled document', st: 'Draft', who: '—', when: 'Just now', pages: 1, sent: false,
        fields: [], message: 'Hi — please review and sign the attached document at your convenience. Let me know if you have any questions.',
        recipients: [
          { id: 1, name: 'Marcus T.', email: 'marcus@cafelumen.com' },
          { id: 2, name: 'Amara (you)', email: 'amara@honestloaves.com' },
        ],
        ...over,
      };
      store.set(s => ({ ...s, docs: [doc, ...s.docs] }));
      return id;
    },
    update: (id, patch) => store.set(s => ({
      ...s, docs: s.docs.map(d => d.id === id ? { ...d, ...(typeof patch === 'function' ? patch(d) : patch) } : d),
    })),
  });
})();

// Reusable templates — shared by the library and the upload screen's pills.
const TplStore = (function () {
  const store = window.makeStore({ tpls: [
    { id: 't1', n: 'NDA', desc: 'Mutual non-disclosure agreement', icon: 'lock', tone: 'plum', used: 24, fields: [{ type: 'signature', label: 'Sign here' }, { type: 'date', label: 'Date' }] },
    { id: 't2', n: 'Consulting Agreement', desc: 'Independent contractor terms', icon: 'briefcase', tone: 'sky', used: 12, fields: [{ type: 'signature', label: 'Sign here' }, { type: 'initial', label: 'Initial' }, { type: 'date', label: 'Date' }] },
    { id: 't3', n: 'Wholesale Supply Contract', desc: 'Recurring B2B supply terms', icon: 'truck', tone: 'amber', used: 6, fields: [{ type: 'signature', label: 'Sign here' }, { type: 'date', label: 'Date' }] },
    { id: 't4', n: 'W-9', desc: 'Taxpayer identification request', icon: 'fileText', tone: 'sage', used: 31, fields: [{ type: 'signature', label: 'Sign here' }] },
    { id: 't5', n: 'Class Waiver', desc: 'Liability waiver for in-person classes', icon: 'shield', tone: 'rose', used: 48, fields: [{ type: 'signature', label: 'Sign here' }, { type: 'initial', label: 'Initial' }] },
    { id: 't6', n: 'Vendor Onboarding', desc: 'New vendor terms & W-9 bundle', icon: 'package', tone: 'spark', used: 9, fields: [{ type: 'signature', label: 'Sign here' }, { type: 'text', label: 'Tax ID' }, { type: 'date', label: 'Date' }] },
  ] });
  const list = () => store.get().tpls;
  return Object.assign(store, {
    list,
    byId: (id) => list().find(t => t.id === id),
    add: (t) => { const id = window.pxid('tpl'); store.set(s => ({ ...s, tpls: [{ id, icon: 'fileText', tone: 'spark', used: 0, fields: [{ type: 'signature', label: 'Sign here' }], ...t }, ...s.tpls] })); return id; },
    update: (id, patch) => store.set(s => ({ ...s, tpls: s.tpls.map(t => t.id === id ? { ...t, ...patch } : t) })),
    remove: (id) => store.set(s => ({ ...s, tpls: s.tpls.filter(t => t.id !== id) })),
  });
})();

const FIELD_META = {
  signature: { icon: 'penTool', tone: 'spark', label: 'Signature' },
  date: { icon: 'calendar', tone: 'sky', label: 'Date' },
  text: { icon: 'type', tone: 'amber', label: 'Text' },
  initial: { icon: 'pencil', tone: 'sage', label: 'Initial' },
};

// Status → derived stage index, and a stage/status derivation from recipients.
function deriveStatus(doc) {
  if (!doc.sent) return { st: 'Draft', idx: 0 };
  if (doc.st === 'Expired') return { st: 'Expired', idx: 1 }; // terminal, not derivable from recipients
  const rs = doc.recipients || [];
  if (rs.some(r => r.status === 'declined')) return { st: 'Declined', idx: 1 };
  const signed = rs.filter(r => r.status === 'signed').length;
  const viewed = rs.filter(r => r.status === 'viewed' || r.status === 'signed').length;
  if (signed > 0 && signed === rs.length) return rs.length > 1 ? { st: 'Countersigned', idx: 4 } : { st: 'Signed', idx: 3 };
  if (signed > 0) return { st: 'Signed', idx: 3 };
  if (viewed > 0) return { st: 'Viewed', idx: 2 };
  return { st: 'Sent', idx: 1 };
}

// Status-aware audit timeline — reflects THIS doc's actual state, not a fixed 6.
function docEvents(doc) {
  const who = doc.who && doc.who !== '—' ? doc.who : (doc.recipients && doc.recipients[0] && doc.recipients[0].name) || 'recipient';
  const w = doc.when && doc.when !== '—' ? doc.when : 'Just now';
  const ev = [{ icon: 'plus', tone: 'neutral', t: 'Document created', meta: `${(doc.fields || []).length} field(s) placed · ${(doc.recipients || []).length} recipient(s)`, when: w + ' · 9:02am' }];
  if (!doc.sent || doc.st === 'Draft') return ev;
  ev.push({ icon: 'send', tone: 'amber', t: 'Sent to ' + who, meta: 'via email · amara@honestloaves.com', when: w + ' · 9:05am' });
  if (doc.st === 'Declined') {
    ev.push({ icon: 'eye', tone: 'sky', t: 'Opened by ' + who, meta: 'IP 73.14.201.9 · Chrome on macOS', when: w + ' · 4:41pm' });
    ev.push({ icon: 'x', tone: 'rose', t: 'Declined by ' + who, meta: 'reason: sending to legal for review first', when: w + ' · 5:10pm' });
    return ev;
  }
  if (doc.st === 'Expired') {
    ev.push({ icon: 'clock', tone: 'neutral', t: 'Signing link expired', meta: 'no signer action within 14 days', when: w + ' · +14d' });
    return ev;
  }
  if (['Viewed', 'Signed', 'Countersigned'].includes(doc.st)) {
    ev.push({ icon: 'eye', tone: 'sky', t: 'Opened by ' + who, meta: 'IP 73.14.201.9 · Chrome on macOS', when: w + ' · 4:41pm' });
    ev.push({ icon: 'fileText', tone: 'sky', t: `Viewed page 1 of ${doc.pages || 1}`, meta: '38s on page', when: w + ' · 4:41pm' });
  }
  if (['Signed', 'Countersigned'].includes(doc.st)) {
    ev.push({ icon: 'penTool', tone: 'sage', t: 'Signature applied by ' + who, meta: 'field "Sign here" · IP 73.14.201.9', when: w + ' · 8:15am' });
  }
  if (doc.st === 'Countersigned') {
    ev.push({ icon: 'check', tone: 'spark', t: 'Countersigned by Honest Loaves', meta: 'IP 98.42.11.207 · Safari on macOS', when: w + ' · 8:40am' });
  }
  return ev;
}

window.SCREENS['signatures'] = function Signatures({ sub }) {
  const P = window.PX; const { go } = window.useApp();
  const docs = window.useStore(SigStore);
  const tpls = window.useStore(TplStore);
  const seg = (sub || '').split('/');
  const active = seg[0] || 'overview';
  const nav = [
    { items: [{ k: 'overview', icon: 'penTool', label: 'Overview' }] },
    { label: 'Documents', items: [
      { k: 'documents', icon: 'fileText', label: 'Documents', badge: docs.docs.length || undefined },
      { k: 'new', icon: 'upload', label: 'Upload & place fields' },
      { k: 'send', icon: 'send', label: 'Send to sign' },
    ]},
    { label: 'History', items: [
      { k: 'audit', icon: 'clipboard', label: 'Audit trail' },
    ]},
    { label: 'Library', items: [
      { k: 'templates', icon: 'layout', label: 'Templates', badge: tpls.tpls.length || undefined },
    ]},
  ];
  const pending = docs.docs.filter(d => ['Sent', 'Viewed'].includes(deriveStatus(d).st)).length;
  const onNav = (k) => go('signatures' + (k === 'overview' ? '' : '/' + k));
  return (
    <window.SubLayout title="Signatures" nav={nav} active={active} onNav={onNav}
      foot={<div style={{ background: P.sparkWash, border: `1px solid ${P.sparkTint}`, borderRadius: 10, padding: 11 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 7 }}><Pex size={18}/><span style={{ fontSize: 12, fontWeight: 600, color: P.ink }}>Pex is watching signatures</span></div>
        <div style={{ fontSize: 11, color: P.ink3, marginTop: 4 }}>{pending} document{pending === 1 ? '' : 's'} waiting on a signer · avg time-to-sign 1.4 days</div>
      </div>}>
      {active === 'overview' && <SigOverview/>}
      {active === 'documents' && <Documents/>}
      {active === 'new' && <DocumentSetup id={seg[1]}/>}
      {active === 'send' && <SendToSign id={seg[1]}/>}
      {active === 'audit' && <AuditTrail id={seg[1]}/>}
      {active === 'templates' && <TemplateLibrary/>}
    </window.SubLayout>
  );
};

const SHead = ({ title, sub, children }) => {
  const P = window.PX;
  return (
    <div style={{ display: 'flex', alignItems: 'flex-start', marginBottom: 18, gap: 12 }}>
      <div style={{ flex: 1 }}>
        <div style={{ fontFamily: P.serif, fontStyle: 'italic', fontSize: 26, color: P.ink, letterSpacing: -0.4 }}>{title}</div>
        {sub && <div style={{ fontSize: 12.5, color: P.ink3, marginTop: 2 }}>{sub}</div>}
      </div>
      {children && <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexShrink: 0 }}>{children}</div>}
    </div>
  );
};

// ── OVERVIEW ─────────────────────────────────────────────────
function SigOverview() {
  const P = window.PX; const { go } = window.useApp();
  const { docs } = window.useStore(SigStore);
  const byStatus = docs.map(d => deriveStatus(d).st);
  const count = (arr) => byStatus.filter(s => arr.includes(s)).length;
  const signed = count(['Signed', 'Countersigned']);
  const pending = count(['Sent', 'Viewed']);
  const activity = [
    { icon: 'check', tone: 'spark', t: 'Marcus T. countersigned Consulting Agreement', when: '2h ago' },
    { icon: 'check', tone: 'sage', t: 'Priya S. signed NDA', when: 'Yesterday' },
    { icon: 'eye', tone: 'sky', t: 'Café Lumen viewed Wholesale Supply Contract', when: '2 days ago' },
    { icon: 'send', tone: 'amber', t: 'Sent W-9 to Daniel R.', when: '3 days ago' },
    { icon: 'x', tone: 'rose', t: 'Milled & Co. declined Vendor NDA', when: '5 days ago' },
  ];
  const breakdown = [
    ['Countersigned', count(['Countersigned']), 'spark'],
    ['Signed', count(['Signed']), 'sage'],
    ['Viewed', count(['Viewed']), 'sky'],
    ['Sent', count(['Sent']), 'amber'],
    ['Draft/Other', count(['Draft', 'Declined', 'Expired']), 'neutral'],
  ];
  const maxB = Math.max(1, ...breakdown.map(b => b[1]));
  return (
    <div style={{ fontFamily: P.sans, padding: 22 }}>
      <SHead title="Signatures" sub="Send documents out for e-signature and track every step to close.">
        <Btn kind="default" size="sm" icon="clipboard" onClick={() => go('signatures/audit')}>Audit trail</Btn>
        <Btn kind="spark" size="sm" icon="plus" onClick={() => go('signatures/new')}>New document</Btn>
      </SHead>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4,1fr)', gap: 14, marginBottom: 14 }}>
        {[['Documents', String(docs.length), 'mail'], ['Signed', String(signed), 'check'], ['Pending', String(pending), 'clock'], ['Avg time-to-sign', '1.4 days', 'zap']].map((c, i) => (
          <Card key={i} pad={16}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}><Label>{c[0]}</Label><Icon name={c[2]} size={15} color={P.ink3}/></div>
            <Num size={26} style={{ marginTop: 6 }}>{c[1]}</Num>
          </Card>
        ))}
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 14 }}>
        <Card pad={0}>
          <div style={{ padding: '14px 18px', borderBottom: `1px solid ${P.line}`, fontSize: 14, fontWeight: 600, color: P.ink }}>Recent activity</div>
          {activity.map((a, i) => (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '13px 18px', borderBottom: i < activity.length - 1 ? `1px solid ${P.line}` : 'none' }}>
              <div style={{ width: 30, height: 30, borderRadius: 8, background: P[a.tone + 'Tint'] || P.sunk, color: P[a.tone] || P.ink2, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                <Icon name={a.icon} size={14}/>
              </div>
              <span style={{ flex: 1, fontSize: 13, color: P.ink }}>{a.t}</span>
              <span style={{ fontSize: 11.5, color: P.ink3 }}>{a.when}</span>
            </div>
          ))}
        </Card>
        <Card pad={18}>
          <div style={{ fontSize: 14, fontWeight: 600, color: P.ink, marginBottom: 12 }}>Status breakdown</div>
          {breakdown.map((s, i) => (
            <div key={i} style={{ marginBottom: 11 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12.5, color: P.ink2, marginBottom: 4 }}><span>{s[0]}</span><span style={{ fontFamily: P.mono }}>{s[1]}</span></div>
              <div style={{ height: 8, background: P.sunk, borderRadius: 6, overflow: 'hidden' }}><div style={{ width: (s[1] / maxB * 100) + '%', height: '100%', background: P[s[2]] || P.ink4 }}/></div>
            </div>
          ))}
        </Card>
      </div>
    </div>
  );
}

// ── DOCUMENTS ────────────────────────────────────────────────
function Documents() {
  const P = window.PX; const { go } = window.useApp();
  const { docs } = window.useStore(SigStore);
  const [q, setQ] = React.useState('');
  const [tab, setTab] = React.useState('all');
  const withSt = docs.map(d => ({ ...d, st: deriveStatus(d).st }));
  const inTab = (d) => tab === 'all' ? true : tab === 'pending' ? ['Sent', 'Viewed'].includes(d.st)
    : tab === 'signed' ? ['Signed', 'Countersigned'].includes(d.st) : ['Draft', 'Declined', 'Expired'].includes(d.st);
  const tabs = [
    { k: 'all', label: 'All', count: withSt.length },
    { k: 'pending', label: 'Pending', count: withSt.filter(d => ['Sent', 'Viewed'].includes(d.st)).length },
    { k: 'signed', label: 'Signed', count: withSt.filter(d => ['Signed', 'Countersigned'].includes(d.st)).length },
    { k: 'other', label: 'Other', count: withSt.filter(d => ['Draft', 'Declined', 'Expired'].includes(d.st)).length },
  ];
  const list = withSt.filter(d => inTab(d) && d.n.toLowerCase().includes(q.toLowerCase()));
  return (
    <div style={{ fontFamily: P.sans, padding: 22 }}>
      <SHead title="Documents" sub="Every document you've sent for signature, in one place.">
        <Btn kind="spark" size="sm" icon="plus" onClick={() => go('signatures/new')}>New document</Btn>
      </SHead>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 4 }}>
        <div style={{ flex: 1 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, background: P.card, border: `1px solid ${P.lineStrong}`, borderRadius: P.rCtl, padding: '8px 11px', maxWidth: 320 }}>
            <Icon name="search" size={15} color={P.ink3}/>
            <input value={q} onChange={e => setQ(e.target.value)} placeholder="Search documents…" style={{ flex: 1, border: 'none', background: 'transparent', outline: 'none', fontSize: 13, color: P.ink, fontFamily: P.sans }}/>
          </div>
        </div>
      </div>
      <Tabs tabs={tabs} active={tab} onChange={setTab} style={{ marginTop: 12 }}/>
      <Card pad={0} style={{ marginTop: 4 }}>
        <div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr 1fr 90px 30px', gap: 12, padding: '12px 18px', borderBottom: `1px solid ${P.line}` }}>
          {['Document', 'Signer', 'Status', 'Updated', ''].map((h, i) => <Label key={i}>{h}</Label>)}
        </div>
        {list.length === 0 && <div style={{ padding: 24, textAlign: 'center', fontSize: 12.5, color: P.ink3 }}>No documents match.</div>}
        {list.map((d, i) => (
          <div key={d.id} onClick={() => go('signatures/audit/' + d.id)} style={{ display: 'grid', gridTemplateColumns: '2fr 1fr 1fr 90px 30px', gap: 12, padding: '13px 18px', borderBottom: i < list.length - 1 ? `1px solid ${P.line}` : 'none', alignItems: 'center', cursor: 'pointer' }}
            onMouseEnter={e => e.currentTarget.style.background = P.hover} onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
              <Icon name="fileText" size={15} color={P.ink3}/>
              <span style={{ fontSize: 13.5, color: P.ink, fontWeight: 500 }}>{d.n}</span>
            </div>
            <span style={{ fontSize: 12.5, color: P.ink3 }}>{d.who}</span>
            <span><Pill tone={SIG_STATUS_TONE[d.st]} style={{ fontSize: 10 }}>{d.st}</Pill></span>
            <span style={{ fontSize: 12, color: P.ink3, fontFamily: P.mono }}>{d.when}</span>
            <Icon name="chevR" size={15} color={P.ink4}/>
          </div>
        ))}
      </Card>
    </div>
  );
}

// ── DOCUMENT UPLOAD + FIELD PLACEMENT ───────────────────────
function DocumentSetup({ id }) {
  const P = window.PX; const { go, toast } = window.useApp();
  const { tpls } = window.useStore(TplStore);
  const existing = id ? SigStore.byId(id) : null;
  const [createdId, setCreatedId] = React.useState(existing ? existing.id : null);
  const [uploaded, setUploaded] = React.useState(!!existing);
  const [captured, setCaptured] = React.useState(existing ? existing.n : '');
  const [docName, setDocName] = React.useState(existing ? existing.n : 'Untitled document');
  const [fields, setFields] = React.useState(existing && existing.fields.length
    ? existing.fields.map(f => ({ ...f, id: window.pxid('f'), x: f.x ?? 60, y: f.y ?? 340 }))
    : [
      { id: 'f1', type: 'signature', x: 60, y: 340, label: 'Sign here' },
      { id: 'f2', type: 'date', x: 260, y: 340, label: 'Date' },
    ]);
  const [tool, setTool] = React.useState('signature');

  const addField = (e) => {
    const rect = e.currentTarget.getBoundingClientRect();
    const x = Math.round(e.clientX - rect.left);
    const y = Math.round(e.clientY - rect.top);
    setFields(fs => [...fs, { id: window.pxid('f'), type: tool, x: Math.max(4, x - 46), y: Math.max(4, y - 14), label: (FIELD_META[tool] || FIELD_META.text).label }]);
  };
  const removeField = (fid, e) => { e.stopPropagation(); setFields(fs => fs.filter(f => f.id !== fid)); };

  // Simulated capture — no real file is read; the dropzone click sets a
  // captured filename and moves on to field placement.
  const captureFile = (name) => {
    const clean = name.replace(/\.[^.]+$/, '');
    setCaptured(name);
    setDocName(clean || 'Untitled document');
    setUploaded(true);
    toast(`"${name}" uploaded — place fields below.`, { icon: 'check', tone: 'sage' });
  };
  const loadTemplate = (t) => {
    setFields(t.fields.map((f, i) => ({ id: window.pxid('f'), type: f.type, label: f.label, x: 60 + (i % 3) * 150, y: 340 + Math.floor(i / 3) * 60 })));
    setCaptured(t.n + ' (template)');
    setDocName(t.n);
    setUploaded(true);
    toast(`Loaded "${t.n}" template — ${t.fields.length} field(s) placed.`, { icon: 'sparkles' });
  };
  const continueToSend = () => {
    let did = createdId;
    const payload = { n: docName || 'Untitled document', fields: fields.map(f => ({ id: f.id, type: f.type, label: f.label, x: f.x, y: f.y })) };
    if (did && SigStore.byId(did)) SigStore.update(did, payload);
    else { did = SigStore.createDraft(payload); setCreatedId(did); }
    toast(`${fields.length} field(s) placed. Ready to send.`, { icon: 'check', tone: 'sage' });
    go('signatures/send/' + did);
  };

  if (!uploaded) {
    return (
      <div style={{ fontFamily: P.sans, padding: 22 }}>
        <SHead title="Upload document" sub="Add a document to prepare it for signature." />
        <Card pad={0} style={{ maxWidth: 640 }}>
          <div onClick={() => captureFile('agreement.pdf')}
            style={{ margin: 22, border: `1.5px dashed ${P.lineStrong}`, borderRadius: 12, padding: '48px 20px', textAlign: 'center', cursor: 'pointer', background: P.sunk }}
            onMouseEnter={e => e.currentTarget.style.borderColor = P.spark} onMouseLeave={e => e.currentTarget.style.borderColor = P.lineStrong}>
            <div style={{ width: 46, height: 46, borderRadius: 12, background: P.sparkTint, color: P.sparkDim, display: 'flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 14px' }}>
              <Icon name="upload" size={20}/>
            </div>
            <div style={{ fontSize: 14, fontWeight: 600, color: P.ink }}>Drop a file here, or click to browse</div>
            <div style={{ fontSize: 12, color: P.ink3, marginTop: 5 }}>PDF, DOCX up to 25MB — we capture the file name; contents stay on your device in this mock</div>
          </div>
          <div style={{ padding: '0 22px 22px' }}>
            <Label style={{ marginBottom: 8 }}>Or start from a template</Label>
            <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
              {tpls.slice(0, 4).map(t => (
                <Pill key={t.id} tone="outline" style={{ cursor: 'pointer', padding: '5px 10px' }} onClick={() => loadTemplate(t)}>{t.n}</Pill>
              ))}
            </div>
          </div>
        </Card>
      </div>
    );
  }

  return (
    <div style={{ fontFamily: P.sans, padding: 22 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 18 }}>
        <Btn kind="ghost" size="sm" icon="chevL" onClick={() => setUploaded(false)}>Upload</Btn>
        <div style={{ flex: 1 }}>
          <div style={{ fontFamily: P.serif, fontStyle: 'italic', fontSize: 24, color: P.ink }}>Place fields</div>
          <div style={{ fontSize: 11.5, color: P.ink3 }}>{captured ? captured + ' · ' : ''}Pick a field type, then click the page to drop it</div>
        </div>
        <Pill tone="sage" dot>Auto-saved</Pill>
        <Btn kind="spark" size="sm" icon="send" onClick={continueToSend}>Continue to send</Btn>
      </div>
      <Card pad={12} style={{ marginBottom: 14, maxWidth: 480 + 240 + 20 }}>
        <Field label="Document name" value={docName} onChange={setDocName} placeholder="Name this document"/>
      </Card>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 240px', gap: 20, alignItems: 'start' }}>
        <div style={{ display: 'flex', justifyContent: 'center' }}>
          <div onClick={addField} style={{ position: 'relative', width: 480, height: 620, background: '#fff', border: `1px solid ${P.line}`, borderRadius: 8, boxShadow: P.shLg, cursor: 'crosshair', overflow: 'hidden' }}>
            <div style={{ padding: '18px 24px' }}>
              <div style={{ height: 10, width: '60%', background: P.sunk, borderRadius: 3, marginBottom: 10 }}/>
              <div style={{ height: 7, width: '90%', background: P.sunk, borderRadius: 3, marginBottom: 6 }}/>
              <div style={{ height: 7, width: '85%', background: P.sunk, borderRadius: 3, marginBottom: 6 }}/>
              <div style={{ height: 7, width: '70%', background: P.sunk, borderRadius: 3 }}/>
            </div>
            {fields.map(f => {
              const m = FIELD_META[f.type] || FIELD_META.text;
              return (
                <div key={f.id} onClick={e => e.stopPropagation()} style={{ position: 'absolute', left: f.x, top: f.y, display: 'flex', alignItems: 'center', gap: 6,
                  padding: '6px 9px', borderRadius: 7, background: P[m.tone + 'Wash'] || P.sunk, border: `1.5px dashed ${P[m.tone] || P.ink3}`, color: P[m.tone] || P.ink2, fontSize: 11.5, fontWeight: 600 }}>
                  <Icon name={m.icon} size={13}/><span>{f.label}</span>
                  <span onClick={e => removeField(f.id, e)} style={{ cursor: 'pointer', opacity: 0.6, marginLeft: 2 }}><Icon name="x" size={11}/></span>
                </div>
              );
            })}
            <div style={{ position: 'absolute', bottom: 10, right: 14, fontSize: 10.5, color: P.ink4 }}>Page 1 of 1 · click to place a field</div>
          </div>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <Card pad={16}>
            <Label style={{ marginBottom: 10 }}>Field type</Label>
            {Object.keys(FIELD_META).map(k => {
              const m = FIELD_META[k]; const on = tool === k;
              return (
                <div key={k} onClick={() => setTool(k)} style={{ display: 'flex', alignItems: 'center', gap: 9, padding: '9px 10px', borderRadius: 9, marginBottom: 6, cursor: 'pointer',
                  background: on ? P.sparkWash : P.sunk, border: `1px solid ${on ? P.sparkTint : P.line}` }}>
                  <Icon name={m.icon} size={15} color={on ? P.spark : P.ink3}/>
                  <span style={{ fontSize: 12.5, color: P.ink, fontWeight: on ? 600 : 500 }}>{m.label}</span>
                </div>
              );
            })}
          </Card>
          <Card pad={16}>
            <Label style={{ marginBottom: 8 }}>Fields on page</Label>
            {fields.length === 0 && <div style={{ fontSize: 12, color: P.ink3 }}>None yet — click the page.</div>}
            {fields.map(f => (
              <div key={f.id} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '5px 0', fontSize: 12, color: P.ink2 }}>
                <Icon name={(FIELD_META[f.type] || FIELD_META.text).icon} size={12} color={P.ink3}/><span style={{ flex: 1 }}>{f.label}</span>
                <span onClick={e => removeField(f.id, e)} style={{ cursor: 'pointer', color: P.ink4 }}><Icon name="x" size={12}/></span>
              </div>
            ))}
          </Card>
        </div>
      </div>
    </div>
  );
}

// ── SEND-TO-SIGN FLOW ────────────────────────────────────────
const RSTATUS_TONE = { invited: 'amber', viewed: 'sky', signed: 'sage', declined: 'rose' };
const RSTATUS_LABEL = { invited: 'Invited', viewed: 'Viewed', signed: 'Signed', declined: 'Declined' };
const emailOk = (e) => /.+@.+\..+/.test((e || '').trim());

function SendToSign({ id }) {
  const P = window.PX; const { toast, go } = window.useApp();
  window.useStore(SigStore);
  const [docId, setDocId] = React.useState(id && SigStore.byId(id) ? id : null);
  React.useEffect(() => {
    if (docId && SigStore.byId(docId)) return;
    const draft = SigStore.list().find(d => !d.sent);
    setDocId(draft ? draft.id : SigStore.createDraft({}));
  }, []);
  const doc = docId ? SigStore.byId(docId) : null;
  const [ordered, setOrdered] = React.useState(true);
  if (!doc) return <div style={{ fontFamily: P.sans, padding: 22, color: P.ink3 }}>Preparing document…</div>;

  const recipients = doc.recipients || [];
  const { st, idx } = deriveStatus(doc);
  const setRecipients = (fn) => SigStore.update(docId, d => ({ ...d, recipients: fn(d.recipients || []) }));
  const patchDoc = (patch) => SigStore.update(docId, patch);

  const addRecipient = () => setRecipients(r => [...r, { id: window.pxid('r'), name: '', email: '' }]);
  const removeRecipient = (rid) => setRecipients(r => r.filter(x => x.id !== rid));
  const editRecipient = (rid, key, v) => setRecipients(r => r.map(x => x.id === rid ? { ...x, [key]: v } : x));

  const send = () => {
    const named = recipients.filter(r => (r.name || '').trim() || (r.email || '').trim());
    if (named.length === 0) { toast('Add at least one recipient before sending.', { tone: 'rose', icon: 'alert' }); return; }
    const bad = named.find(r => !(r.name || '').trim() || !emailOk(r.email));
    if (bad) { toast('Every recipient needs a name and a valid email.', { tone: 'rose', icon: 'alert' }); return; }
    patchDoc(d => ({
      ...d, sent: true, when: 'Just now', who: named[0].name, st: 'Sent',
      recipients: named.map(r => ({ ...r, status: 'invited' })),
    }));
    toast(`Sent to ${named.length} recipient(s).`, { icon: 'send', tone: 'sage' });
  };

  // Ceremony: advance one signer through invite → viewed → signed.
  const act = (rid, next) => {
    setRecipients(r => r.map(x => x.id === rid ? { ...x, status: next } : x));
    const rec = recipients.find(x => x.id === rid);
    const after = recipients.map(x => x.id === rid ? { ...x, status: next } : x);
    const derived = deriveStatus({ ...doc, recipients: after });
    patchDoc(d => ({ ...d, st: derived.st, who: (after[0] && after[0].name) || d.who }));
    if (next === 'viewed') toast(`${rec.name || 'Signer'} opened the document.`, { icon: 'eye', tone: 'sky' });
    if (next === 'signed') {
      const allSigned = after.every(x => x.status === 'signed');
      toast(allSigned ? `Complete — ${derived.st}.` : `${rec.name || 'Signer'} signed.`, { icon: 'check', tone: 'sage' });
    }
  };

  const activeIdx = recipients.findIndex(r => r.status !== 'signed' && r.status !== 'declined');
  const fields = doc.fields || [];

  return (
    <div style={{ fontFamily: P.sans, padding: 22 }}>
      <SHead title="Send to sign" sub="Add signers, write a note, and send — then track it through to close.">
        {!doc.sent
          ? <Btn kind="spark" size="sm" icon="send" onClick={send}>Send</Btn>
          : <Pill tone={SIG_STATUS_TONE[st]} dot>{st}</Pill>}
      </SHead>
      <div style={{ display: 'flex', alignItems: 'center', gap: 9, marginBottom: 14, padding: '10px 14px', background: P.sunk, borderRadius: 10 }}>
        <Icon name="fileText" size={15} color={P.ink3}/>
        <span style={{ fontSize: 13, fontWeight: 600, color: P.ink, flex: 1 }}>{doc.n}</span>
        <span style={{ fontSize: 11.5, color: P.ink3 }}>{fields.length} field{fields.length === 1 ? '' : 's'} placed</span>
        {fields.slice(0, 4).map((f, i) => { const m = FIELD_META[f.type] || FIELD_META.text; return <span key={i} title={f.label} style={{ color: P[m.tone] || P.ink3 }}><Icon name={m.icon} size={13}/></span>; })}
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 340px', gap: 20, alignItems: 'start' }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <Card pad={16}>
            <div style={{ display: 'flex', alignItems: 'center', marginBottom: 10 }}>
              <Label>Recipients</Label><div style={{ flex: 1 }}/>
              {!doc.sent && <React.Fragment><span style={{ fontSize: 11, color: P.ink3, marginRight: 6 }}>Signing order</span><Toggle on={ordered} size="sm" onClick={() => setOrdered(v => !v)}/></React.Fragment>}
            </div>
            {recipients.map((r, i) => (
              <div key={r.id} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '8px 0', borderBottom: i < recipients.length - 1 ? `1px solid ${P.line}` : 'none' }}>
                {ordered && <span style={{ width: 20, height: 20, borderRadius: 20, background: P.sunk, color: P.ink3, fontSize: 11, fontWeight: 600, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>{i + 1}</span>}
                <Avatar name={r.name || '?'} size={26}/>
                {!doc.sent ? (
                  <React.Fragment>
                    <input value={r.name} onChange={e => editRecipient(r.id, 'name', e.target.value)} placeholder="Name"
                      style={{ width: 130, border: `1px solid ${P.line}`, borderRadius: 7, padding: '6px 8px', fontSize: 12, color: P.ink, fontFamily: P.sans, background: P.card, outline: 'none' }}/>
                    <input value={r.email} onChange={e => editRecipient(r.id, 'email', e.target.value)} placeholder="email@company.com"
                      style={{ flex: 1, border: `1px solid ${P.line}`, borderRadius: 7, padding: '6px 8px', fontSize: 12, color: P.ink, fontFamily: P.sans, background: P.card, outline: 'none' }}/>
                    <span onClick={() => removeRecipient(r.id)} style={{ cursor: 'pointer', color: P.ink4, padding: 4 }}><Icon name="x" size={13}/></span>
                  </React.Fragment>
                ) : (
                  <React.Fragment>
                    <div style={{ flex: 1 }}>
                      <div style={{ fontSize: 12.5, color: P.ink, fontWeight: 500 }}>{r.name}</div>
                      <div style={{ fontSize: 11, color: P.ink3 }}>{r.email}</div>
                    </div>
                    <Pill tone={RSTATUS_TONE[r.status] || 'neutral'} style={{ fontSize: 10 }}>{RSTATUS_LABEL[r.status] || 'Invited'}</Pill>
                    {r.status === 'invited' && (!ordered || i === activeIdx) && <Btn kind="default" size="sm" icon="eye" onClick={() => act(r.id, 'viewed')}>Open</Btn>}
                    {r.status === 'viewed' && (!ordered || i === activeIdx) && <Btn kind="spark" size="sm" icon="penTool" onClick={() => act(r.id, 'signed')}>Sign</Btn>}
                  </React.Fragment>
                )}
              </div>
            ))}
            {!doc.sent && <Btn kind="ghost" size="sm" icon="userPlus" onClick={addRecipient} style={{ marginTop: 6 }}>Add recipient</Btn>}
            {doc.sent && activeIdx === -1 && st !== 'Declined' && <div style={{ marginTop: 10, fontSize: 12, color: P.sage, fontWeight: 500 }}>All signers complete — document {st.toLowerCase()}.</div>}
          </Card>
          <Card pad={16}>
            <Label style={{ marginBottom: 8 }}>Message</Label>
            <textarea value={doc.message} onChange={e => patchDoc({ message: e.target.value })} rows={4} disabled={doc.sent}
              style={{ width: '100%', border: `1px solid ${P.line}`, borderRadius: 8, padding: '9px 11px', fontSize: 12.5, color: P.ink, fontFamily: P.sans, background: doc.sent ? P.sunk : P.card, outline: 'none', resize: 'vertical' }}/>
          </Card>
        </div>
        <Card pad={18}>
          <div style={{ fontSize: 14, fontWeight: 600, color: P.ink, marginBottom: 14 }}>Status</div>
          {SIG_STAGES.map((s, i) => {
            const done = i <= idx;
            return (
              <div key={s} style={{ display: 'flex', alignItems: 'flex-start', gap: 10 }}>
                <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
                  <div style={{ width: 22, height: 22, borderRadius: 22, background: done ? P.sage : P.sunk, color: done ? '#fff' : P.ink4, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                    {done ? <Icon name="check" size={12} stroke={2.5}/> : <span style={{ fontSize: 10, fontWeight: 600 }}>{i + 1}</span>}
                  </div>
                  {i < SIG_STAGES.length - 1 && <div style={{ width: 2, height: 26, background: i < idx ? P.sage : P.line }}/>}
                </div>
                <div style={{ paddingTop: 2, paddingBottom: 14 }}>
                  <div style={{ fontSize: 12.5, fontWeight: done ? 600 : 500, color: done ? P.ink : P.ink3 }}>{s}</div>
                </div>
              </div>
            );
          })}
          <div style={{ fontSize: 11.5, color: P.ink3, marginTop: 2, lineHeight: 1.5 }}>
            {!doc.sent ? 'Send the document to begin. Each signer opens then signs — you drive the ceremony below.'
              : activeIdx === -1 ? 'Every signer has completed. A finished copy sits in your Documents list.'
              : `Waiting on ${(recipients[activeIdx] && recipients[activeIdx].name) || 'a signer'} to ${recipients[activeIdx] && recipients[activeIdx].status === 'viewed' ? 'sign' : 'open'}.`}
          </div>
          {doc.sent && activeIdx === -1 && <Btn kind="default" size="sm" full icon="fileText" style={{ marginTop: 12 }} onClick={() => go('signatures/audit/' + docId)}>View audit trail</Btn>}
        </Card>
      </div>
    </div>
  );
}

// ── AUDIT TRAIL ──────────────────────────────────────────────
function AuditTrail({ id }) {
  const P = window.PX; const { go, toast } = window.useApp();
  const { docs } = window.useStore(SigStore);
  const raw = SigStore.byId(id) || docs[0];
  const doc = raw ? { ...raw, st: deriveStatus(raw).st } : null;
  const [exporting, setExporting] = React.useState(false);
  if (!doc) return <div style={{ fontFamily: P.sans, padding: 22, color: P.ink3 }}>No documents yet.</div>;
  const events = docEvents(doc);
  const exportPdf = () => {
    setExporting(true);
    setTimeout(() => { setExporting(false); toast('Audit certificate exported (PDF).', { icon: 'download', tone: 'sage' }); }, 900);
  };
  return (
    <div style={{ fontFamily: P.sans, padding: 22 }}>
      <SHead title="Audit trail" sub={doc.n + ' · a complete, timestamped record of every event.'}>
        <Btn kind="default" size="sm" icon="fileText" onClick={() => go('signatures/documents')}>All documents</Btn>
        <Btn kind="default" size="sm" icon="download" loading={exporting} onClick={exportPdf}>Export PDF</Btn>
      </SHead>
      <div style={{ display: 'grid', gridTemplateColumns: '260px 1fr', gap: 18 }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {docs.map(d0 => {
            const d = { ...d0, st: deriveStatus(d0).st };
            const on = d.id === doc.id;
            return (
              <Card key={d.id} pad={13} onClick={() => go('signatures/audit/' + d.id)} hover style={{ cursor: 'pointer', border: `1.5px solid ${on ? P.spark : P.line}`, background: on ? P.sparkWash : P.card }}>
                <div style={{ fontSize: 12.5, fontWeight: 600, color: P.ink }}>{d.n}</div>
                <div style={{ marginTop: 6 }}><Pill tone={SIG_STATUS_TONE[d.st]} style={{ fontSize: 10 }}>{d.st}</Pill></div>
              </Card>
            );
          })}
        </div>
        <Card pad={0}>
          <div style={{ padding: '14px 18px', borderBottom: `1px solid ${P.line}`, display: 'flex', alignItems: 'center', gap: 9 }}>
            <Icon name="fileText" size={16} color={P.ink3}/>
            <span style={{ fontSize: 14, fontWeight: 600, color: P.ink, flex: 1 }}>{doc.n}</span>
            <Pill tone={SIG_STATUS_TONE[doc.st]}>{doc.st}</Pill>
          </div>
          <div style={{ padding: '18px 22px' }}>
            {events.map((e, i) => (
              <div key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 12 }}>
                <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
                  <div style={{ width: 28, height: 28, borderRadius: 8, background: P[e.tone + 'Tint'] || P.sunk, color: P[e.tone] || P.ink2, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
                    <Icon name={e.icon} size={13}/>
                  </div>
                  {i < events.length - 1 && <div style={{ width: 2, flex: 1, minHeight: 22, background: P.line }}/>}
                </div>
                <div style={{ paddingBottom: 20, flex: 1 }}>
                  <div style={{ fontSize: 13, color: P.ink, fontWeight: 500 }}>{e.t}</div>
                  <div style={{ fontSize: 11.5, color: P.ink3, marginTop: 2, fontFamily: P.mono }}>{e.meta}</div>
                  <div style={{ fontSize: 11, color: P.ink4, marginTop: 2 }}>{e.when}</div>
                </div>
              </div>
            ))}
          </div>
        </Card>
      </div>
    </div>
  );
}

// ── TEMPLATE LIBRARY ─────────────────────────────────────────
function TemplateLibrary() {
  const P = window.PX; const { go, toast } = window.useApp();
  const { tpls } = window.useStore(TplStore);
  const [editing, setEditing] = React.useState(null); // { id?, n, desc }
  const blank = { n: '', desc: '' };

  const useTemplate = (t) => {
    const id = SigStore.createDraft({ n: t.n, fields: (t.fields || []).map(f => ({ id: window.pxid('f'), type: f.type, label: f.label, x: 60, y: 340 })) });
    TplStore.update(t.id, { used: (t.used || 0) + 1 });
    toast(`Starting send-to-sign from "${t.n}".`, { icon: 'sparkles' });
    go('signatures/send/' + id);
  };
  const saveTemplate = () => {
    const name = (editing.n || '').trim();
    if (!name) { toast('Give the template a name.', { tone: 'rose', icon: 'alert' }); return; }
    if (editing.id) { TplStore.update(editing.id, { n: name, desc: editing.desc }); toast('Template updated.', { icon: 'check', tone: 'sage' }); }
    else { TplStore.add({ n: name, desc: editing.desc || 'Custom document template' }); toast('Template created.', { icon: 'check', tone: 'sage' }); }
    setEditing(null);
  };
  const deleteTemplate = (t) => { TplStore.remove(t.id); toast(`Deleted "${t.n}".`, { icon: 'trash' }); };

  return (
    <div style={{ fontFamily: P.sans, padding: 22 }}>
      <SHead title="Templates" sub="Reusable documents — start a send-to-sign flow already filled in.">
        <Btn kind="spark" size="sm" icon="plus" onClick={() => setEditing({ ...blank })}>New template</Btn>
      </SHead>
      {tpls.length === 0 && <Card pad={30} style={{ textAlign: 'center', color: P.ink3, fontSize: 13 }}>No templates yet — create one to get started.</Card>}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 14 }}>
        {tpls.map(t => (
          <Card key={t.id} pad={0} hover>
            <div style={{ height: 110, background: P[t.tone + 'Wash'] || P.sunk, display: 'flex', alignItems: 'center', justifyContent: 'center', position: 'relative' }}>
              <div style={{ width: 44, height: 44, borderRadius: 12, background: P[t.tone + 'Tint'] || P.sunk, color: P[t.tone] || P.ink2, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <Icon name={t.icon} size={20}/>
              </div>
              <div style={{ position: 'absolute', top: 8, right: 8, display: 'flex', gap: 4 }}>
                <span onClick={() => setEditing({ id: t.id, n: t.n, desc: t.desc })} title="Edit" style={{ width: 26, height: 26, borderRadius: 7, background: P.card, border: `1px solid ${P.line}`, display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', color: P.ink3 }}><Icon name="pencil" size={13}/></span>
                <span onClick={() => deleteTemplate(t)} title="Delete" style={{ width: 26, height: 26, borderRadius: 7, background: P.card, border: `1px solid ${P.line}`, display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', color: P.rose }}><Icon name="trash" size={13}/></span>
              </div>
            </div>
            <div style={{ padding: '14px 16px' }}>
              <div style={{ fontSize: 14, fontWeight: 600, color: P.ink }}>{t.n}</div>
              <div style={{ fontSize: 12, color: P.ink3, marginTop: 3, lineHeight: 1.4 }}>{t.desc}</div>
              <div style={{ display: 'flex', alignItems: 'center', marginTop: 12 }}>
                <span style={{ fontSize: 11, color: P.ink4, flex: 1 }}>Used {t.used}× · {(t.fields || []).length} field{(t.fields || []).length === 1 ? '' : 's'}</span>
                <Btn kind="default" size="sm" onClick={() => useTemplate(t)}>Use template</Btn>
              </div>
            </div>
          </Card>
        ))}
      </div>

      {editing && (
        <window.Modal title={editing.id ? 'Edit template' : 'New template'} sub="Templates prefill a send-to-sign flow." onClose={() => setEditing(null)}
          foot={<React.Fragment>
            <Btn kind="ghost" size="sm" onClick={() => setEditing(null)}>Cancel</Btn>
            <Btn kind="spark" size="sm" icon="check" onClick={saveTemplate}>{editing.id ? 'Save changes' : 'Create template'}</Btn>
          </React.Fragment>}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            <Field label="Template name" value={editing.n} onChange={v => setEditing(e => ({ ...e, n: v }))} placeholder="e.g. Photography release"/>
            <TextArea label="Description" value={editing.desc} onChange={v => setEditing(e => ({ ...e, desc: v }))} rows={3} placeholder="What is this document for?"/>
          </div>
        </window.Modal>
      )}
    </div>
  );
}
