function Campaigns() {
  const [filter, setFilter] = React.useState('all');
  const filtered = CAMPAIGNS.filter(c => filter === 'all' ? true : c.channel === filter);

  const totalSpend = CAMPAIGNS.reduce((s, c) => s + c.spend, 0);
  const totalBooked = CAMPAIGNS.reduce((s, c) => s + c.booked, 0);
  const totalClicked = CAMPAIGNS.reduce((s, c) => s + c.clicked, 0);

  return (
    <div>
      <div className="page-hd">
        <div className="page-hd-l">
          <div className="page-eyebrow">Marketing · {CAMPAIGNS.filter(c => c.status === 'live').length} live</div>
          <h1 className="page-title">Campaigns</h1>
          <div className="page-sub">Outbound, paid, lifecycle. All channels in one ledger — with the agents running them attributed end-to-end.</div>
        </div>
        <div className="page-hd-r">
          <button className="btn" data-handled="1" onClick={() => window.toast('Date range picker', 'info', 'Pick a custom window')}><Icon.Calendar className="icon"/>May 2026</button>
          <button className="btn primary" data-handled="1" onClick={() => window.runAction('newCampaign')}><Icon.Plus className="icon"/>New campaign</button>
        </div>
      </div>

      <div style={{ padding: 24, display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 14 }}>
        <KpiBlock label="SPEND · MTD" val={(totalSpend / 1000).toFixed(1)} unit="$k" delta="+18%" deltaBad stream={fakeStream(11, 14, 80, 25)}/>
        <KpiBlock label="MEETINGS BOOKED" val={totalBooked} delta="+42%" stream={fakeStream(12, 14, 18, 14)}/>
        <KpiBlock label="CAC" val="42" unit="$" delta="-31%" deltaGood stream={fakeStream(13, 14, 60, 20).map(v => 80 - v * 0.3)}/>
        <KpiBlock label="ENGAGED" val={(totalClicked / 1000).toFixed(1)} unit="k" delta="+24%" stream={fakeStream(14, 14, 30, 15)}/>
      </div>

      <div style={{ padding: '0 24px 24px' }}>
        <div className="panel">
          <div className="panel-hd">
            <h3>All campaigns</h3>
            <div className="row" style={{ gap: 8 }}>
              <div className="segmented">
                {['all', 'EMAIL', 'PAID', 'SOCIAL', 'SMS', 'EVENT', 'AUTO'].map(c => (
                  <button key={c} className={filter === c ? 'active' : ''} onClick={() => setFilter(c)}>{c.toUpperCase()}</button>
                ))}
              </div>
            </div>
          </div>
          <div>
            <table className="dem">
              <thead>
                <tr>
                  <th>Campaign</th><th>Channel</th><th>Owner</th><th>Status</th>
                  <th>Reach</th><th>Engaged</th><th>Booked</th><th>Spend</th><th>CAC</th><th>Trend</th>
                </tr>
              </thead>
              <tbody>
                {filtered.map(c => {
                  const reach = c.sent > 0 ? c.sent : c.opened;
                  const engaged = c.replied + c.clicked;
                  const cac = c.booked > 0 ? (c.spend / c.booked).toFixed(0) : '—';
                  return (
                    <tr key={c.id}>
                      <td>
                        <div className="col" style={{ gap: 2 }}>
                          <span>{c.name}</span>
                          <span className="faint mono" style={{ fontSize: 10 }}>{c.id} · started May 4</span>
                        </div>
                      </td>
                      <td><span className={`channel-chip ${c.channel.toLowerCase()}`}>{c.channel}</span></td>
                      <td><span className="mono gradient-text" style={{ fontSize: 11, fontWeight: 600 }}>{c.owner.toUpperCase()}</span></td>
                      <td><StatusTag status={c.status}/></td>
                      <td className="num">{reach.toLocaleString()}</td>
                      <td className="num">{engaged.toLocaleString()}</td>
                      <td className="num" style={{ color: c.booked > 0 ? 'var(--cyan)' : 'var(--text-faint)' }}>{c.booked || '—'}</td>
                      <td className="num">{c.spend > 0 ? '£' + c.spend.toLocaleString() : '—'}</td>
                      <td className="num">{cac !== '—' ? '£' + cac : '—'}</td>
                      <td><Sparkline data={fakeStream(c.id.charCodeAt(1), 18, 12, 8)} w={70} h={18} gradient/></td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        </div>
      </div>

      <div style={{ padding: '0 24px 36px', display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 14 }}>
        <div className="panel">
          <div className="panel-hd">
            <h3>Spend vs. booked · last 30 days</h3>
            <span className="panel-meta">£16,632 spent → 313 booked</span>
          </div>
          <div className="panel-body">
            <div style={{ height: 240, position: 'relative' }}>
              <svg width="100%" height="100%" viewBox="0 0 800 240" preserveAspectRatio="none">
                <defs>
                  <linearGradient id="spend-grad" x1="0" x2="0" y1="0" y2="1">
                    <stop offset="0%" stopColor="#ff7ad9" stopOpacity="0.35"/>
                    <stop offset="100%" stopColor="#ff7ad9" stopOpacity="0"/>
                  </linearGradient>
                  <linearGradient id="book-grad" x1="0" x2="0" y1="0" y2="1">
                    <stop offset="0%" stopColor="#4be8ff" stopOpacity="0.35"/>
                    <stop offset="100%" stopColor="#4be8ff" stopOpacity="0"/>
                  </linearGradient>
                </defs>
                {/* grid */}
                {[0, 0.25, 0.5, 0.75, 1].map(y => (
                  <line key={y} x1="0" x2="800" y1={y * 240} y2={y * 240} stroke="rgba(255,255,255,0.05)" strokeWidth="0.5"/>
                ))}
                <path d={areaPath(fakeStream(20, 30, 40, 25), 800, 240, 0.1)} fill="url(#spend-grad)"/>
                <path d={linePath(fakeStream(20, 30, 40, 25), 800, 240, 0.1)} fill="none" stroke="#ff7ad9" strokeWidth="1.5"/>
                <path d={areaPath(fakeStream(21, 30, 30, 18), 800, 240, 0.1)} fill="url(#book-grad)"/>
                <path d={linePath(fakeStream(21, 30, 30, 18), 800, 240, 0.1)} fill="none" stroke="#4be8ff" strokeWidth="1.5"/>
              </svg>
              <div style={{ position: 'absolute', top: 0, right: 0, display: 'flex', gap: 14, fontSize: 11, fontFamily: 'var(--font-mono)' }}>
                <span className="row" style={{ gap: 5 }}><span style={{ width: 10, height: 2, background: '#ff7ad9' }}/>spend</span>
                <span className="row" style={{ gap: 5 }}><span style={{ width: 10, height: 2, background: '#4be8ff' }}/>booked</span>
              </div>
            </div>
            <div className="row faint mono" style={{ fontSize: 10, marginTop: 6, justifyContent: 'space-between' }}>
              <span>APR 22</span><span>APR 29</span><span>MAY 6</span><span>MAY 13</span><span>MAY 20</span>
            </div>
          </div>
        </div>

        <div className="panel">
          <div className="panel-hd">
            <h3><Icon.Sparkles style={{ width: 14, height: 14 }} className="gradient-text"/>AI insights</h3>
            <span className="tag live">3 new</span>
          </div>
          <div>
            {[
              { hint: 'PROMOTE', ttl: '"Founders v3" beats v2 by 41%', sub: 'A/B significant after 4 days. Calliope suggests promoting to all founders segment.', cta: 'Promote' },
              { hint: 'OPTIMIZE', ttl: 'Meta CPA up 38% on "Demiurge for ops"', sub: 'Audience overlap with "Founders" campaign. Orion suggests excluding shared audience.', cta: 'Apply' },
              { hint: 'WARN', ttl: 'SMS unsubscribes elevated', sub: 'D14 sequence — opt-out rate 2.1× baseline. Consider revising step 2 copy.', cta: 'Review' },
              { hint: 'INSIGHT', ttl: 'Tuesday 10:30 BST = peak reply window', sub: 'Atlas 2.4× reply rate on Tues 10-11 BST. Shift outbound batch by 90m?', cta: 'Schedule' },
            ].map((s, i) => {
              const hintColor = s.hint === 'WARN' ? 'var(--warn)' : s.hint === 'PROMOTE' ? 'var(--cyan)' : 'var(--violet)';
              return (
                <div key={i} style={{ padding: '14px 18px', borderBottom: i < 3 ? '1px solid var(--border)' : 'none' }}>
                  <div className="row" style={{ gap: 8, marginBottom: 6 }}>
                    <span className="mono" style={{ fontSize: 9, color: hintColor, letterSpacing: '0.14em' }}>{s.hint}</span>
                    <span style={{ fontSize: 13 }}>{s.ttl}</span>
                  </div>
                  <div className="dim" style={{ fontSize: 11, marginBottom: 8, lineHeight: 1.5 }}>{s.sub}</div>
                  <button className="btn sm">{s.cta}</button>
                </div>
              );
            })}
          </div>
        </div>
      </div>
    </div>
  );
}

window.Campaigns = Campaigns;
