﻿// LedgerBeaver web app ΓÇö screens
// Each screen handles loading/empty/error and has // SUPABASE comments where queries go.

const { fmt, fmtSigned, KpiCard, StatusPill, AgentChip, SectionHead, Stateful, Sparkline } = window.LBUI;
const D = window.LB_DATA;

// =================== CONSOLE (Dashboard) ===================
const ScreenConsole = ({ goto, setupComplete }) => {
  const k = D.kpis;
  // SUPABASE: useEffect ΓåÆ load KPIs in parallel. For prototype, instant.
  const state = 'ready';

  if (!setupComplete) {
    return (
      <div className="screen">
        <SectionHead
          kicker="CONSOLE"
          title={LB.t('state.setup.h')}
          sub="Two more steps and your AI is live."
        />
        <div className="state">
          <Beaver pose="point" size={120} halo="spotlight" anim="pop-then-idle" />
          <h4>{LB.t('state.setup.h')}</h4>
          <p>Finish connecting approvals and your team, then watch Claude take over your books.</p>
          <button className="btn btn-primary" onClick={() => goto('setup')}>{LB.t('state.setup.cta')} ΓåÆ</button>
        </div>
      </div>
    );
  }

  return (
    <div className="screen">
      <SectionHead
        kicker="CONSOLE ┬╖ 14 MAY 2026"
        title={<>Good morning, Sam. <span style={{color:'var(--amber)'}}>Claude</span> handled <span style={{color:'var(--text-hi)'}}>14 things</span> overnight.</>}
        sub="3 need your tap. Everything else is clean."
        actions={<>
          <button className="btn btn-ghost"><Icon name="refresh" size={14} /> Refresh</button>
          <button className="btn btn-primary"><Icon name="plus" size={14} /> New entry</button>
        </>}
      />

      <div className="kpi-grid">
        <KpiCard label="Cash on hand"      value={k.cash.v}          delta={k.cash.d}          accent="neutral" />
        <KpiCard label="AP outstanding"    value={k.apOutstanding.v} delta={k.apOutstanding.d} accent="amber" />
        <KpiCard label="AR outstanding"    value={k.arOutstanding.v} delta={k.arOutstanding.d} accent="emerald" />
        <KpiCard label="P&L ┬╖ May (MTD)"   value={k.monthlyPL.v}     delta={k.monthlyPL.d}     accent="purple" />
        <KpiCard label="Pending approvals" value={String(k.pendingApp.v)} accent="amber" />
        <KpiCard label="Security alerts"   value={String(k.securityAlt.v)} accent="neutral" />
      </div>

      <div className="card-row">
        <div className="card panel">
          <div className="panel-head">
            <div>
              <div className="eyebrow">Approvals queue</div>
              <h3 className="panel-title">3 things need you today</h3>
            </div>
            <button className="btn btn-ghost" onClick={() => goto('approvals')}>
              Open all <Icon name="arrowR" size={14} />
            </button>
          </div>
          {D.approvals.slice(0, 3).map(a => (
            <div className="approve-row" key={a.id} style={{gridTemplateColumns: '64px 1fr auto auto'}}>
              <div className="ap-kind" data-kind={a.kind}>{a.kind}</div>
              <div>
                <div className="ap-title">{a.title}</div>
                <div className="ap-ctx"><AgentChip name={a.agent} /> ┬╖ {a.ctx}</div>
              </div>
              {a.amt != null && <div className="ap-amt">{fmt(a.amt)}</div>}
              <div className="ap-act">
                <button className="btn btn-soft" style={{padding:'6px 10px',fontSize:12}}>Review</button>
                <button className="btn btn-primary" style={{padding:'6px 10px',fontSize:12}}>Approve</button>
              </div>
            </div>
          ))}
        </div>

        <div className="card panel">
          <div className="panel-head">
            <div>
              <div className="eyebrow">Cash forecast ┬╖ 30 days</div>
              <h3 className="panel-title">{fmt(248_412 + 88_400 - 56_120)} projected</h3>
            </div>
          </div>
          <Sparkline />
          <div className="forecast-rows">
            <div className="frow"><span>Inflows (AR collection)</span><span style={{color:'var(--ar)'}}>+{fmt(88_400)}</span></div>
            <div className="frow"><span>Outflows (AP + Payroll)</span><span style={{color:'var(--err)'}}>ΓêÆ{fmt(56_120)}</span></div>
            <div className="frow"><span>Net 30-day</span><span style={{color:'var(--text-hi)', fontWeight: 600}}>+{fmt(32_280)}</span></div>
          </div>
        </div>
      </div>

      <div className="card-row fourup">
        <ModuleCard tag="AP"        accent="amber"   title="Accounts Payable"  n="9 open" sub="2 need approval ┬╖ 1 duplicate" onClick={() => goto('ap')}        icon="ap" />
        <ModuleCard tag="AR"        accent="emerald" title="Accounts Receivable" n="7 open" sub="2 overdue ┬╖ 1 partial"        onClick={() => goto('ar')}        icon="ar" />
        <ModuleCard tag="GL"        accent="purple"  title="General Ledger"     n="6 today" sub="0 exceptions ┬╖ clean"          onClick={() => goto('gl')}        icon="gl" />
        <ModuleCard tag="Workflow"  accent="cyan"    title="Workflow drilldown" n="2 in flight" sub="Trace any txn end-to-end"   onClick={() => goto('workflow')}  icon="terminal" />
      </div>

      {/* The Dam ┬╖ Partner Hub widget */}
      {window.DamWidget && <DamWidget goto={goto} />}
    </div>
  );
};

const ModuleCard = ({ tag, accent, title, n, sub, onClick, icon }) => (
  <div className="card module-card" onClick={onClick}>
    <div className="mc-head">
      <span className="mc-tag" data-accent={accent}>{tag}</span>
      <Icon name={icon} size={18} className="mc-icon" />
    </div>
    <div className="mc-title">{title}</div>
    <div className="mc-n">{n}</div>
    <div className="mc-sub">{sub}</div>
    <div className="mc-arrow"><Icon name="arrowUR" size={14} /></div>
  </div>
);

// =================== SETUP CENTER ===================
const ScreenSetup = ({ goto, setSetup, setupSteps }) => {
  // SUPABASE: read setup status from companies/email_connections/plaid_links/approval_rules tables
  // const steps = await Promise.all([ checkEmailConnection(), checkBankConnection(), checkApprovalRules(), checkTeamInvites() ]);

  const [oauthModal, setOauthModal] = useState(false);
  const done = setupSteps.filter(s => s.done).length;
  const pct = Math.round((done / setupSteps.length) * 100);
  const allDone = done === setupSteps.length;

  const onStepClick = (step) => {
    if (step.done) return;
    // SUPABASE WIRE points:
    //  email     ΓåÆ kick off Google OAuth: redirect to /oauth/google with VITE_GOOGLE_CLIENT_ID
    //  bank      ΓåÆ supabase.functions.invoke('plaid-link-token') then open Plaid Link
    //  approvals ΓåÆ INSERT default rules: { name: 'Auto-approve <$500', threshold: 500 }, etc.
    //  team      ΓåÆ sendTeamInvites([email1, email2])
    if (step.id === 'email') { setOauthModal(true); return; }
    setSetup(step.id, true);
  };

  return (
    <div className="screen">
      <div className="setup-hero">
        <div>
          <div className="eyebrow" style={{color:'var(--amber)'}} data-i18n="setup.h">Welcome. Let's get you live.</div>
          <h2 className="setup-h"><span data-i18n="setup.sub">Four steps. About 4 minutes. Your AI takes it from there.</span></h2>
          <div className="setup-progress"><span style={{ width: pct + '%' }} /></div>
          <div className="setup-progress-label">{done} / {setupSteps.length} ┬╖ {pct}% complete</div>
        </div>
        <Beaver pose={allDone ? 'achievement' : 'cheer'} size={140} halo="spotlight" anim={allDone ? 'pop-then-idle' : 'idle'} />
      </div>

      <div className="setup-grid">
        {setupSteps.map(step => (
          <div key={step.id} className={"setup-step " + (step.done ? 'done' : '')}>
            <div className="setup-step-ico">
              {step.done
                ? <Icon name="check" size={20} />
                : <Icon name={step.id === 'email' ? 'mail' : step.id === 'bank' ? 'dollar' : step.id === 'approvals' ? 'approvals' : 'user'} size={20} />}
            </div>
            <div>
              <h5 data-i18n={step.h}>{step.h}</h5>
              <p  data-i18n={step.sub}>{step.sub}</p>
            </div>
            <button className={step.done ? 'btn btn-ghost' : 'btn btn-primary'} onClick={() => onStepClick(step)}>
              {step.done ? <span data-i18n="setup.connected">Connected</span> : <span data-i18n="setup.connect">Connect</span>}
            </button>
          </div>
        ))}
      </div>

      <div style={{ marginTop: 28, textAlign: 'center' }}>
        <button className="btn btn-primary btn-lg" disabled={!allDone} onClick={() => goto('console')}
                style={{ padding:'14px 24px', opacity: allDone ? 1 : 0.4, cursor: allDone ? 'pointer' : 'not-allowed' }}>
          <span data-i18n="setup.launch">Launch dashboard</span> ΓåÆ
        </button>
        {!allDone && <div style={{ marginTop: 10, fontSize: 12, color: 'var(--text-lo)', fontFamily: 'var(--font-mono)' }}>Available once all setup steps are connected.</div>}
      </div>

      {oauthModal && (
        <div className="modal-overlay" onClick={() => setOauthModal(false)}>
          <div className="modal" onClick={e => e.stopPropagation()}>
            <h3>Connect Gmail</h3>
            <p>LedgerBeaver will read incoming invoice emails only. You can disconnect any time.</p>
            <div className="snippet">
              <div className="snippet-head">
                <span>Permission scopes</span>
                <span style={{ color: 'var(--amber)' }}>read-only</span>
              </div>
              <pre>{`gmail.readonly         ┬╖ view incoming mail
gmail.metadata          ┬╖ sender + subject only
openid email profile    ┬╖ identify your account`}</pre>
            </div>
            <p style={{ marginTop: 14, fontSize: 12, color: 'var(--text-lo)' }}>
              {/* PRODUCTION WIRE:
                  window.location.href = `https://accounts.google.com/o/oauth2/v2/auth?client_id=${VITE_GOOGLE_CLIENT_ID}&...`;
                  callback writes to email_connections table. */}
              Redirects to Google. You return to LedgerBeaver after granting access.
            </p>
            <div className="modal-actions">
              <button className="btn btn-soft" onClick={() => setOauthModal(false)}>Cancel</button>
              <button className="btn btn-primary" onClick={() => { setSetup('email', true); setOauthModal(false); }}>
                <Icon name="link" size={14} /> Continue with Google
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

// =================== AP ===================
const ScreenAP = () => {
  const [sel, setSel] = useState(D.ap.bills[0].id);
  const sb = D.ap.bills.find(b => b.id === sel) || D.ap.bills[0];
  return (
    <div className="screen">
      <SectionHead
        kicker="ACCOUNTS PAYABLE"
        title="Invoice intake ┬╖ matching ┬╖ approval"
        sub="Your agent works the inbox. You handle exceptions."
        actions={<>
          <button className="btn btn-ghost"><Icon name="filter" size={14} /> Filter</button>
          <button className="btn btn-primary"><Icon name="upload" size={14} /> Upload</button>
        </>}
      />
      <div className="kpi-grid">
        <KpiCard label="Total payables"   value={D.ap.kpis.totalPay}      accent="neutral" />
        <KpiCard label="Approved to pay"  value={D.ap.kpis.approvedToPay} accent="emerald" />
        <KpiCard label="Open exceptions"  value={D.ap.kpis.openExc}       accent="red" />
        <KpiCard label="Cash outflow MTD" value={D.ap.kpis.cashOutMTD}    accent="amber" />
      </div>

      <div className="ap-grid">
        <div className="card panel">
          <div className="panel-head">
            <div>
              <div className="eyebrow">Inbox ┬╖ 9 open</div>
              <h3 className="panel-title">Vendor invoices</h3>
            </div>
            <span className="chip"><span className="live-dot" />Live</span>
          </div>
          <table className="lb-table">
            <thead><tr><th>Invoice</th><th>Vendor</th><th>Amount</th><th>Due</th><th>Status</th><th>Source</th></tr></thead>
            <tbody>
              {D.ap.bills.map(b => (
                <tr key={b.id} className={sel === b.id ? 'sel' : ''} onClick={() => setSel(b.id)}>
                  <td className="mono">{b.id}</td>
                  <td><strong>{b.vendor}</strong><div className="muted-sm">{b.po}</div></td>
                  <td className="mono num">{fmt(b.amt)}</td>
                  <td className="mono"><span className="muted">{b.due.slice(5)}</span></td>
                  <td><StatusPill s={b.status} /></td>
                  <td><AgentChip name={b.agent} /></td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>

        <div className="card panel inspector">
          <div className="panel-head">
            <div>
              <div className="eyebrow">Inspector</div>
              <h3 className="panel-title">{sb.id}</h3>
            </div>
            <StatusPill s={sb.status} />
          </div>
          <div className="insp-rows">
            <div><span>Vendor</span><span>{sb.vendor}</span></div>
            <div><span>Amount</span><span style={{color:'var(--amber)', fontWeight:600}}>{fmt(sb.amt)}</span></div>
            <div><span>PO</span><span>{sb.po}</span></div>
            <div><span>Due</span><span>{sb.due}</span></div>
            <div><span>Source</span><span><AgentChip name={sb.agent} /> via email</span></div>
          </div>

          <div className="match-block">
            <div className="match-h">3-way match</div>
            <div className="match-rows">
              <div className="mrow"><span>Purchase order</span><span className="ok">Γ£ô Pass</span></div>
              <div className="mrow"><span>Receiving doc</span><span className="ok">Γ£ô Pass</span></div>
              <div className="mrow"><span>Invoice amount</span><span className="ok">Γ£ô Pass</span></div>
              <div className="mrow"><span>Confidence</span><span className="amber">{(sb.match?.conf ? Math.round(sb.match.conf*100) : 94)}%</span></div>
            </div>
          </div>

          <div className="agent-quote">
            <Icon name="bot" size={14} />
            <span>"Posted to <strong>5120 ┬╖ COGS ┬╖ Materials</strong>. Routing to Sam for approval since amount exceeds vendor's 30-day average by 22%."</span>
          </div>

          <div className="insp-actions">
            <button className="btn btn-soft">Decline</button>
            <button className="btn btn-ghost">Reassign</button>
            <button className="btn btn-primary">Approve ┬╖ {fmt(sb.amt)}</button>
          </div>
        </div>
      </div>
    </div>
  );
};

// =================== AR ===================
const ScreenAR = () => {
  const a = D.ar;
  return (
    <div className="screen">
      <SectionHead
        kicker="ACCOUNTS RECEIVABLE"
        title="Invoices ┬╖ aging ┬╖ collection"
        sub="Your agent drafts reminders, you press send."
        actions={<>
          <button className="btn btn-ghost"><Icon name="download" size={14} /> Aging CSV</button>
          <button className="btn btn-primary"><Icon name="plus" size={14} /> New invoice</button>
        </>}
      />
      <div className="kpi-grid">
        <KpiCard label="Total receivable" value={a.kpis.totalRec}    accent="neutral" />
        <KpiCard label="DSO"              value={`${a.kpis.dso} days`} accent="emerald" />
        <KpiCard label="Overdue"          value={a.kpis.overdue}     accent="red" />
        <KpiCard label="Invoiced MTD"     value={a.kpis.mtdInvoiced} accent="emerald" />
      </div>

      <div className="card panel">
        <div className="panel-head">
          <div>
            <div className="eyebrow">Aging</div>
            <h3 className="panel-title">{fmt(a.kpis.totalRec)} across buckets</h3>
          </div>
        </div>
        <AgingBar aging={a.aging} />
      </div>

      <div className="card panel" style={{ marginTop: 16 }}>
        <div className="panel-head">
          <div>
            <div className="eyebrow">Customer invoices</div>
            <h3 className="panel-title">7 open</h3>
          </div>
          <button className="btn btn-ghost"><Icon name="filter" size={14} /> All statuses</button>
        </div>
        <table className="lb-table">
          <thead><tr><th>Invoice</th><th>Customer</th><th>Sent</th><th>Due</th><th>Amount</th><th>Paid</th><th>Status</th></tr></thead>
          <tbody>
            {a.invoices.map(inv => (
              <tr key={inv.id}>
                <td className="mono">{inv.id}</td>
                <td><strong>{inv.cust}</strong>{inv.days && <div className="muted-sm" style={{color:'var(--err)'}}>{inv.days} days overdue</div>}</td>
                <td className="mono"><span className="muted">{inv.sent.slice(5)}</span></td>
                <td className="mono"><span className="muted">{inv.due.slice(5)}</span></td>
                <td className="mono num">{fmt(inv.amt)}</td>
                <td className="mono num">{fmt(inv.paid)}</td>
                <td><StatusPill s={inv.status} /></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  );
};

const AgingBar = ({ aging }) => {
  const total = aging.current + aging.d30 + aging.d60 + aging.d90 + aging.d90plus;
  const buckets = [
    { k: 'current', l: 'Current', c: 'var(--ar)' },
    { k: 'd30',     l: '1-30',    c: '#34D399' },
    { k: 'd60',     l: '31-60',   c: '#FBBF24' },
    { k: 'd90',     l: '61-90',   c: '#FB923C' },
    { k: 'd90plus', l: '90+',     c: 'var(--err)' },
  ];
  return (
    <div>
      <div className="aging-bar">
        {buckets.map(b => (
          <div key={b.k} style={{ background: b.c, flex: aging[b.k] / total }} title={`${b.l}: ${fmt(aging[b.k])}`} />
        ))}
      </div>
      <div style={{ display:'flex', justifyContent:'space-between', marginTop: 12, fontFamily:'var(--font-mono)', fontSize: 12 }}>
        {buckets.map(b => (
          <div key={b.k}>
            <div style={{ color: b.c, fontWeight: 600 }}>{b.l}</div>
            <div style={{ color: 'var(--text-hi)', fontSize: 14, marginTop: 2 }}>{fmt(aging[b.k])}</div>
          </div>
        ))}
      </div>
    </div>
  );
};

// =================== GL ===================
const ScreenGL = () => (
  <div className="screen">
    <SectionHead
      kicker="GENERAL LEDGER"
      title="Chart of accounts ┬╖ journal entries"
      sub="Agent-posted, audit-trailed, reconciled to the cent."
      actions={<>
        <button className="btn btn-ghost"><Icon name="download" size={14} /> Trial balance</button>
        <button className="btn btn-ghost"><Icon name="lock" size={14} /> Close period</button>
        <button className="btn btn-primary"><Icon name="plus" size={14} /> Journal entry</button>
      </>}
    />
    <div className="gl-grid">
      <div className="card panel">
        <div className="panel-head">
          <div>
            <div className="eyebrow">Chart of accounts</div>
            <h3 className="panel-title">{D.gl.accounts.length} accounts</h3>
          </div>
        </div>
        <table className="lb-table">
          <thead><tr><th>Acct</th><th>Name</th><th>Type</th><th>Balance</th></tr></thead>
          <tbody>
            {D.gl.accounts.map(a => (
              <tr key={a.num}>
                <td className="mono">{a.num}</td>
                <td>{a.name}</td>
                <td><span className="chip" style={{ fontSize: 10 }}>{a.type}</span></td>
                <td className="mono num">{fmt(Math.abs(a.bal))}{a.bal < 0 ? ' CR' : ''}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <div className="card panel">
        <div className="panel-head">
          <div>
            <div className="eyebrow">Journal ┬╖ today</div>
            <h3 className="panel-title">6 entries ┬╖ 1 pending</h3>
          </div>
          <span className="chip" style={{ color: 'var(--ok)' }}><span className="live-dot" />Reconciled</span>
        </div>
        <table className="lb-table">
          <thead><tr><th>Date</th><th>Ref</th><th>Description</th><th>DR</th><th>CR</th><th>Amount</th><th>Src</th></tr></thead>
          <tbody>
            {D.gl.journal.map((j, i) => (
              <tr key={i}>
                <td className="mono">{j.date.slice(5)}</td>
                <td className="mono">{j.ref}</td>
                <td>{j.desc}</td>
                <td className="mono">{j.dr}</td>
                <td className="mono">{j.cr}</td>
                <td className="mono num">{fmt(j.amt)}</td>
                <td>{j.src === 'Claude' ? <AgentChip name="Claude" /> : <span className="muted">You</span>}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
    </div>
  </div>
);

// =================== APPROVALS ΓÇö batch + reason + audit ===================
const ScreenApprovals = () => {
  const [selected, setSelected] = useState({});  // id ΓåÆ true
  const [reasons, setReasons]   = useState({});  // id ΓåÆ string
  const [showAudit, setShowAudit] = useState({});// id ΓåÆ bool (for approved-now or expanded)

  const toggle = (id) => setSelected(s => ({ ...s, [id]: !s[id] }));
  const setAll = (ids, on) => setSelected(s => ({ ...s, ...Object.fromEntries(ids.map(id => [id, on])) }));
  const selectedIds = Object.keys(selected).filter(k => selected[k]);

  // SUPABASE: const items = await supabase.from('approvals').select('*').eq('status','pending');
  const buckets = { today: [], tomorrow: [], 'this week': [] };
  D.approvals.forEach(a => buckets[a.urg].push(a));

  // Batch approve handler
  // SUPABASE WIRE:
  //   for (const id of selectedIds) {
  //     await supabase.from('approvals').update({ status: 'approved', approved_by: userId, reason: reasons[id] }).eq('id', id);
  //     await supabase.from('approval_history').insert({ approval_id: id, who: userId, what: 'approved', reason });
  //   }
  const batchApprove = () => {
    alert(`Approve ${selectedIds.length} items?\n\n` + selectedIds.map(id => {
      const a = D.approvals.find(x => x.id === Number(id));
      return `ΓÇó ${a?.title}${reasons[id] ? ` ΓÇö "${reasons[id]}"` : ''}`;
    }).join('\n'));
  };

  return (
    <div className="screen">
      <SectionHead
        kicker="APPROVALS"
        title={`${D.approvals.length} things need your eyes`}
        sub="Routed by Claude per your spend policy. Tap to approve, swipe to flag."
        actions={<>
          <button className="btn btn-ghost"><Icon name="filter" size={14} /> All kinds</button>
          <button className="btn btn-ghost" onClick={() => setAll(D.approvals.map(a => a.id), true)}>
            Select all
          </button>
        </>}
      />

      {selectedIds.length > 0 && (
        <div className="batch-bar">
          <span className="count">{selectedIds.length} selected</span>
          <span style={{ color: 'var(--text-mid)', fontSize: 13 }}>
            Total: <strong style={{ color: 'var(--text-hi)' }}>
              {fmt(selectedIds.reduce((s, id) => s + (D.approvals.find(a => a.id === Number(id))?.amt || 0), 0))}
            </strong>
          </span>
          <span className="spacer" />
          <button className="btn btn-ghost" onClick={() => setSelected({})}>Clear</button>
          <button className="btn btn-primary" onClick={batchApprove}>
            <Icon name="check" size={14} /> Approve {selectedIds.length}
          </button>
        </div>
      )}

      {Object.entries(buckets).map(([urg, items]) => items.length > 0 && (
        <div className="card panel" key={urg} style={{ marginBottom: 16 }}>
          <div className="panel-head">
            <div className="eyebrow" style={{
              color: urg === 'today' ? 'var(--err)' : urg === 'tomorrow' ? 'var(--warn)' : 'var(--text-mid)',
            }}>{urg.toUpperCase()} ┬╖ {items.length}</div>
          </div>
          {items.map(a => (
            <div className={"approve-row " + (selected[a.id] ? 'checked' : '')} key={a.id}>
              <input type="checkbox" checked={!!selected[a.id]} onChange={() => toggle(a.id)} />
              <div className="ap-kind" data-kind={a.kind}>{a.kind}</div>
              <div>
                <div className="ap-title">{a.title}</div>
                <div className="ap-ctx"><AgentChip name={a.agent} /> ┬╖ {a.ctx}</div>
                {selected[a.id] && (
                  <div className="reason-box">
                    <Icon name="bot" size={12} style={{ color: 'var(--amber)' }} />
                    <input
                      type="text"
                      placeholder="Reason (optional ΓÇö captured in audit trail)"
                      value={reasons[a.id] || ''}
                      onChange={e => setReasons(r => ({ ...r, [a.id]: e.target.value }))}
                    />
                  </div>
                )}
                {showAudit[a.id] && (
                  <div className="audit-pop">
                    <h5>Audit history</h5>
                    {D.auditSample.map((row, i) => (
                      <div className="audit-row" key={i}>
                        <span className="who">{row.who}</span>
                        <span>{row.what}</span>
                        <time>{row.at.split(' ')[1]} {row.at.split(' ')[2]}</time>
                      </div>
                    ))}
                  </div>
                )}
              </div>
              {a.amt != null && <div className="ap-amt">{fmt(a.amt)}</div>}
              <div className="ap-act">
                <button className="btn btn-soft"
                        style={{padding:'6px 10px',fontSize:12}}
                        title="View audit trail"
                        onClick={() => setShowAudit(s => ({ ...s, [a.id]: !s[a.id] }))}>
                  <Icon name="eye" size={12} />
                </button>
                <button className="btn btn-soft" style={{padding:'6px 10px',fontSize:12}}>Review</button>
                <button className="btn btn-primary" style={{padding:'6px 10px',fontSize:12}}>Approve</button>
              </div>
            </div>
          ))}
        </div>
      ))}
    </div>
  );
};

// =================== WORKFLOW DRILLDOWN ΓÇö NEW ===================
const ScreenWorkflow = () => {
  const [live, setLive] = useState(false);
  const [txn, setTxn] = useState(D.workflows[0].id);
  const wf = D.workflows.find(w => w.id === txn) || D.workflows[0];

  return (
    <div className="screen">
      <SectionHead
        kicker="WORKFLOW DRILLDOWN"
        title="Trace any transaction end-to-end"
        sub="Watch a single invoice, PO, or journal entry travel through every stage ΓÇö including the agent tool-calls it triggered."
        actions={<>
          <div className="wf-toggle">
            <span>Mode</span>
            <span className={"pill " + (!live ? 'on' : '')} onClick={() => setLive(false)}>Demo</span>
            <span className={"pill " + (live ? 'on' : '')}   onClick={() => setLive(true)}>Live</span>
          </div>
        </>}
      />

      <div className="card panel" style={{ marginBottom: 16 }}>
        <div className="panel-head" style={{ alignItems: 'center' }}>
          <div>
            <div className="eyebrow">Pipeline</div>
            <h3 className="panel-title">{wf.label}</h3>
          </div>
          <select
            value={txn}
            onChange={e => setTxn(e.target.value)}
            style={{
              padding: '8px 12px', borderRadius: 10,
              background: 'var(--bg-2)', border: '1px solid var(--line)',
              color: 'var(--text-hi)', fontFamily: 'var(--font-mono)', fontSize: 13,
            }}
          >
            {D.workflows.map(w => <option key={w.id} value={w.id}>{w.label}</option>)}
          </select>
        </div>
        <div className="wf-pipeline">
          {wf.stages.map((s, i) => (
            <div key={s.id} className={"wf-stage " + (s.status === 'active' ? 'active' : '')}>
              <div className="stage-num">Stage {i + 1}</div>
              <h5>{s.label}</h5>
              <div className="stage-by"><Icon name={s.by === 'Claude' ? 'bot' : 'user'} size={11} />{s.by} ┬╖ {s.t}</div>
              <div className="stage-status">
                {s.status === 'done' && 'Γ£ô Complete'}
                {s.status === 'active' && 'ΓùÅ In flight'}
                {s.status === 'pending' && 'Γùï Pending'}
              </div>
              <div style={{ fontSize: 11.5, color: 'var(--text-lo)', marginTop: 6, lineHeight: 1.4 }}>{s.detail}</div>
              {i < wf.stages.length - 1 && <div className="wf-arrow"><Icon name="chevR" size={14} /></div>}
            </div>
          ))}
        </div>
      </div>

      <div className="card panel">
        <div className="panel-head">
          <div>
            <div className="eyebrow">Event stream {live && <span style={{ color: 'var(--ok)' }}>┬╖ LIVE</span>}</div>
            <h3 className="panel-title">Tool calls + database events</h3>
          </div>
          <span className="chip" style={{ color: live ? 'var(--ok)' : 'var(--text-mid)' }}>
            {live ? <><span className="live-dot" />Tailing</> : 'Replay'}
          </span>
        </div>
        <div className="wf-stream">
          {D.wfStream.map((r, i) => (
            <div className="stream-row" key={i}>
              <span className="t">{r.t}</span>
              <span className="ev">{r.ev}</span>
              <span className="body">{r.body}</span>
              <span className="amt">{r.amt}</span>
            </div>
          ))}
        </div>
        <div style={{ marginTop: 16, fontSize: 11, color: 'var(--text-lo)', fontFamily: 'var(--font-mono)' }}>
          {/* SUPABASE WIRE: subscribe to ap_audit_trail / ar_audit_trail / gl_audit_trail
              with .on('postgres_changes', { event: 'INSERT' }, payload => append(payload)) */}
          Demo events. Toggle Live to tail real audit-trail rows from Supabase.
        </div>
      </div>
    </div>
  );
};

// =================== AGENT FEED ===================
const ScreenFeed = () => (
  <div className="screen">
    <SectionHead
      kicker="AGENT ACTIVITY"
      title="Everything Claude has done"
      sub="Chronological. Every action attributed. Every call replayable."
      actions={<>
        <button className="btn btn-ghost"><Icon name="filter" size={14} /> All types</button>
        <button className="btn btn-ghost"><Icon name="download" size={14} /> Export</button>
      </>}
    />
    <div className="card panel">
      <div className="feed-list">
        {D.feed.map((f, i) => (
          <div className="feed-row" key={i} data-urg={f.urg}>
            <div className="feed-time">{f.t}</div>
            <div className="feed-line" />
            <div>
              <div className="feed-meta">
                <span className="rail-cat" data-cat={f.cat}>{f.cat}</span>
                <AgentChip name={f.who} />
                <span style={{
                  fontFamily: 'var(--font-mono)', fontSize: 9.5, padding: '2px 6px', borderRadius: 4,
                  background: f.urg === 'urgent' ? 'rgba(239,68,68,0.12)' : f.urg === 'action' ? 'rgba(251,191,36,0.14)' : 'var(--bg-3)',
                  color: f.urg === 'urgent' ? 'var(--err)' : f.urg === 'action' ? 'var(--warn)' : 'var(--text-mid)',
                  letterSpacing: 0.12, textTransform: 'uppercase',
                }}>{f.urg}</span>
              </div>
              <div className="feed-title">{f.title}</div>
              <div className="feed-desc">{f.desc}</div>
              <button className="btn btn-soft" style={{ marginTop: 8, padding: '6px 10px', fontSize: 12 }}>
                {f.cta} <Icon name="arrowR" size={12} />
              </button>
            </div>
          </div>
        ))}
      </div>
    </div>
  </div>
);

// =================== REPORTS ===================
const ScreenReports = () => {
  const pl = D.pl;
  const totalRev  = pl.revenue.reduce((s, r) => s + r.v, 0);
  const totalOpex = pl.opex.reduce((s, o) => s + o.v, 0);
  const gross = totalRev - pl.cogs;
  const net   = gross - totalOpex;
  return (
    <div className="screen">
      <SectionHead
        kicker="REPORTS ┬╖ YTD 2026"
        title="P&L ┬╖ Balance Sheet ┬╖ Trial Balance"
        sub="Snapshot generated 2 minutes ago by Claude."
        actions={<>
          <button className="btn btn-ghost"><Icon name="download" size={14} /> PDF</button>
          <button className="btn btn-ghost"><Icon name="download" size={14} /> CSV</button>
          <button className="btn btn-primary"><Icon name="refresh" size={14} /> Re-run</button>
        </>}
      />

      <div className="kpi-grid">
        <KpiCard label="Revenue YTD"  value={totalRev}   accent="emerald" />
        <KpiCard label="Gross profit" value={gross}      accent="amber" />
        <KpiCard label="OpEx YTD"     value={totalOpex}  accent="red" />
        <KpiCard label="Net income"   value={net}        accent="neutral" />
      </div>

      <div className="card panel">
        <div className="panel-head">
          <div>
            <div className="eyebrow">Profit &amp; loss</div>
            <h3 className="panel-title">YTD 2026 ┬╖ accrual</h3>
          </div>
        </div>
        <table className="lb-table report">
          <tbody>
            <tr className="grp"><td colSpan="2">REVENUE</td></tr>
            {pl.revenue.map(r => <tr key={r.name}><td>{r.name}</td><td className="mono num">{fmt(r.v)}</td></tr>)}
            <tr className="subtot"><td>Total revenue</td><td className="mono num">{fmt(totalRev)}</td></tr>

            <tr className="grp"><td colSpan="2">COST OF GOODS</td></tr>
            <tr><td>COGS ┬╖ Materials</td><td className="mono num">({fmt(pl.cogs)})</td></tr>
            <tr className="subtot"><td>Gross profit</td><td className="mono num" style={{color:'var(--amber)'}}>{fmt(gross)}</td></tr>

            <tr className="grp"><td colSpan="2">OPERATING EXPENSES</td></tr>
            {pl.opex.map(o => <tr key={o.name}><td>{o.name}</td><td className="mono num">({fmt(o.v)})</td></tr>)}
            <tr className="subtot"><td>Total OpEx</td><td className="mono num">({fmt(totalOpex)})</td></tr>

            <tr className="total"><td>NET INCOME</td><td className="mono num">{fmt(net)}</td></tr>
          </tbody>
        </table>
      </div>
    </div>
  );
};

// =================== SETTINGS ===================
const ScreenSettings = ({ setSetup }) => {
  const [tab, setTab] = useState('agents');
  return (
    <div className="screen">
      <SectionHead
        kicker="SETTINGS"
        title="Connect AI ┬╖ MCP ┬╖ Spend policies"
        sub="The wiring that lets your agent touch your books safely."
      />
      <div className="tabs">
        {[
          ['agents',   'Connected agents'],
          ['mcp',      'MCP tools'],
          ['policies', 'Spend policies'],
          ['team',     'Team'],
          ['billing',  'Billing'],
        ].map(([k, l]) => (
          <button key={k} className={"tab " + (tab===k ? 'on' : '')} onClick={() => setTab(k)}>{l}</button>
        ))}
      </div>

      {tab === 'agents' && (
        <div className="settings-grid">
          <div className="card panel">
            <div className="panel-head"><h3 className="panel-title">Your agents</h3><button className="btn btn-primary"><Icon name="plus" size={14} /> Add</button></div>
            <div className="agent-list">
              {D.agents.map((a, i) => (
                <div className="agent-card" key={i} data-primary={a.primary || false}>
                  <div className="agent-card-l">
                    <div className="ag-ava"><Icon name="bot" size={18} /></div>
                    <div>
                      <div className="ag-name">{a.name} {a.primary && <span className="chip" style={{background:'var(--amber-soft)',color:'var(--amber)',borderColor:'var(--amber)',marginLeft:6}}>primary</span>}</div>
                      <div className="ag-meta"><span className="mono">{a.via}</span> ┬╖ {a.scope} ┬╖ last seen {a.last}</div>
                    </div>
                  </div>
                  <div className="agent-card-r">
                    <span className="chip">
                      <span className="live-dot" style={{ background: a.status === 'active' ? 'var(--ok)' : 'var(--text-lo)' }} />
                      {a.status}
                    </span>
                    <button className="btn btn-ghost" style={{padding:'6px 10px',fontSize:12}}>Manage</button>
                  </div>
                </div>
              ))}
            </div>
          </div>

          <div className="card panel">
            <div className="panel-head"><h3 className="panel-title">Connect a new agent</h3></div>
            <p style={{ color: 'var(--text-mid)', fontSize: 14, marginBottom: 14 }}>Paste this into your agent's MCP config.</p>
            <div className="snippet">
              <div className="snippet-head"><span className="mono">mcp ┬╖ stdio</span><button className="btn btn-ghost" style={{padding:'4px 8px', fontSize:11}}><Icon name="copy" size={12} /> Copy</button></div>
              <pre>{`{
  "mcpServers": {
    "ledgerbeaver": {
      "url": "https://api.ledgerbeaver.com/mcp",
      "headers": { "Authorization": "Bearer $LB_API_KEY" }
    }
  }
}`}</pre>
            </div>
            <div style={{ display: 'flex', gap: 8, marginTop: 14 }}>
              <button className="btn btn-soft" style={{flex:1}}>Claude config</button>
              <button className="btn btn-soft" style={{flex:1}}>Cursor config</button>
              <button className="btn btn-soft" style={{flex:1}}>OpenClaw</button>
            </div>
          </div>
        </div>
      )}

      {tab === 'mcp' && (
        <div className="card panel">
          <div className="panel-head">
            <div>
              <div className="eyebrow">MCP tools ┬╖ 91 exposed</div>
              <h3 className="panel-title">Tool catalog</h3>
            </div>
            <button className="btn btn-ghost"><Icon name="search" size={14} /> Search</button>
          </div>
          <div className="mcp-grid">
            {D.mcpTools.map(t => (
              <div className="mcp-tool" key={t.ns + t.name}>
                <div className="mcp-ns" data-ns={t.ns}>{t.ns}</div>
                <div>
                  <div className="mcp-name mono">{t.name}<span style={{color:'var(--text-lo)'}}>()</span></div>
                  <div className="mcp-desc">{t.desc}</div>
                </div>
                <button className="btn btn-ghost" style={{padding:'4px 10px', fontSize:11}}>Schema</button>
              </div>
            ))}
          </div>
        </div>
      )}

      {tab === 'policies' && (
        <div className="card panel">
          <div className="panel-head"><h3 className="panel-title">Spend policies</h3><button className="btn btn-primary"><Icon name="plus" size={14} /> New rule</button></div>
          <div className="policy-list">
            <PolicyRow lhs="Invoices < $500" rhs="Auto-approve" />
            <PolicyRow lhs="Invoices $500 ΓÇô $5,000" rhs="Approve by any Manager" />
            <PolicyRow lhs="Invoices > $5,000" rhs="Approve by Sam (CFO) ΓÇö dual approval required" />
            <PolicyRow lhs="New vendor first payment" rhs="Hold for Sam, regardless of amount" />
            <PolicyRow lhs="Cloud / SaaS (acct 6010, 6015)" rhs="Auto-approve up to $1,000" />
            <PolicyRow lhs="Duplicate detection" rhs="Block + notify (cannot override)" />
          </div>
        </div>
      )}

      {tab === 'team' && (
        <div className="card panel">
          <div className="panel-head">
            <h3 className="panel-title">Your team</h3>
            <button className="btn btn-primary"><Icon name="send" size={14} /> Invite</button>
          </div>
          <div className="agent-list">
            {[
              { name: 'Sam Reyes',  email: 'sam@northgate.co',     role: 'Owner', status: 'active' },
              { name: 'Maya Vargas',email: 'maya@northgate.co',    role: 'Approver', status: 'active' },
              { name: 'Dean Park',  email: 'dean@accountants.co',  role: 'Accountant ┬╖ external', status: 'invited' },
            ].map((t, i) => (
              <div className="agent-card" key={i}>
                <div className="agent-card-l">
                  <div className="ag-ava" style={{ background: 'var(--amber)', color: 'var(--on-amber)' }}>{t.name.split(' ').map(p=>p[0]).join('')}</div>
                  <div>
                    <div className="ag-name">{t.name}</div>
                    <div className="ag-meta">{t.email} ┬╖ {t.role}</div>
                  </div>
                </div>
                <div className="agent-card-r">
                  <span className="chip"><span className="live-dot" style={{ background: t.status === 'active' ? 'var(--ok)' : 'var(--warn)' }} />{t.status}</span>
                </div>
              </div>
            ))}
          </div>
        </div>
      )}

      {tab === 'billing' && (
        <div className="card panel">
          <div className="panel-head"><h3 className="panel-title">Plan ┬╖ Pro ┬╖ $39.99/mo</h3><button className="btn btn-ghost">Manage</button></div>
          <p style={{color:'var(--text-mid)', maxWidth: 480}}>Renews Jun 4, 2026. Next invoice: $39.99. 3 of 3 agent slots used.</p>
        </div>
      )}
    </div>
  );
};

const PolicyRow = ({ lhs, rhs }) => (
  <div className="policy-row">
    <div className="policy-l"><span className="mono">IF</span> {lhs}</div>
    <Icon name="arrowR" size={14} />
    <div className="policy-r"><span className="mono">THEN</span> {rhs}</div>
    <button className="btn btn-ghost" style={{padding:'4px 8px', fontSize:11}}>Edit</button>
  </div>
);

/* ============================================================
   SCREEN: The Dam — Partner Hub (INLINE — same design as dam-v3.html)
   ============================================================ */
const ScreenDam = () => {
  const useState = React.useState;
  const useEffect = React.useEffect;
  const useMemo = React.useMemo;
  const useRef = React.useRef;

  /* -------- DATA (same as dam-v3.html) -------- */
  const SEED_PARTNERS = [
    { id: 'p001', name: 'Northgate Logistics', type: 'vendor', initials: 'NL', color: 'linear-gradient(135deg,#F97316,#FB923C)', email: 'ap@northgate.co', health: 'ok', healthLabel: 'Active', lastActivity: '2h ago', activityWhen: 'today, 14:02', openValue: '$48,200', contract: 'Renews Mar 12', contractStatus: 'ren', tags: ['preferred', 'net-30'], autoTags: ['high-volume'], description: 'Primary freight + last-mile logistics. Auto-detected from 47 invoices since 2023.', relationships: 3, opportunities: 2, stats: { totalSpend: '$612,400', avgDaysToPay: '6.4 days', invoices: 47, lastPayment: 'Apr 28' } },
    { id: 'p002', name: 'Lumi Studio', type: 'customer', initials: 'LS', color: 'linear-gradient(135deg,#10B981,#34D399)', email: 'billing@lumi.studio', health: 'warn', healthLabel: 'Watch', lastActivity: '6h ago', activityWhen: 'today, 09:48', openValue: '$12,400', contract: '2 months left', contractStatus: 'warn', tags: ['design-agency', 'monthly'], autoTags: ['slow-payer'], description: 'Recurring retainer customer. Last 2 invoices > 14 days.', relationships: 2, opportunities: 1, stats: { totalSpend: '$184,200', avgDaysToPay: '18.1 days', invoices: 22, lastPayment: 'Apr 11' } },
    { id: 'p003', name: 'Halcyon Cloud', type: 'vendor', initials: 'HC', color: 'linear-gradient(135deg,#A855F7,#C084FC)', email: 'finance@halcyon.cloud', health: 'ok', healthLabel: 'Active', lastActivity: '1d ago', activityWhen: 'yesterday, 16:31', openValue: '$8,920', contract: 'Auto-renew Jul', contractStatus: 'ok', tags: ['infrastructure', 'usage-based'], autoTags: [], description: 'Cloud infrastructure provider. Monthly usage-based billing.', relationships: 1, opportunities: 0, stats: { totalSpend: '$104,800', avgDaysToPay: '3.2 days', invoices: 14, lastPayment: 'May 2' } },
    { id: 'p004', name: 'Bramble & Co.', type: 'customer', initials: 'BC', color: 'linear-gradient(135deg,#F59E0B,#FCD34D)', email: 'accounts@brambleco.com', health: 'err', healthLabel: 'Overdue', lastActivity: '3d ago', activityWhen: 'May 12', openValue: '$24,800', contract: 'Expires May 28', contractStatus: 'ren', tags: ['enterprise', 'net-45'], autoTags: ['churn-risk'], description: 'Long-running enterprise customer. Invoice #INV-2384 is 11 days overdue.', relationships: 4, opportunities: 1, stats: { totalSpend: '$1.2M', avgDaysToPay: '38.7 days', invoices: 91, lastPayment: 'Mar 22' } },
    { id: 'p005', name: 'Pinegrove Legal', type: 'partner', initials: 'PL', color: 'linear-gradient(135deg,#7E22CE,#A855F7)', email: 'counsel@pinegrovelegal.com', health: 'info', healthLabel: 'Invited', lastActivity: 'invited 2d ago', activityWhen: 'May 13', openValue: '—', contract: 'Pending', contractStatus: 'pending', tags: ['legal', 'partner'], autoTags: [], description: 'External counsel. Invited to vendor portal — pending registration.', relationships: 0, opportunities: 0, stats: { totalSpend: '—', avgDaysToPay: '—', invoices: 0, lastPayment: '—' } },
    { id: 'p006', name: 'Mara Chen', type: 'internal', initials: 'MC', color: 'linear-gradient(135deg,#E8650D,#F97316)', email: 'mara@ledgerbeaver.com', health: 'ok', healthLabel: 'Active', lastActivity: '12m ago', activityWhen: 'today, 16:18', openValue: '—', contract: '—', contractStatus: 'none', tags: ['controller', 'approver'], autoTags: [], description: 'Internal · Finance Controller. Approves invoices > $5k.', relationships: 8, opportunities: 0, stats: { totalSpend: '—', avgDaysToPay: '—', invoices: 0, lastPayment: '—' } },
    { id: 'p007', name: 'Riverbend Catering', type: 'vendor', initials: 'RC', color: 'linear-gradient(135deg,#C2410C,#EA580C)', email: 'invoices@riverbend.com', health: 'ok', healthLabel: 'Active', lastActivity: '5d ago', activityWhen: 'May 11', openValue: '$2,140', contract: 'No contract', contractStatus: 'none', tags: ['adhoc'], autoTags: ['new'], description: 'New vendor · 3 invoices · added by agent during AP run on May 4.', relationships: 0, opportunities: 0, stats: { totalSpend: '$6,420', avgDaysToPay: '4.0 days', invoices: 3, lastPayment: 'May 6' } },
    { id: 'p008', name: 'Cascade Insurance', type: 'vendor', initials: 'CI', color: 'linear-gradient(135deg,#0E7490,#06B6D4)', email: 'billing@cascade.ins', health: 'warn', healthLabel: 'Watch', lastActivity: '2d ago', activityWhen: 'May 14', openValue: '$18,400', contract: 'Renews Jun 1', contractStatus: 'ren', tags: ['insurance', 'annual'], autoTags: ['renewal-soon'], description: 'Annual policy renewal in 15 days. Premium increase detected: +8%.', relationships: 1, opportunities: 0, stats: { totalSpend: '$84,000', avgDaysToPay: '14 days', invoices: 4, lastPayment: 'Feb 1' } },
    { id: 'p009', name: 'Otter & Sons Furniture', type: 'customer', initials: 'OS', color: 'linear-gradient(135deg,#047857,#10B981)', email: 'orders@ottersons.com', health: 'ok', healthLabel: 'Active', lastActivity: '4h ago', activityWhen: 'today, 12:10', openValue: '$6,200', contract: 'N/A', contractStatus: 'none', tags: ['wholesale', 'net-15'], autoTags: [], description: 'Wholesale customer · pays on time · 14 invoices in past year.', relationships: 2, opportunities: 2, stats: { totalSpend: '$94,000', avgDaysToPay: '11.2 days', invoices: 14, lastPayment: 'May 8' } },
    { id: 'p010', name: 'Marsh & Holloway LLP', type: 'partner', initials: 'MH', color: 'linear-gradient(135deg,#6D28D9,#8B5CF6)', email: 'partners@marshholloway.com', health: 'ok', healthLabel: 'Active', lastActivity: '1w ago', activityWhen: 'May 9', openValue: '—', contract: '12 months left', contractStatus: 'ok', tags: ['audit', 'annual'], autoTags: [], description: 'External audit partner. Annual engagement.', relationships: 2, opportunities: 0, stats: { totalSpend: '$72,000', avgDaysToPay: '7.5 days', invoices: 6, lastPayment: 'Apr 30' } },
    { id: 'p011', name: 'Ferguson Print Co.', type: 'vendor', initials: 'FP', color: 'linear-gradient(135deg,#B45309,#F59E0B)', email: 'ap@fergusonprint.com', health: 'ok', healthLabel: 'Active', lastActivity: '3w ago', activityWhen: 'Apr 24', openValue: '$0', contract: 'No contract', contractStatus: 'none', tags: ['print', 'adhoc'], autoTags: [], description: 'Occasional vendor · stationary, marketing collateral.', relationships: 0, opportunities: 0, stats: { totalSpend: '$3,800', avgDaysToPay: '8.0 days', invoices: 5, lastPayment: 'Apr 24' } },
    { id: 'p012', name: 'Saoirse Donnelly', type: 'internal', initials: 'SD', color: 'linear-gradient(135deg,#7E22CE,#C084FC)', email: 'saoirse@ledgerbeaver.com', health: 'ok', healthLabel: 'Active', lastActivity: '3h ago', activityWhen: 'today, 13:20', openValue: '—', contract: '—', contractStatus: 'none', tags: ['cfo', 'approver'], autoTags: [], description: 'Internal · CFO. Final approver for invoices > $25k.', relationships: 6, opportunities: 0, stats: { totalSpend: '—', avgDaysToPay: '—', invoices: 0, lastPayment: '—' } },
  ];

  const [partners] = useState(SEED_PARTNERS);
  const [openPartner, setOpenPartner] = useState(null);
  const [filter, setFilter] = useState('all');
  const [search, setSearch] = useState('');

  const filtered = partners.filter(p => {
    if (filter !== 'all' && p.type !== filter) return false;
    if (search && !p.name.toLowerCase().includes(search.toLowerCase())) return false;
    return true;
  });

  const counts = { all: partners.length, vendor: 0, customer: 0, internal: 0, partner: 0 };
  partners.forEach(p => counts[p.type]++);

  return (
    <div className="screen">
      <style>{`
        .dam-hero { display: grid; grid-template-columns: 1.25fr 0.85fr; gap: 32px; border: 1px solid var(--line); border-radius: 24px; overflow: hidden; background: radial-gradient(800px 320px at 12% 8%, color-mix(in oklab, var(--amber) 18%, transparent), transparent 60%), linear-gradient(180deg, var(--bg-2) 0%, var(--bg-1) 100%); box-shadow: var(--shadow-pop); }
        .dam-hero-left { padding: 36px; display: flex; flex-direction: column; gap: 16px; }
        .dam-hero-h { font-family: var(--font-display); font-weight: 700; font-size: clamp(32px, 3.5vw, 48px); line-height: 1.05; letter-spacing: -0.03em; color: var(--text-hi); margin: 0; }
        .dam-hero-h span { color: var(--amber); }
        .dam-hero-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-top: 8px; }
        .dam-hero-stat { padding: 14px; border: 1px solid var(--line); background: color-mix(in oklab, var(--bg-2) 70%, transparent); border-radius: 12px; }
        .dam-hero-stat .n { font-family: var(--font-display); font-weight: 700; font-size: 22px; color: var(--text-hi); }
        .dam-hero-stat .l { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.14em; color: var(--text-lo); text-transform: uppercase; margin-top: 2px; }
        .dam-hero-stat .d { font-size: 11px; color: var(--ok); font-family: var(--font-mono); margin-top: 4px; }
        .dam-hero-stat .d.warn { color: var(--warn); }
        .dam-pins { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-top: 20px; }
        .dam-pin { background: var(--bg-2); border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px; cursor: pointer; transition: all .15s; text-align: left; color: inherit; font-family: inherit; font-size: inherit; border: none; }
        .dam-pin:hover { border-color: var(--line-2); transform: translateY(-1px); background: var(--bg-3); }
        .dam-pin .pin-top { display: flex; align-items: center; gap: 8px; }
        .dam-pin .pin-ico { width: 22px; height: 22px; border-radius: 6px; display: grid; place-items: center; flex-shrink: 0; background: var(--amber-soft); color: var(--amber); }
        .dam-pin .pin-title { font-size: 13px; font-weight: 600; color: var(--text-hi); }
        .dam-pin .pin-n { font-family: var(--font-display); font-weight: 700; font-size: 22px; color: var(--text-hi); letter-spacing: -0.02em; margin-top: 4px; }
        .dam-pin .pin-sub { font-family: var(--font-mono); font-size: 10.5px; color: var(--text-mid); }
        .dam-table { width: 100%; border-collapse: collapse; font-size: 13px; margin-top: 16px; }
        .dam-table thead th { text-align: left; padding: 10px 16px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-lo); font-weight: 600; background: var(--bg-1); border-bottom: 1px solid var(--line); }
        .dam-table tbody tr { border-bottom: 1px solid var(--line); cursor: pointer; transition: background .12s; }
        .dam-table tbody tr:hover { background: var(--bg-3); }
        .dam-table td { padding: 12px 16px; color: var(--text); vertical-align: middle; }
        .dam-partner-cell { display: flex; align-items: center; gap: 12px; }
        .dam-pavatar { width: 32px; height: 32px; border-radius: 8px; display: grid; place-items: center; font-weight: 700; font-size: 12px; color: white; flex-shrink: 0; }
        .dam-pname { display: flex; flex-direction: column; }
        .dam-pname .n { font-weight: 600; color: var(--text-hi); font-size: 13.5px; }
        .dam-pname .e { font-family: var(--font-mono); font-size: 11px; color: var(--text-lo); }
        .dam-type-chip { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; border: 1px solid currentColor; }
        .dam-type-chip .d { width: 5px; height: 5px; border-radius: 999px; background: currentColor; }
        .dam-type-vendor { color: var(--ap); }
        .dam-type-customer { color: var(--ar); }
        .dam-type-internal { color: var(--amber); }
        .dam-type-partner { color: var(--gl); }
        .dam-health { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 500; }
        .dam-health-dot { width: 7px; height: 7px; border-radius: 999px; }
        .dam-health-ok { color: var(--ok); } .dam-health-ok .dam-health-dot { background: var(--ok); }
        .dam-health-warn { color: var(--warn); } .dam-health-warn .dam-health-dot { background: var(--warn); }
        .dam-health-err { color: var(--err); } .dam-health-err .dam-health-dot { background: var(--err); }
        .dam-health-info { color: var(--info); } .dam-health-info .dam-health-dot { background: var(--info); }
        .dam-tag { padding: 1px 7px; border-radius: 4px; background: var(--bg-1); border: 1px solid var(--line); font-family: var(--font-mono); font-size: 10px; color: var(--text-mid); }
        .dam-tag-auto { color: var(--amber); border-color: color-mix(in oklab, var(--amber) 40%, transparent); background: var(--amber-soft); }
        .dam-value { font-family: var(--font-mono); font-weight: 600; color: var(--text-hi); text-align: right; }
        .dam-contract .ren { color: var(--warn); }
        .dam-contract .ok { color: var(--ok); }
        @media (max-width: 1024px) { .dam-hero { grid-template-columns: 1fr; } .dam-hero-stats { grid-template-columns: repeat(2, 1fr); } .dam-pins { grid-template-columns: repeat(2, 1fr); } }
      `}</style>

      {/* Hero */}
      <div className="dam-hero" style={{marginTop: 20}}>
        <div className="dam-hero-left">
          <span style={{display: 'inline-flex', alignItems: 'center', gap: 8, padding: '5px 12px 5px 8px', background: 'var(--bg-3)', border: '1px solid var(--line)', borderRadius: 999, fontFamily: 'var(--font-mono)', fontSize: 11, fontWeight: 600, letterSpacing: '0.06em', color: 'var(--text)'}}>
            <span style={{width: 7, height: 7, background: 'var(--amber)', borderRadius: '50%'}} />
            The Dam · Partner Hub · live
          </span>
          <h1 className="dam-hero-h">
            Every partner,<br />
            <span>stitched together by the dam.</span>
          </h1>
          <p style={{color: 'var(--text-mid)', fontSize: 15, lineHeight: 1.6, maxWidth: 560, margin: 0}}>
            A living directory that <strong style={{color: 'var(--text-hi)'}}>auto-grows from every invoice, contract, and message</strong> your agent handles.
          </p>
          <div className="dam-hero-stats">
            <div className="dam-hero-stat"><div className="n">124</div><div className="l">Partners</div><div className="d">▲ 9 this month</div></div>
            <div className="dam-hero-stat"><div className="n">$1.84M</div><div className="l">Open value</div><div className="d">▲ 4.2%</div></div>
            <div className="dam-hero-stat"><div className="n">7</div><div className="l">Opportunities</div><div className="d">across 5 partners</div></div>
            <div className="dam-hero-stat"><div className="n">3</div><div className="l">Renewing ≤ 30d</div><div className="d warn">▲ 2 need review</div></div>
          </div>
          <div style={{display: 'flex', gap: 10, marginTop: 8, flexWrap: 'wrap'}}>
            <button className="btn btn-primary" style={{padding: '11px 18px', fontSize: 14}} onClick={() => alert('Add partner — coming soon')}>+ Add partner</button>
            <button className="btn btn-ghost" style={{padding: '11px 18px', fontSize: 14}} onClick={() => alert('Invite — coming soon')}>Invite vendor</button>
          </div>
        </div>
        <div style={{position: 'relative', background: 'radial-gradient(600px 400px at 70% 30%, color-mix(in oklab, var(--amber) 14%, transparent), transparent 60%), linear-gradient(160deg, color-mix(in oklab, var(--ar) 12%, transparent) 0%, transparent 50%), var(--bg-3)', borderLeft: '1px solid var(--line)', overflow: 'hidden', minHeight: 360}}>
          <img src="assets/dam-illustration.jpg" alt="" style={{position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', objectPosition: 'center 40%'}} />
          <div style={{position: 'absolute', inset: 0, background: 'linear-gradient(180deg, transparent 50%, color-mix(in oklab, var(--bg-1) 60%, transparent) 100%)', pointerEvents: 'none'}} />
          <span style={{position: 'absolute', left: 18, bottom: 16, zIndex: 2, display: 'inline-flex', alignItems: 'center', gap: 6, padding: '6px 10px', borderRadius: 8, background: 'color-mix(in oklab, var(--bg-1) 85%, transparent)', border: '1px solid var(--line)', fontFamily: 'var(--font-mono)', fontSize: 10.5, color: 'var(--text-mid)', backdropFilter: 'blur(8px)'}}>
            ✨ Auto-built from your books
          </span>
        </div>
      </div>

      {/* Pinned Views */}
      <div className="dam-pins">
        {[
          { title: 'Renewing in 30 days', n: 3, sub: '2 need review', tone: 'var(--warn)' },
          { title: 'New since you visited', n: 5, sub: 'added by agent', tone: 'var(--amber)' },
          { title: 'Top vendors by spend', n: 8, sub: '$612k+ this year', tone: 'var(--ok)' },
          { title: 'Awaiting your reply', n: 4, sub: 'across 3 partners', tone: 'var(--info)' },
        ].map((p, i) => (
          <button key={i} className="dam-pin" onClick={() => alert(`Filter: ${p.title}`)}>
            <div className="pin-top">
              <div className="pin-ico" style={{background: `color-mix(in oklab, ${p.tone} 18%, transparent)`, color: p.tone}}>●</div>
              <div className="pin-title">{p.title}</div>
            </div>
            <div className="pin-n">{p.n}</div>
            <div className="pin-sub">{p.sub}</div>
          </button>
        ))}
      </div>

      {/* Filter Bar */}
      <div className="dam-toolbar" style={{marginTop: 24, display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap'}}>
        <div className="dam-chips">
          {['all', 'vendor', 'customer', 'partner', 'internal'].map(t => (
            <button key={t} className={`dam-chip ${filter === t ? 'on' : ''}`} onClick={() => setFilter(t)}>
              {t[0].toUpperCase() + t.slice(1)}
              <span className="n">{counts[t]}</span>
            </button>
          ))}
        </div>
        <div style={{flex: 1}} />
        <div className="dam-search">
          <input type="text" placeholder="Search partners..." value={search} onChange={e => setSearch(e.target.value)} />
        </div>
      </div>

      {/* Directory Table */}
      <table className="dam-table">
        <thead>
          <tr>
            <th>Partner</th>
            <th>Type</th>
            <th>Health</th>
            <th>Open Value</th>
            <th>Contract</th>
            <th>Tags</th>
          </tr>
        </thead>
        <tbody>
          {filtered.map(p => (
            <tr key={p.id} onClick={() => setOpenPartner(p)}>
              <td>
                <div className="dam-partner-cell">
                  <div className="dam-pavatar" style={{background: p.color}}>{p.initials}</div>
                  <div className="dam-pname">
                    <div className="n">{p.name}</div>
                    <div className="e">{p.email}</div>
                  </div>
                </div>
              </td>
              <td>
                <span className={`dam-type-chip dam-type-${p.type}`}>
                  <span className="d" />
                  {p.type === 'internal' ? 'Internal' : p.type === 'partner' ? 'Partner' : p.type === 'customer' ? 'Customer' : 'Vendor'}
                </span>
              </td>
              <td>
                <span className={`dam-health dam-health-${p.health}`}>
                  <span className="dam-health-dot" />
                  {p.healthLabel}
                </span>
              </td>
              <td className="dam-value">{p.openValue}</td>
              <td className="dam-contract">
                <span className={p.contractStatus === 'ren' ? 'ren' : p.contractStatus === 'ok' ? 'ok' : ''}>{p.contract}</span>
              </td>
              <td>
                <div style={{display: 'flex', gap: 4, flexWrap: 'wrap'}}>
                  {p.tags.map(t => <span key={t} className="dam-tag">{t}</span>)}
                  {p.autoTags.map(t => <span key={t} className="dam-tag dam-tag-auto">⚡ {t}</span>)}
                </div>
              </td>
            </tr>
          ))}
        </tbody>
      </table>

      {/* Slide-over Panel */}
      {openPartner && (
        <div className="dam-overlay" style={{position: 'fixed', inset: 0, background: 'color-mix(in oklab, black 50%, transparent)', zIndex: 90}} onClick={() => setOpenPartner(null)}>
          <aside style={{position: 'fixed', right: 0, top: 0, bottom: 0, width: 'min(720px, 92vw)', background: 'var(--bg-1)', borderLeft: '1px solid var(--line)', zIndex: 91, padding: '20px 24px', overflowY: 'auto'}} onClick={e => e.stopPropagation()}>
            <div style={{display: 'flex', alignItems: 'center', gap: 14, marginBottom: 20}}>
              <div className="dam-pavatar" style={{background: openPartner.color, width: 44, height: 44, fontSize: 16}}>{openPartner.initials}</div>
              <div>
                <div style={{fontFamily: 'var(--font-display)', fontWeight: 700, fontSize: 20, color: 'var(--text-hi)'}}>{openPartner.name}</div>
                <div style={{fontFamily: 'var(--font-mono)', fontSize: 11.5, color: 'var(--text-mid)'}}>{openPartner.email} · {openPartner.lastActivity}</div>
              </div>
              <button style={{marginLeft: 'auto', width: 34, height: 34, borderRadius: 8, background: 'var(--bg-2)', border: '1px solid var(--line)', color: 'var(--text-mid)', cursor: 'pointer'}} onClick={() => setOpenPartner(null)}>✕</button>
            </div>
            <p style={{fontSize: 13, color: 'var(--text-mid)', lineHeight: 1.5, marginBottom: 16}}>{openPartner.description}</p>
            <div style={{display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10, marginBottom: 20}}>
              <div style={{padding: 12, background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 10}}>
                <div style={{fontSize: 9, fontFamily: 'var(--font-mono)', color: 'var(--text-lo)', letterSpacing: '0.16em', textTransform: 'uppercase'}}>Spend</div>
                <div style={{fontSize: 18, fontWeight: 700, color: 'var(--text-hi)', marginTop: 2}}>{openPartner.stats.totalSpend}</div>
              </div>
              <div style={{padding: 12, background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 10}}>
                <div style={{fontSize: 9, fontFamily: 'var(--font-mono)', color: 'var(--text-lo)', letterSpacing: '0.16em', textTransform: 'uppercase'}}>Avg Pay</div>
                <div style={{fontSize: 18, fontWeight: 700, color: 'var(--text-hi)', marginTop: 2}}>{openPartner.stats.avgDaysToPay}</div>
              </div>
              <div style={{padding: 12, background: 'var(--bg-2)', border: '1px solid var(--line)', borderRadius: 10}}>
                <div style={{fontSize: 9, fontFamily: 'var(--font-mono)', color: 'var(--text-lo)', letterSpacing: '0.16em', textTransform: 'uppercase'}}>Invoices</div>
                <div style={{fontSize: 18, fontWeight: 700, color: 'var(--text-hi)', marginTop: 2}}>{openPartner.stats.invoices}</div>
              </div>
            </div>
            <div style={{display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 16}}>
              {openPartner.tags.map(t => <span key={t} className="dam-tag">{t}</span>)}
              {openPartner.autoTags.map(t => <span key={t} className="dam-tag dam-tag-auto">⚡ {t}</span>)}
            </div>
          </aside>
        </div>
      )}
    </div>
  );
};

window.LBScreens = {
  console:   ScreenConsole,
  setup:     ScreenSetup,
  ap:        ScreenAP,
  ar:        ScreenAR,
  gl:        ScreenGL,
  approvals: ScreenApprovals,
  workflow:  ScreenWorkflow,
  feed:      ScreenFeed,
  reports:   ScreenReports,
  settings:  ScreenSettings,
  dam:       ScreenDam,
};
