// ── add-agreement-modal.jsx ──────────────────────────────────────
// Global "+ NEW AGREEMENT" wizard. Triggered by:
//   window.dispatchEvent(new CustomEvent('astro-add-agreement'))
//
// Agreement = the contract that binds parties + territories + works/recordings.
// Match-back to the rich AGREEMENTS data shape in screens3.jsx so newly-created
// rows render correctly in both AgreementsView and ScreenAgreement detail.
//
// Steps:
//   1 TYPE       — agreement_type (Co-pub, Admin, Sub-pub, Distribution, Sync, etc.)
//   2 PARTIES    — at least 2 (Assignor / Assignee or similar), pulled from
//                  Profiles / Publishers / Labels with role + IPI
//   3 TERMS      — start, end, term length, auto-renew, retention, advance,
//                  CWR record type, society agreement #
//   4 TERRITORY  — World / specific list, rights captured (Mech / Perf / Sync),
//                  collection share, ownership share, exclusions
//   5 WORKS      — pick existing works/recordings included under this deal
//                  (multi-select from catalog; can leave empty for blanket)
//   6 CONFIRM    — review summary; assigns AG-YYYY-NNNN id and inserts into
//                  window.AGREEMENTS so it appears in the catalog tab.
// ──────────────────────────────────────────────────────────────────

const { useState: useAgS, useEffect: useAgE, useMemo: useAgM } = React;

// ── Helpers ─────────────────────────────────────────────────────
function _agToday() {
  return new Date().toISOString().slice(0, 10);
}
function _agAddYears(iso, years) {
  if (!iso) return '';
  const d = new Date(iso);
  d.setFullYear(d.getFullYear() + years);
  return d.toISOString().slice(0, 10);
}
function _agNextId() {
  const yr = new Date().getFullYear();
  const list = window.AGREEMENTS || [];
  const ids = list.map(a => a.id).filter(Boolean);
  let n = 1;
  while (ids.includes(`AG-${yr}-${String(n).padStart(4, '0')}`)) n++;
  return `AG-${yr}-${String(n).padStart(4, '0')}`;
}

// Agreement type catalog — drives step 1 picker. Pulled from REF.agreementTypes
// when ready, otherwise the seed list mirrors the kinds already represented in
// screens3.jsx AGREEMENTS.
function _agTypes() {
  const REF = window.REF;
  const ui = {
    'PUBLISHING_COPUB':  { hint: 'Co-publishing · split mech/perf', cwr: 'OS', icon: '◑' },
    'ADMINISTRATION':    { hint: 'Admin only · no ownership',       cwr: 'PG', icon: '◐' },
    'SUB_PUBLISHING':    { hint: 'Sub-pub · territorial admin',     cwr: 'PG', icon: '◔' },
    'DISTRIBUTION':      { hint: 'Recording dist · master rights',  cwr: null, icon: '⬢' },
    'SYNC_LICENSE':      { hint: 'Sync · film/TV/ad placement',     cwr: null, icon: '⬡' },
    'WORK_FOR_HIRE':     { hint: 'WFH · creator assigns ownership', cwr: 'OS', icon: '◉' },
    'NEIGHBORING_RIGHTS':{ hint: 'NR · masters & performers',       cwr: null, icon: '◎' },
    'SETTLEMENT':        { hint: 'Settlement · dispute resolution', cwr: null, icon: '◇' },
  };
  if (REF && REF.ready && Array.isArray(REF.agreementTypes) && REF.agreementTypes.length) {
    return REF.agreementTypes.map(r => {
      const u = ui[r.code] || { hint: r.description || '', cwr: null, icon: '◌' };
      return { code: r.code, label: r.label, hint: u.hint, cwr: u.cwr, icon: u.icon };
    });
  }
  return [
    { code:'PUBLISHING_COPUB',   label:'Publishing · Co-pub',     hint:ui.PUBLISHING_COPUB.hint,   cwr:'OS', icon:ui.PUBLISHING_COPUB.icon },
    { code:'ADMINISTRATION',     label:'Administration',          hint:ui.ADMINISTRATION.hint,     cwr:'PG', icon:ui.ADMINISTRATION.icon },
    { code:'SUB_PUBLISHING',     label:'Sub-publishing',          hint:ui.SUB_PUBLISHING.hint,     cwr:'PG', icon:ui.SUB_PUBLISHING.icon },
    { code:'DISTRIBUTION',       label:'Recording · Distribution',hint:ui.DISTRIBUTION.hint,       cwr:null, icon:ui.DISTRIBUTION.icon },
    { code:'SYNC_LICENSE',       label:'Sync License',            hint:ui.SYNC_LICENSE.hint,       cwr:null, icon:ui.SYNC_LICENSE.icon },
    { code:'WORK_FOR_HIRE',      label:'Work for Hire',           hint:ui.WORK_FOR_HIRE.hint,      cwr:'OS', icon:ui.WORK_FOR_HIRE.icon },
    { code:'NEIGHBORING_RIGHTS', label:'Neighboring Rights',      hint:ui.NEIGHBORING_RIGHTS.hint, cwr:null, icon:ui.NEIGHBORING_RIGHTS.icon },
    { code:'SETTLEMENT',         label:'Settlement',              hint:ui.SETTLEMENT.hint,         cwr:null, icon:ui.SETTLEMENT.icon },
  ];
}

function _agPartyRoles() {
  const REF = window.REF;
  if (REF && REF.ready && Array.isArray(REF.agreementPartyRoles) && REF.agreementPartyRoles.length) {
    return REF.agreementPartyRoles.map(r => ({ v: r.code, l: r.label }));
  }
  return [
    { v:'ASSIGNOR',          l:'Assignor'           },
    { v:'ASSIGNEE',          l:'Assignee'           },
    { v:'ORIGINAL_PUB',      l:'Original Publisher' },
    { v:'SUB_PUB',           l:'Sub-Publisher'      },
    { v:'WRITER',            l:'Writer'             },
    { v:'ARTIST',            l:'Artist'             },
    { v:'LABEL',             l:'Label'              },
    { v:'DISTRIBUTOR',       l:'Distributor'        },
    { v:'WITNESS',           l:'Witness'            },
    { v:'GUARANTOR',         l:'Guarantor'          },
    { v:'COUNTERPARTY',      l:'Counterparty'       },
  ];
}

function _agStatuses() {
  return [
    { v:'draft',     l:'Draft',     desc:'Authoring in progress'      },
    { v:'review',    l:'In review', desc:'Sent for counter-signature' },
    { v:'active',    l:'Active',    desc:'Fully executed'             },
  ];
}

// ── Common UI atoms (mirror shape of release modal) ─────────────
function _AgLbl({ children, hint }) {
  return (
    <div className="ff-mono upper" style={{ fontSize: 9, letterSpacing:'.12em', color:'var(--ink-3)', marginBottom: 6 }}>
      {children}
      {hint && <span style={{ marginLeft: 8, textTransform: 'none', letterSpacing: 0, color:'var(--ink-4)' }}>{hint}</span>}
    </div>
  );
}
function _AgInp({ value, onChange, placeholder, mono = false, type = 'text', disabled = false, autoFocus = false, style }) {
  return (
    <input
      autoFocus={autoFocus}
      disabled={disabled}
      type={type}
      value={value == null ? '' : value}
      onChange={(e) => onChange(e.target.value)}
      placeholder={placeholder}
      className={mono ? 'ff-mono' : ''}
      style={{
        width:'100%', padding:'9px 11px', fontSize:13, lineHeight:1.4,
        background:'var(--bg)', color:'var(--ink)', border:'1px solid var(--rule)',
        outline:'none', boxSizing:'border-box', ...style,
      }} />
  );
}
function _AgSel({ value, onChange, children, mono = false, style, disabled = false }) {
  return (
    <select disabled={disabled} value={value == null ? '' : value} onChange={(e) => onChange(e.target.value)}
      className={mono ? 'ff-mono' : ''}
      style={{
        width:'100%', padding:'8px 11px', fontSize:13,
        background:'var(--bg)', color:'var(--ink)', border:'1px solid var(--rule)',
        outline:'none', boxSizing:'border-box', cursor: disabled ? 'not-allowed' : 'pointer', ...style,
      }}>
      {children}
    </select>
  );
}
function _AgChip({ active, onClick, children, sub, hint, icon }) {
  return (
    <button onClick={onClick}
      style={{
        textAlign:'left', padding:'12px 14px', cursor:'pointer',
        background: active ? 'var(--ink)' : 'var(--bg)',
        color: active ? 'var(--bg)' : 'var(--ink)',
        border:'1px solid', borderColor: active ? 'var(--ink)' : 'var(--rule)',
        display:'flex', flexDirection:'column', gap: 4,
      }}>
      <div style={{ display:'flex', alignItems:'center', gap: 8 }}>
        {icon && <span className="ff-mono" style={{ fontSize: 14, opacity:.85 }}>{icon}</span>}
        <span style={{ fontSize:13, fontWeight: 600 }}>{children}</span>
        {hint && <span className="ff-mono" style={{ marginLeft:'auto', fontSize: 9, color: active ? 'rgba(255,255,255,.55)' : 'var(--ink-3)', letterSpacing:'.08em' }}>{hint}</span>}
      </div>
      {sub && <div className="ff-mono" style={{ fontSize: 10, color: active ? 'rgba(255,255,255,.7)' : 'var(--ink-3)' }}>{sub}</div>}
    </button>
  );
}

// ── MAIN MODAL ───────────────────────────────────────────────────
function GlobalAddAgreementModal() {
  const [open, setOpen] = useAgS(false);
  const [step, setStep] = useAgS('type');
  const [form, setForm] = useAgS(() => _agInitForm());

  function _agInitForm() {
    return {
      // type
      typeCode: 'PUBLISHING_COPUB',
      kindLabel: 'Publishing · Co-pub',
      typeCwr: 'OS',
      // parties — at least 2
      parties: [
        { role:'ASSIGNOR', name:'', kind:'writer',    ipi:'', share: 50, isControlled: true  },
        { role:'ASSIGNEE', name:'', kind:'publisher', ipi:'', share: 50, isControlled: true  },
      ],
      // terms
      refNumber: '',
      societyAgreementNumber: '',
      start: _agToday(),
      end: _agAddYears(_agToday(), 5),
      termYears: 5,
      autoRenew: true,
      renewNoticeMonths: 6,
      retentionYears: 3,
      retentionEndDate: _agAddYears(_agToday(), 8),
      priorRoyaltyStatus: 'A', // A=All, N=None, U=Until paid
      sharesCanChange: false,
      advanceGiven: false,
      advanceAmount: '',
      advanceCurrency: 'USD',
      salesOrManufacture: 'S',
      jurisdiction: 'England & Wales',
      disputeResolution: 'Arbitration',
      status: 'draft',
      value: '',
      // territory
      territoryMode: 'world', // world | specific
      territories: [{ code: 'WW', label: 'World', rights: 'Mechanical + Performance', collection: 50, ownership: 50, excluded: [] }],
      // works
      works: [],
      // notes
      notes: '',
    };
  }

  // Open / close protocol
  useAgE(() => {
    const onOpen = (e) => {
      setOpen(true);
      const fresh = _agInitForm();
      // Optional preset: { kind: 'SUB_PUBLISHING', skipToStep: 'parties' }
      const preset = e?.detail?.kind;
      if (preset) {
        const opt = _agTypes().find(t => t.code === preset);
        if (opt) {
          fresh.typeCode = opt.code;
          fresh.kindLabel = opt.label;
          fresh.typeCwr = opt.cwr;
        }
      }
      setForm(fresh);
      setStep(e?.detail?.skipToStep || (preset ? 'parties' : 'type'));
    };
    window.addEventListener('astro-add-agreement', onOpen);
    return () => window.removeEventListener('astro-add-agreement', onOpen);
  }, []);

  // Recompute end date when termYears or start changes (only if user hasn't manually overridden)
  useAgE(() => {
    if (!form.start || !form.termYears) return;
    setForm(f => ({ ...f, end: _agAddYears(f.start, Number(f.termYears)), retentionEndDate: _agAddYears(_agAddYears(f.start, Number(f.termYears)), Number(f.retentionYears) || 0) }));
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [form.start, form.termYears, form.retentionYears]);

  if (!open) return null;

  const set = (patch) => setForm(f => ({ ...f, ...patch }));
  const close = () => setOpen(false);

  // Step navigation
  const STEPS = ['type', 'parties', 'terms', 'territory', 'works', 'confirm'];
  const stepLabels = { type:'01 · TYPE', parties:'02 · PARTIES', terms:'03 · TERMS', territory:'04 · TERRITORY', works:'05 · WORKS', confirm:'06 · CONFIRM' };
  const idx = STEPS.indexOf(step);
  const canGoNext = (() => {
    if (step === 'type') return !!form.typeCode;
    if (step === 'parties') return form.parties.filter(p => p.name.trim()).length >= 2;
    if (step === 'terms') return !!form.start && !!form.end;
    if (step === 'territory') return form.territories.length > 0;
    return true;
  })();
  const next = () => idx < STEPS.length - 1 && setStep(STEPS[idx + 1]);
  const back = () => idx > 0 && setStep(STEPS[idx - 1]);

  // Save handler
  const save = () => {
    const id = _agNextId();
    const a = form.parties.find(p => p.role === 'ASSIGNOR' || p.role === 'ORIGINAL_PUB' || p.role === 'WRITER' || p.role === 'ARTIST') || form.parties[0];
    const b = form.parties.find(p => (p.role === 'ASSIGNEE' || p.role === 'SUB_PUB' || p.role === 'LABEL' || p.role === 'DISTRIBUTOR') && p !== a) || form.parties[1] || form.parties[0];
    const newAgreement = {
      id,
      kind: form.kindLabel,
      a: a?.name || '—',
      b: b?.name || '—',
      territory: form.territoryMode === 'world' ? 'World'
        : (form.territories.length === 1 ? form.territories[0].label : `${form.territories.length} territories`),
      share: form.parties.map(p => p.share != null ? p.share : '—').join('/'),
      start: form.start,
      end: form.end,
      term: `${form.termYears}y`,
      status: form.status,
      value: form.advanceGiven && form.advanceAmount
        ? `$${Number(form.advanceAmount).toLocaleString()} adv.`
        : (form.value || (form.typeCode === 'ADMINISTRATION' || form.typeCode === 'SUB_PUBLISHING' ? 'admin only' : 'recoupable')),
      // Rich
      typeCwr: form.typeCwr || null,
      refNumber: form.refNumber,
      societyAgreementNumber: form.societyAgreementNumber || null,
      autoRenew: form.autoRenew,
      renewNoticeMonths: Number(form.renewNoticeMonths) || 0,
      retentionYears: Number(form.retentionYears) || 0,
      retentionEndDate: form.retentionEndDate,
      priorRoyaltyStatus: form.priorRoyaltyStatus,
      sharesCanChange: form.sharesCanChange,
      advanceGiven: form.advanceGiven,
      salesOrManufacture: form.salesOrManufacture,
      jurisdiction: form.jurisdiction,
      disputeResolution: form.disputeResolution,
      parties: form.parties.filter(p => p.name.trim()).map(p => ({
        role: _humanizeRole(p.role),
        name: p.name.trim(),
        kind: p.kind,
        ipi: p.ipi || null,
        share: p.share != null ? Number(p.share) : null,
        isControlled: p.isControlled !== false,
      })),
      territories: form.territories.map(t => ({
        code: t.code, label: t.label, rights: t.rights,
        collection: Number(t.collection) || 0,
        ownership: Number(t.ownership) || 0,
        excluded: t.excluded || [],
      })),
      works: form.works,
      versions: [
        { n: 1, date: _agToday(), author: 'You', note: 'Draft created via wizard', current: true },
      ],
      signatures: [],
      assets: [],
      advanceSchedule: form.advanceGiven && form.advanceAmount ? [
        { n: 1, label: 'On signing', amount: Number(form.advanceAmount), due: form.start, paid: false, paidOn: null },
      ] : [],
      audit: [
        { at: new Date().toISOString(), who: 'You', what: 'Agreement draft created via New-Agreement wizard' },
      ],
    };

    if (Array.isArray(window.AGREEMENTS)) {
      window.AGREEMENTS.unshift(newAgreement);
    }
    if (window.toast) window.toast(`Agreement ${id} created · ${form.kindLabel}`, 'ok');
    close();

    // Open the new agreement page
    setTimeout(() => {
      if (window.dispatchEvent) {
        window.dispatchEvent(new CustomEvent('astro-open-agreement', { detail: { id }}));
      }
    }, 80);
  };

  function _humanizeRole(role) {
    const map = {
      ASSIGNOR:'Assignor', ASSIGNEE:'Assignee',
      ORIGINAL_PUB:'Original Publisher', SUB_PUB:'Sub-Publisher',
      WRITER:'Writer', ARTIST:'Artist', LABEL:'Label',
      DISTRIBUTOR:'Distributor', WITNESS:'Witness',
      GUARANTOR:'Guarantor', COUNTERPARTY:'Counterparty',
    };
    return map[role] || role;
  }

  const types = _agTypes();
  const partyRoles = _agPartyRoles();

  return (
    <>
      <div onClick={close} style={{ position:'fixed', inset: 0, background:'rgba(0,0,0,.45)', zIndex: 90 }}/>
      <div style={{
        position:'fixed', top:'2vh', left:'50%', transform:'translateX(-50%)',
        width:'min(1080px, 96vw)', maxHeight:'96vh', overflow:'hidden',
        background:'var(--bg)', border:'1px solid var(--ink)', boxShadow:'10px 10px 0 rgba(0,0,0,.18)',
        zIndex: 91, color:'var(--ink)', display:'flex', flexDirection:'column',
      }}>
        {/* Header */}
        <div style={{ padding:'18px 24px 14px', borderBottom:'1px solid var(--rule)', display:'flex', alignItems:'flex-start', gap: 16 }}>
          <div style={{ flex: 1 }}>
            <div className="ff-mono upper" style={{ fontSize: 9, letterSpacing:'.14em', color:'var(--ink-3)', marginBottom: 4 }}>NEW AGREEMENT</div>
            <div className="ff-display" style={{ fontSize: 26, fontWeight: 700, letterSpacing:'-0.015em', lineHeight: 1.1 }}>
              {step === 'type'      && 'What kind of agreement?'}
              {step === 'parties'   && 'Who are the parties?'}
              {step === 'terms'     && 'Terms & dates'}
              {step === 'territory' && 'Territory & rights'}
              {step === 'works'     && 'Works covered'}
              {step === 'confirm'   && 'Review & create'}
            </div>
          </div>
          <button onClick={close} aria-label="Close"
            style={{ padding:'4px 10px', background:'transparent', border:'1px solid var(--rule)', color:'var(--ink-2)', cursor:'pointer', fontSize: 16, lineHeight: 1 }}>×</button>
        </div>

        {/* Step strip */}
        <div style={{ display:'flex', gap: 0, padding:'0 24px', background:'var(--bg-2)', borderBottom:'1px solid var(--rule)', overflowX:'auto' }}>
          {STEPS.map((k, i) => {
            const active = k === step;
            const done = i < idx;
            return (
              <button key={k} onClick={() => done && setStep(k)} disabled={!done && !active}
                className="ff-mono upper"
                style={{
                  padding:'12px 14px', fontSize: 9, letterSpacing:'.12em',
                  border: 0, background:'transparent', cursor: done ? 'pointer' : 'default',
                  borderBottom: active ? '2px solid var(--ink)' : '2px solid transparent',
                  color: active ? 'var(--ink)' : (done ? 'var(--ink-2)' : 'var(--ink-4)'),
                  fontWeight: active ? 700 : 500, marginBottom: -1, whiteSpace: 'nowrap',
                }}>
                {stepLabels[k]}
                {done && <span style={{ marginLeft: 6 }}>✓</span>}
              </button>
            );
          })}
        </div>

        {/* Body */}
        <div style={{ flex: 1, overflowY:'auto', padding:'22px 24px 28px', minHeight:'40vh' }}>
          {step === 'type'      && <_AgStepType      form={form} set={set} types={types} />}
          {step === 'parties'   && <_AgStepParties   form={form} set={set} partyRoles={partyRoles} />}
          {step === 'terms'     && <_AgStepTerms     form={form} set={set} />}
          {step === 'territory' && <_AgStepTerritory form={form} set={set} />}
          {step === 'works'     && <_AgStepWorks     form={form} set={set} />}
          {step === 'confirm'   && <_AgStepConfirm   form={form} types={types} />}
        </div>

        {/* Footer */}
        <div style={{ padding:'12px 18px', borderTop:'1px solid var(--rule)', background:'var(--bg-2)', display:'flex', alignItems:'center', gap: 12 }}>
          <span className="ff-mono" style={{ fontSize: 11, color:'var(--ink-3)' }}>
            Step {idx + 1} of {STEPS.length}
          </span>
          <span style={{ flex: 1 }}/>
          {idx > 0 && (
            <button onClick={back} className="ff-mono upper"
              style={{ padding:'8px 16px', fontSize: 10, letterSpacing:'.1em', background:'transparent', color:'var(--ink)', border:'1px solid var(--rule)', cursor:'pointer' }}>
              ← BACK
            </button>
          )}
          {idx < STEPS.length - 1 && (
            <button onClick={next} disabled={!canGoNext} className="ff-mono upper"
              style={{
                padding:'8px 16px', fontSize: 10, letterSpacing:'.1em',
                background: canGoNext ? 'var(--ink)' : 'var(--rule)',
                color: canGoNext ? 'var(--bg)' : 'var(--ink-3)',
                border: 0, cursor: canGoNext ? 'pointer' : 'not-allowed', fontWeight: 600,
              }}>
              CONTINUE →
            </button>
          )}
          {idx === STEPS.length - 1 && (
            <button onClick={save} className="ff-mono upper"
              style={{ padding:'8px 18px', fontSize: 10, letterSpacing:'.1em', background:'#2d6a3f', color:'#fff', border: 0, cursor:'pointer', fontWeight: 700 }}>
              ✓ CREATE AGREEMENT
            </button>
          )}
        </div>
      </div>
    </>
  );
}

// ── Step 1: TYPE ──────────────────────────────────────────────────
function _AgStepType({ form, set, types }) {
  return (
    <div>
      <_AgLbl>Agreement type</_AgLbl>
      <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(240px, 1fr))', gap: 10, marginBottom: 18 }}>
        {types.map(t => (
          <_AgChip key={t.code}
            icon={t.icon}
            active={form.typeCode === t.code}
            onClick={() => set({ typeCode: t.code, kindLabel: t.label, typeCwr: t.cwr })}
            sub={t.hint}
            hint={t.cwr ? `CWR · ${t.cwr}` : null}>
            {t.label}
          </_AgChip>
        ))}
      </div>
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 14 }}>
        <div>
          <_AgLbl hint="Optional · your internal contract code">Reference number</_AgLbl>
          <_AgInp value={form.refNumber} onChange={v => set({ refNumber: v })} placeholder="e.g. PP-FP-2024-COPUB-01" mono />
        </div>
        <div>
          <_AgLbl hint="Optional · society-side agreement #">Society agreement #</_AgLbl>
          <_AgInp value={form.societyAgreementNumber} onChange={v => set({ societyAgreementNumber: v })} placeholder="e.g. PRS-882-441-330" mono />
        </div>
      </div>
    </div>
  );
}

// ── Step 2: PARTIES ───────────────────────────────────────────────
function _AgStepParties({ form, set, partyRoles }) {
  const update = (i, patch) => set({ parties: form.parties.map((p, k) => k === i ? { ...p, ...patch } : p) });
  const add = () => set({ parties: form.parties.concat({ role: 'COUNTERPARTY', name: '', kind: 'company', ipi: '', share: null, isControlled: false }) });
  const remove = (i) => set({ parties: form.parties.length > 2 ? form.parties.filter((_, k) => k !== i) : form.parties });

  // Auto-share-balance: if 2 parties and shares are set, keep them adding to 100
  const handleShareChange = (i, val) => {
    const num = val === '' ? null : Number(val);
    if (form.parties.length === 2 && num != null && !Number.isNaN(num)) {
      const j = i === 0 ? 1 : 0;
      const other = Math.max(0, 100 - num);
      set({ parties: form.parties.map((p, k) => k === i ? { ...p, share: num } : k === j ? { ...p, share: other } : p) });
    } else {
      update(i, { share: num });
    }
  };

  const totalShare = form.parties.reduce((a, p) => a + (Number(p.share) || 0), 0);
  const validParties = form.parties.filter(p => p.name.trim()).length;

  return (
    <div>
      <_AgLbl hint={`${validParties} of ${form.parties.length} named · share total ${totalShare}%`}>Parties to this agreement</_AgLbl>
      <div style={{ display:'flex', flexDirection:'column', gap: 10, marginBottom: 14 }}>
        {form.parties.map((p, i) => (
          <div key={i} style={{
            border:'1px solid var(--rule)', background:'var(--bg)',
            padding:'12px 14px',
            display:'grid',
            gridTemplateColumns:'130px minmax(180px, 2fr) 110px 130px 80px 30px',
            gap: 10, alignItems:'center',
          }}>
            <_AgSel value={p.role} onChange={v => update(i, { role: v })} mono>
              {partyRoles.map(r => <option key={r.v} value={r.v}>{r.l}</option>)}
            </_AgSel>
            {window.PublisherTypeahead && p.kind === 'publisher' ? (
              <window.PublisherTypeahead
                value={p.name}
                aid={p._pubId}
                onSelect={(patch) => update(i, {
                  name: patch.pub ?? patch.name ?? p.name,
                  ipi:  patch.pubIpi ?? patch.ipi ?? p.ipi,
                  _pubId: patch._pubId ?? p._pubId,
                })}
              />
            ) : window.WriterTypeahead && (p.kind === 'writer' || p.kind === 'artist') ? (
              <window.WriterTypeahead
                value={p.name}
                aid={p._aid}
                onSelect={(patch) => update(i, {
                  name: patch.name ?? p.name,
                  ipi:  patch.ipi ?? p.ipi,
                  _aid: patch._aid ?? p._aid,
                })}
              />
            ) : (
              <_AgInp value={p.name} onChange={v => update(i, { name: v })} placeholder={p.kind === 'company' ? 'Organization name' : 'Name'} />
            )}
            <_AgSel value={p.kind} onChange={v => update(i, { kind: v })} mono>
              <option value="writer">Writer</option>
              <option value="artist">Artist</option>
              <option value="publisher">Publisher</option>
              <option value="label">Label</option>
              <option value="company">Company</option>
            </_AgSel>
            <_AgInp value={p.ipi || ''} onChange={v => update(i, { ipi: v.replace(/\D/g, '').slice(0, 11) })} placeholder="IPI" mono />
            <_AgInp value={p.share == null ? '' : p.share} onChange={v => handleShareChange(i, v)} placeholder="—" mono type="number" />
            <button onClick={() => remove(i)} aria-label="Remove party"
              disabled={form.parties.length <= 2}
              title={form.parties.length <= 2 ? 'Minimum 2 parties' : 'Remove'}
              style={{ padding:'6px 8px', background:'transparent', border:'1px solid var(--rule)', color: form.parties.length <= 2 ? 'var(--ink-4)' : 'var(--ink-2)', cursor: form.parties.length <= 2 ? 'not-allowed' : 'pointer', fontSize: 14, lineHeight: 1 }}>×</button>
          </div>
        ))}
      </div>
      <div style={{ display:'flex', alignItems:'center', gap: 14 }}>
        <button onClick={add} className="ff-mono upper"
          style={{ padding:'7px 12px', fontSize: 10, letterSpacing:'.1em', background:'transparent', color:'var(--ink)', border:'1px dashed var(--rule)', cursor:'pointer' }}>
          + ADD PARTY
        </button>
        {totalShare > 0 && totalShare !== 100 && (
          <span className="ff-mono" style={{ fontSize: 11, color:'#b78113' }}>
            ⚠ Shares total {totalShare}% — should be 100% for most agreement types
          </span>
        )}
      </div>
    </div>
  );
}

// ── Step 3: TERMS ─────────────────────────────────────────────────
function _AgStepTerms({ form, set }) {
  const onTermYears = (v) => {
    const n = Math.max(0, Math.min(99, Number(v) || 0));
    set({ termYears: n, end: _agAddYears(form.start, n) });
  };
  const onStart = (v) => {
    set({ start: v, end: _agAddYears(v, Number(form.termYears) || 0) });
  };

  return (
    <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 18 }}>
      <div>
        <_AgLbl>Effective start date</_AgLbl>
        <_AgInp value={form.start} onChange={onStart} type="date" mono />
      </div>
      <div>
        <_AgLbl hint="Auto-derived from term years">Effective end date</_AgLbl>
        <_AgInp value={form.end} onChange={v => set({ end: v })} type="date" mono />
      </div>
      <div>
        <_AgLbl>Term length (years)</_AgLbl>
        <_AgInp value={form.termYears} onChange={onTermYears} type="number" mono />
      </div>
      <div>
        <_AgLbl hint="Period after term-end during which royalties continue to flow">Retention years</_AgLbl>
        <_AgInp value={form.retentionYears} onChange={v => set({ retentionYears: Number(v) || 0 })} type="number" mono />
      </div>

      <div style={{ gridColumn:'1 / -1', borderTop:'1px solid var(--rule-soft)', paddingTop: 14, marginTop: 4 }}>
        <_AgLbl>Renewal & rights</_AgLbl>
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap: 14 }}>
          <label className="ff-mono" style={{ display:'flex', alignItems:'center', gap: 8, fontSize: 12, cursor:'pointer', padding:'10px 12px', background:'var(--bg)', border:'1px solid var(--rule)' }}>
            <input type="checkbox" checked={!!form.autoRenew} onChange={e => set({ autoRenew: e.target.checked })} />
            <span>Auto-renew at term-end</span>
          </label>
          <div>
            <_AgInp value={form.renewNoticeMonths} onChange={v => set({ renewNoticeMonths: Number(v) || 0 })} type="number" mono />
            <div className="ff-mono" style={{ fontSize: 9, color:'var(--ink-3)', marginTop: 4, letterSpacing:'.08em' }}>NOTICE MONTHS BEFORE RENEWAL</div>
          </div>
          <label className="ff-mono" style={{ display:'flex', alignItems:'center', gap: 8, fontSize: 12, cursor:'pointer', padding:'10px 12px', background:'var(--bg)', border:'1px solid var(--rule)' }}>
            <input type="checkbox" checked={!!form.sharesCanChange} onChange={e => set({ sharesCanChange: e.target.checked })} />
            <span>Shares can change post-signing</span>
          </label>
        </div>
      </div>

      <div style={{ gridColumn:'1 / -1', borderTop:'1px solid var(--rule-soft)', paddingTop: 14, marginTop: 4 }}>
        <_AgLbl>Advance</_AgLbl>
        <div style={{ display:'grid', gridTemplateColumns:'auto 1fr 1fr 1fr', gap: 12, alignItems:'center' }}>
          <label className="ff-mono" style={{ display:'flex', alignItems:'center', gap: 8, fontSize: 12, cursor:'pointer' }}>
            <input type="checkbox" checked={!!form.advanceGiven} onChange={e => set({ advanceGiven: e.target.checked })} />
            <span>Advance given</span>
          </label>
          <div>
            <_AgInp value={form.advanceAmount} onChange={v => set({ advanceAmount: v.replace(/[^\d.]/g, '') })} placeholder="0" type="text" mono disabled={!form.advanceGiven} />
            <div className="ff-mono" style={{ fontSize: 9, color:'var(--ink-3)', marginTop: 4, letterSpacing:'.08em' }}>AMOUNT</div>
          </div>
          <div>
            <_AgSel value={form.advanceCurrency} onChange={v => set({ advanceCurrency: v })} mono disabled={!form.advanceGiven}>
              {(typeof window.refCurrencies === 'function'
                ? window.refCurrencies().map(c => <option key={c.code} value={c.code}>{c.code}</option>)
                : <option value="USD">USD</option>)}
            </_AgSel>
            <div className="ff-mono" style={{ fontSize: 9, color:'var(--ink-3)', marginTop: 4, letterSpacing:'.08em' }}>CURRENCY</div>
          </div>
          <div>
            <_AgSel value={form.priorRoyaltyStatus} onChange={v => set({ priorRoyaltyStatus: v })} mono>
              <option value="A">A · All royalties retained</option>
              <option value="N">N · No prior royalties retained</option>
              <option value="U">U · Until paid</option>
            </_AgSel>
            <div className="ff-mono" style={{ fontSize: 9, color:'var(--ink-3)', marginTop: 4, letterSpacing:'.08em' }}>PRIOR ROYALTY STATUS</div>
          </div>
        </div>
      </div>

      <div style={{ gridColumn:'1 / -1', borderTop:'1px solid var(--rule-soft)', paddingTop: 14, marginTop: 4 }}>
        <_AgLbl>Legal</_AgLbl>
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap: 14 }}>
          <div>
            <_AgInp value={form.jurisdiction} onChange={v => set({ jurisdiction: v })} placeholder="e.g. England & Wales" />
            <div className="ff-mono" style={{ fontSize: 9, color:'var(--ink-3)', marginTop: 4, letterSpacing:'.08em' }}>GOVERNING JURISDICTION</div>
          </div>
          <div>
            <_AgSel value={form.disputeResolution} onChange={v => set({ disputeResolution: v })}>
              <option>Arbitration</option>
              <option>Arbitration · LCIA</option>
              <option>Arbitration · ICC</option>
              <option>Arbitration · AAA</option>
              <option>Mediation</option>
              <option>Court · venue specified</option>
            </_AgSel>
            <div className="ff-mono" style={{ fontSize: 9, color:'var(--ink-3)', marginTop: 4, letterSpacing:'.08em' }}>DISPUTE RESOLUTION</div>
          </div>
          <div>
            <_AgSel value={form.status} onChange={v => set({ status: v })} mono>
              <option value="draft">Draft</option>
              <option value="review">In review</option>
              <option value="active">Active (executed)</option>
            </_AgSel>
            <div className="ff-mono" style={{ fontSize: 9, color:'var(--ink-3)', marginTop: 4, letterSpacing:'.08em' }}>INITIAL STATUS</div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ── Step 4: TERRITORY ─────────────────────────────────────────────
function _AgStepTerritory({ form, set }) {
  const REF = window.REF;
  const territories = (REF && REF.ready && REF.territories) ? REF.territories : null;

  const setMode = (mode) => {
    if (mode === 'world') {
      set({
        territoryMode: 'world',
        territories: [{ code: 'WW', label: 'World', rights: 'Mechanical + Performance', collection: 50, ownership: 50, excluded: [] }],
      });
    } else {
      set({
        territoryMode: 'specific',
        territories: form.territories[0]?.code === 'WW'
          ? [{ code: 'US', label: 'United States', rights: 'Mechanical + Performance', collection: 50, ownership: 50, excluded: [] }]
          : form.territories,
      });
    }
  };
  const addRow = () => {
    set({ territories: form.territories.concat({ code: '', label: '', rights: 'Mechanical + Performance', collection: 0, ownership: 0, excluded: [] }) });
  };
  const updateRow = (i, patch) => {
    set({ territories: form.territories.map((t, k) => k === i ? { ...t, ...patch } : t) });
  };
  const removeRow = (i) => {
    set({ territories: form.territories.length > 1 ? form.territories.filter((_, k) => k !== i) : form.territories });
  };

  return (
    <div>
      <div style={{ display:'flex', gap: 8, marginBottom: 16 }}>
        <_AgChip active={form.territoryMode === 'world'} onClick={() => setMode('world')} icon="🌐" sub="All countries · single row">World</_AgChip>
        <_AgChip active={form.territoryMode === 'specific'} onClick={() => setMode('specific')} icon="◐" sub="Specify territories one-by-one">Specific territories</_AgChip>
      </div>

      <_AgLbl>{form.territoryMode === 'world' ? 'Worldwide rights' : `Territory list (${form.territories.length})`}</_AgLbl>
      <div style={{ border:'1px solid var(--rule)', overflow:'hidden' }}>
        <div className="ff-mono upper" style={{
          display:'grid', gridTemplateColumns:'80px 1.4fr 1.6fr 80px 80px 30px',
          gap: 10, padding:'8px 12px', background:'var(--bg-2)', fontSize: 9, letterSpacing:'.1em', color:'var(--ink-3)',
        }}>
          <div>CODE</div>
          <div>TERRITORY</div>
          <div>RIGHTS</div>
          <div style={{ textAlign:'right' }}>COLL %</div>
          <div style={{ textAlign:'right' }}>OWN %</div>
          <div></div>
        </div>
        {form.territories.map((t, i) => (
          <div key={i} style={{
            display:'grid', gridTemplateColumns:'80px 1.4fr 1.6fr 80px 80px 30px',
            gap: 10, padding:'8px 12px', borderTop:'1px solid var(--rule-soft)', alignItems:'center',
          }}>
            <_AgInp value={t.code} onChange={v => {
              const code = v.toUpperCase().slice(0, 3);
              const found = territories ? territories.find(x => x.code === code) : null;
              updateRow(i, { code, label: found ? found.label : t.label });
            }} placeholder="WW" mono disabled={form.territoryMode === 'world'} />
            <_AgInp value={t.label} onChange={v => updateRow(i, { label: v })} placeholder="World" disabled={form.territoryMode === 'world'} />
            <_AgSel value={t.rights} onChange={v => updateRow(i, { rights: v })} mono>
              <option>Mechanical + Performance</option>
              <option>Mechanical only</option>
              <option>Performance only</option>
              <option>Sync only</option>
              <option>All uses</option>
              <option>Master + Mechanical</option>
            </_AgSel>
            <_AgInp value={t.collection} onChange={v => updateRow(i, { collection: Number(v) || 0 })} type="number" mono style={{ textAlign:'right' }} />
            <_AgInp value={t.ownership}  onChange={v => updateRow(i, { ownership:  Number(v) || 0 })} type="number" mono style={{ textAlign:'right' }} />
            <button onClick={() => removeRow(i)} disabled={form.territories.length <= 1 || form.territoryMode === 'world'}
              style={{ padding:'4px 8px', background:'transparent', border:'1px solid var(--rule)', color:'var(--ink-2)', cursor: form.territories.length > 1 ? 'pointer' : 'not-allowed', fontSize: 14, lineHeight: 1 }}>×</button>
          </div>
        ))}
      </div>
      {form.territoryMode === 'specific' && (
        <button onClick={addRow} className="ff-mono upper"
          style={{ marginTop: 10, padding:'7px 12px', fontSize: 10, letterSpacing:'.1em', background:'transparent', color:'var(--ink)', border:'1px dashed var(--rule)', cursor:'pointer' }}>
          + ADD TERRITORY
        </button>
      )}
    </div>
  );
}

// ── Step 5: WORKS ─────────────────────────────────────────────────
function _AgStepWorks({ form, set }) {
  const [q, setQ] = useAgS('');
  const works = useAgM(() => window.WORKS || [], []);
  const filtered = useAgM(() => {
    const qn = q.trim().toLowerCase();
    if (!qn) return works.slice(0, 30);
    return works.filter(w =>
      (w.title || '').toLowerCase().includes(qn) ||
      (w.iswc || '').toLowerCase().includes(qn) ||
      (w.id || '').toLowerCase().includes(qn)
    ).slice(0, 50);
  }, [q, works]);
  const selectedIds = new Set(form.works.map(w => w.id));

  const toggle = (w) => {
    if (selectedIds.has(w.id)) {
      set({ works: form.works.filter(x => x.id !== w.id) });
    } else {
      const def = form.territories[0] || {};
      set({ works: form.works.concat({
        id: w.id, title: w.title, iswc: w.iswc || '',
        collection: def.collection || 50,
        ownership: def.ownership || 50,
        status: w.status === 'Registered' ? 'registered' : (w.status === 'Pending' ? 'pending' : 'registered'),
      }) });
    }
  };

  return (
    <div>
      <_AgLbl hint={form.works.length === 0 ? 'Optional · leave empty for blanket agreement' : `${form.works.length} selected`}>
        Works covered
      </_AgLbl>
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 16 }}>
        {/* Search */}
        <div>
          <_AgInp value={q} onChange={setQ} placeholder="Search works by title, ISWC, ID…" mono autoFocus />
          <div style={{ marginTop: 8, border:'1px solid var(--rule)', maxHeight: 360, overflowY:'auto' }}>
            {filtered.length === 0 && (
              <div className="ff-mono" style={{ padding:'18px 14px', textAlign:'center', color:'var(--ink-3)', fontSize: 12 }}>
                {q ? 'No works match' : 'Type to search'}
              </div>
            )}
            {filtered.map(w => {
              const sel = selectedIds.has(w.id);
              return (
                <button key={w.id} onClick={() => toggle(w)}
                  style={{
                    display:'grid', gridTemplateColumns:'auto 1fr auto', gap: 10, alignItems:'center',
                    padding:'8px 12px', width:'100%', textAlign:'left',
                    background: sel ? 'var(--bg-2)' : 'var(--bg)',
                    color:'var(--ink)', border: 0, borderBottom:'1px solid var(--rule-soft)', cursor:'pointer',
                  }}>
                  <span className="ff-mono" style={{
                    width: 16, height: 16, display:'inline-flex', alignItems:'center', justifyContent:'center',
                    border:'1px solid var(--ink-3)', background: sel ? 'var(--ink)' : 'transparent', color:'var(--bg)', fontSize: 10,
                  }}>{sel ? '✓' : ''}</span>
                  <div>
                    <div style={{ fontSize: 12, fontWeight: 500 }}>{w.title}</div>
                    <div className="ff-mono" style={{ fontSize: 10, color:'var(--ink-3)', marginTop: 1 }}>
                      {w.id}{w.iswc ? ` · ${w.iswc}` : ''}{w.writers ? ` · ${(Array.isArray(w.writers) ? w.writers.join(', ') : w.writers).slice(0, 40)}` : ''}
                    </div>
                  </div>
                  <span className="ff-mono num" style={{ fontSize: 10, color:'var(--ink-3)' }}>{w.status || ''}</span>
                </button>
              );
            })}
          </div>
        </div>

        {/* Selected list */}
        <div>
          <div className="ff-mono upper" style={{ fontSize: 9, letterSpacing:'.12em', color:'var(--ink-3)', marginBottom: 8 }}>SELECTED · {form.works.length}</div>
          <div style={{ border:'1px solid var(--rule)', maxHeight: 396, overflowY:'auto', background:'var(--bg-2)' }}>
            {form.works.length === 0 ? (
              <div className="ff-mono" style={{ padding:'24px 14px', textAlign:'center', color:'var(--ink-3)', fontSize: 12, fontStyle:'italic' }}>
                No works selected.<br/>This will be a blanket agreement covering all current and future works under these parties.
              </div>
            ) : form.works.map((w, i) => (
              <div key={w.id} style={{
                display:'grid', gridTemplateColumns:'1fr 60px 60px 24px', gap: 8, alignItems:'center',
                padding:'8px 12px', borderBottom:'1px solid var(--rule-soft)', fontSize: 12,
              }}>
                <div>
                  <div style={{ fontWeight: 500 }}>{w.title}</div>
                  <div className="ff-mono" style={{ fontSize: 10, color:'var(--ink-3)' }}>{w.id} · {w.iswc || 'no ISWC'}</div>
                </div>
                <_AgInp value={w.collection} onChange={v => set({ works: form.works.map((x, k) => k === i ? { ...x, collection: Number(v) || 0 } : x) })} type="number" mono style={{ padding:'4px 8px', fontSize: 11, textAlign:'right' }} />
                <_AgInp value={w.ownership}  onChange={v => set({ works: form.works.map((x, k) => k === i ? { ...x, ownership:  Number(v) || 0 } : x) })} type="number" mono style={{ padding:'4px 8px', fontSize: 11, textAlign:'right' }} />
                <button onClick={() => set({ works: form.works.filter((_, k) => k !== i) })}
                  style={{ padding:'2px 6px', background:'transparent', border:'1px solid var(--rule)', color:'var(--ink-2)', cursor:'pointer', fontSize: 12, lineHeight: 1 }}>×</button>
              </div>
            ))}
          </div>
          {form.works.length > 0 && (
            <div className="ff-mono upper" style={{
              display:'grid', gridTemplateColumns:'1fr 60px 60px 24px',
              gap: 8, padding:'6px 12px', fontSize: 9, color:'var(--ink-3)', letterSpacing:'.1em',
            }}>
              <div></div>
              <div style={{ textAlign:'right' }}>COLL %</div>
              <div style={{ textAlign:'right' }}>OWN %</div>
              <div></div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}

// ── Step 6: CONFIRM ───────────────────────────────────────────────
function _AgStepConfirm({ form, types }) {
  const t = types.find(x => x.code === form.typeCode);
  const totShare = form.parties.reduce((a, p) => a + (Number(p.share) || 0), 0);
  const lineStyle = { display:'grid', gridTemplateColumns:'160px 1fr', gap: 16, padding:'8px 0', borderBottom:'1px solid var(--rule-soft)', fontSize: 12 };
  const labelStyle = { color:'var(--ink-3)', textTransform:'uppercase', letterSpacing:'.08em', fontSize: 10, fontFamily:'var(--ff-mono, monospace)' };

  return (
    <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: 28 }}>
      <div>
        <div className="ff-mono upper" style={{ fontSize: 9, letterSpacing:'.14em', color:'var(--ink-3)', marginBottom: 10 }}>SUMMARY</div>
        <div style={lineStyle}>
          <div style={labelStyle}>Type</div>
          <div style={{ fontWeight: 600 }}>{t?.icon} {form.kindLabel}{form.typeCwr && <span className="ff-mono" style={{ marginLeft: 8, fontSize: 10, padding:'1px 6px', background:'var(--ink)', color:'var(--bg)', letterSpacing:'.08em' }}>CWR · {form.typeCwr}</span>}</div>
        </div>
        {form.refNumber && (
          <div style={lineStyle}>
            <div style={labelStyle}>Reference</div>
            <div className="ff-mono">{form.refNumber}</div>
          </div>
        )}
        {form.societyAgreementNumber && (
          <div style={lineStyle}>
            <div style={labelStyle}>Society agt #</div>
            <div className="ff-mono">{form.societyAgreementNumber}</div>
          </div>
        )}
        <div style={lineStyle}>
          <div style={labelStyle}>Term</div>
          <div>
            <span className="ff-mono">{form.start}</span>
            <span style={{ margin:'0 8px', color:'var(--ink-3)' }}>→</span>
            <span className="ff-mono">{form.end}</span>
            <span className="ff-mono" style={{ marginLeft: 10, color:'var(--ink-3)' }}>({form.termYears}y)</span>
          </div>
        </div>
        <div style={lineStyle}>
          <div style={labelStyle}>Renewal</div>
          <div>{form.autoRenew ? `Auto-renews · ${form.renewNoticeMonths}-month notice` : 'No auto-renew'}</div>
        </div>
        <div style={lineStyle}>
          <div style={labelStyle}>Retention</div>
          <div>{form.retentionYears}y · ends {form.retentionEndDate}</div>
        </div>
        <div style={lineStyle}>
          <div style={labelStyle}>Advance</div>
          <div>
            {form.advanceGiven
              ? <><span className="ff-mono num">{form.advanceCurrency} {Number(form.advanceAmount || 0).toLocaleString()}</span><span style={{ marginLeft: 10, color:'var(--ink-3)' }}>· prior royalty: {form.priorRoyaltyStatus}</span></>
              : <span style={{ color:'var(--ink-3)', fontStyle:'italic' }}>None</span>}
          </div>
        </div>
        <div style={lineStyle}>
          <div style={labelStyle}>Jurisdiction</div>
          <div>{form.jurisdiction} · {form.disputeResolution}</div>
        </div>
        <div style={lineStyle}>
          <div style={labelStyle}>Status</div>
          <div>
            <span className="ff-mono upper" style={{ padding:'2px 8px', fontSize: 10, letterSpacing:'.1em', background: form.status === 'active' ? '#2d6a3f' : form.status === 'review' ? '#b78113' : 'var(--bg-2)', color: form.status === 'draft' ? 'var(--ink)' : '#fff' }}>
              {form.status === 'active' ? 'ACTIVE' : form.status === 'review' ? 'IN REVIEW' : 'DRAFT'}
            </span>
          </div>
        </div>
      </div>

      <div>
        <div className="ff-mono upper" style={{ fontSize: 9, letterSpacing:'.14em', color:'var(--ink-3)', marginBottom: 10 }}>PARTIES · {form.parties.filter(p => p.name.trim()).length}</div>
        <div style={{ marginBottom: 18 }}>
          {form.parties.filter(p => p.name.trim()).map((p, i) => (
            <div key={i} style={{ padding:'7px 0', borderBottom:'1px solid var(--rule-soft)', display:'grid', gridTemplateColumns:'auto 1fr auto', gap: 10, alignItems:'center', fontSize: 12 }}>
              <span className="ff-mono upper" style={{ fontSize: 9, padding:'2px 6px', background:'var(--bg-2)', color:'var(--ink-2)', letterSpacing:'.08em' }}>{p.role}</span>
              <div>
                <div style={{ fontWeight: 500 }}>{p.name}</div>
                <div className="ff-mono" style={{ fontSize: 10, color:'var(--ink-3)' }}>{p.kind}{p.ipi ? ` · IPI ${p.ipi}` : ''}</div>
              </div>
              <span className="ff-mono num" style={{ fontSize: 11 }}>{p.share != null ? `${p.share}%` : '—'}</span>
            </div>
          ))}
          {totShare > 0 && (
            <div className="ff-mono" style={{ marginTop: 6, fontSize: 10, color: totShare === 100 ? 'var(--ink-3)' : '#b78113', textAlign:'right' }}>
              Total · {totShare}%
            </div>
          )}
        </div>

        <div className="ff-mono upper" style={{ fontSize: 9, letterSpacing:'.14em', color:'var(--ink-3)', marginBottom: 10 }}>TERRITORY · {form.territoryMode === 'world' ? 'WORLD' : `${form.territories.length} ROWS`}</div>
        <div style={{ marginBottom: 18 }}>
          {form.territories.map((t, i) => (
            <div key={i} style={{ padding:'6px 0', borderBottom:'1px solid var(--rule-soft)', display:'grid', gridTemplateColumns:'60px 1fr 60px 60px', gap: 10, fontSize: 11, alignItems:'center' }}>
              <span className="ff-mono">{t.code}</span>
              <span>{t.label} <span style={{ color:'var(--ink-3)' }}>· {t.rights}</span></span>
              <span className="ff-mono num" style={{ textAlign:'right' }}>{t.collection}%</span>
              <span className="ff-mono num" style={{ textAlign:'right' }}>{t.ownership}%</span>
            </div>
          ))}
        </div>

        <div className="ff-mono upper" style={{ fontSize: 9, letterSpacing:'.14em', color:'var(--ink-3)', marginBottom: 10 }}>WORKS · {form.works.length === 0 ? 'BLANKET' : form.works.length}</div>
        {form.works.length === 0 ? (
          <div className="ff-mono" style={{ fontSize: 11, color:'var(--ink-3)', fontStyle:'italic' }}>Blanket agreement — covers all works under these parties.</div>
        ) : (
          <div style={{ maxHeight: 140, overflowY:'auto', border:'1px solid var(--rule-soft)' }}>
            {form.works.slice(0, 12).map(w => (
              <div key={w.id} style={{ padding:'5px 10px', borderBottom:'1px solid var(--rule-soft)', display:'grid', gridTemplateColumns:'auto 1fr', gap: 8, fontSize: 11 }}>
                <span className="ff-mono" style={{ color:'var(--ink-3)' }}>{w.id}</span>
                <span>{w.title}</span>
              </div>
            ))}
            {form.works.length > 12 && (
              <div className="ff-mono" style={{ padding:'6px 10px', fontSize: 10, color:'var(--ink-3)' }}>+ {form.works.length - 12} more…</div>
            )}
          </div>
        )}
      </div>
    </div>
  );
}

Object.assign(window, { GlobalAddAgreementModal });
