// ============================================================
// DEMIURGE · GLOBAL ACTIONS REGISTRY
// Every named CTA in the app routes here. No dead UI.
// ============================================================

// ---------- shared style atoms (modal forms) ----------
const _label = { fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text-faint)', textTransform: 'uppercase', letterSpacing: '0.14em', marginBottom: 6, display: 'block' };
const _input = { width: '100%', padding: '8px 12px', background: 'rgba(0,0,0,0.3)', border: '1px solid var(--border)', borderRadius: 'var(--radius)', fontSize: 13, color: 'var(--text)' };
const _row   = { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 };
const _grid  = (n) => ({ display: 'grid', gridTemplateColumns: `repeat(${n}, 1fr)`, gap: 8 });
const _card  = (active) => ({
  padding: 10, borderRadius: 6, cursor: 'pointer',
  border: `1px solid ${active ? 'rgba(75,232,255,0.5)' : 'var(--border)'}`,
  background: active ? 'rgba(75,232,255,0.08)' : 'rgba(255,255,255,0.02)',
  display: 'flex', flexDirection: 'column', gap: 4,
  transition: 'all 0.15s',
});
const _hint  = { fontSize: 10.5, color: 'var(--text-dim)', lineHeight: 1.4 };

// Generic chip-grid picker
function ChipGrid({ value, onChange, options, cols = 3, multi = false }) {
  const isOn = (k) => multi ? (value || []).includes(k) : value === k;
  const toggle = (k) => {
    if (multi) {
      const v = value || [];
      onChange(v.includes(k) ? v.filter(x => x !== k) : [...v, k]);
    } else onChange(k);
  };
  return (
    <div style={_grid(cols)}>
      {options.map(o => {
        const k = typeof o === 'string' ? o : o.k;
        const label = typeof o === 'string' ? o : o.label;
        const sub   = typeof o === 'object' ? o.sub : null;
        return (
          <div key={k} style={_card(isOn(k))} onClick={() => toggle(k)}>
            <div style={{ fontSize: 12.5, color: 'var(--text)', fontWeight: 500 }}>{label}</div>
            {sub && <div style={_hint}>{sub}</div>}
          </div>
        );
      })}
    </div>
  );
}

// Stepper for wizards
function Stepper({ steps, current }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginBottom: 18 }}>
      {steps.map((s, i) => (
        <React.Fragment key={s}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6, color: i <= current ? 'var(--text)' : 'var(--text-faint)' }}>
            <div style={{
              width: 18, height: 18, borderRadius: '50%',
              display: 'grid', placeItems: 'center',
              background: i < current ? 'var(--iridescent)' : i === current ? 'rgba(75,232,255,0.18)' : 'rgba(255,255,255,0.04)',
              border: `1px solid ${i === current ? 'rgba(75,232,255,0.5)' : 'var(--border)'}`,
              color: i < current ? '#07091a' : 'inherit',
              fontFamily: 'var(--font-mono)', fontSize: 9, fontWeight: 700,
            }}>{i < current ? '✓' : i + 1}</div>
            <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase' }}>{s}</span>
          </div>
          {i < steps.length - 1 && <div style={{ flex: 1, height: 1, background: i < current ? 'var(--iridescent)' : 'var(--border)' }}/>}
        </React.Fragment>
      ))}
    </div>
  );
}

// Animated progress used by "Run AI Audit", "Run Workflow", "Run Deep Analysis"
function ProgressRunner({ steps, onDone, doneLabel = 'Complete' }) {
  const [i, setI] = React.useState(0);
  React.useEffect(() => {
    if (i >= steps.length) { onDone?.(); return; }
    const t = setTimeout(() => setI(i + 1), 650 + Math.random() * 400);
    return () => clearTimeout(t);
  }, [i]);
  const done = i >= steps.length;
  return (
    <div>
      <div style={{ height: 4, background: 'rgba(255,255,255,0.06)', borderRadius: 2, overflow: 'hidden', marginBottom: 18 }}>
        <div style={{
          height: '100%', width: `${(i / steps.length) * 100}%`,
          background: 'var(--iridescent)',
          boxShadow: '0 0 12px rgba(139,107,255,0.6)',
          transition: 'width 0.4s ease',
        }}/>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {steps.map((s, idx) => {
          const state = idx < i ? 'done' : idx === i ? 'active' : 'pending';
          const col = state === 'done' ? 'var(--good)' : state === 'active' ? 'var(--cyan)' : 'var(--text-faint)';
          return (
            <div key={idx} style={{ display: 'flex', alignItems: 'center', gap: 10, fontSize: 12, color: col, fontFamily: 'var(--font-mono)' }}>
              <span style={{ width: 14, display: 'inline-block' }}>
                {state === 'done' ? '✓' : state === 'active' ? <span className="pip ok"/> : '·'}
              </span>
              <span>{s}</span>
            </div>
          );
        })}
      </div>
      {done && <div style={{ marginTop: 16, padding: 12, background: 'rgba(93,255,176,0.06)', border: '1px solid rgba(93,255,176,0.25)', borderRadius: 6, fontSize: 12, color: 'var(--good)' }}>✓ {doneLabel}</div>}
    </div>
  );
}

// Footer button helpers (modal footer is rendered separately, but we expose builders)
const _ftrBtn = (label, onClick, primary = false) => (
  <button key={label} className={`btn ${primary ? 'primary' : ''}`} onClick={onClick} data-handled="1">{label}</button>
);

// ============================================================
// WIZARD: Campaign Builder
// ============================================================
function CampaignBuilder({ defaults = {} }) {
  const [step, setStep] = React.useState(0);
  const [config, setConfig] = React.useState({
    name: defaults.name || 'Untitled campaign',
    channels: defaults.channels || ['email'],
    audience: defaults.audience || 'all_customers',
    subject: defaults.subject || '',
    body: defaults.body || '',
    schedule: defaults.schedule || 'now',
    sendDate: defaults.sendDate || '',
  });
  const [busy, setBusy] = React.useState(false);

  const set = (k, v) => setConfig(c => ({ ...c, [k]: v }));
  const canNext = step === 0 ? config.name.trim() && config.channels.length > 0
                : step === 1 ? !!config.audience
                : step === 2 ? config.body.trim().length > 0
                : true;
  const launch = () => {
    setBusy(true);
    setTimeout(() => {
      window.closeModal();
      window.toast(`Campaign "${config.name}" launched`, 'ok', `Going out to ${(window.AUDIENCE_SIZES?.[config.audience]) || '2,400'} via ${config.channels.join(' + ')}`);
    }, 800);
  };

  const generateWithAI = async () => {
    if (!window.claude?.complete) return;
    setBusy(true);
    try {
      const t = await window.claude.complete({
        messages: [{ role: 'user', content: `Write a short ${config.channels.join('+')} marketing message about: "${config.name}". 2-4 sentences. Friendly tone. No preamble.` }]
      });
      set('body', t);
      if (config.channels.includes('email') && !config.subject) {
        set('subject', config.name);
      }
    } catch {
      set('body', `Hey — just a quick note about ${config.name}. We've got something special for you this week. Hit reply if you want details.`);
    }
    setBusy(false);
  };

  return (
    <div>
      <Stepper steps={['Setup', 'Audience', 'Content', 'Review']} current={step}/>

      {step === 0 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <div>
            <label style={_label}>Campaign name</label>
            <input style={_input} value={config.name} onChange={e => set('name', e.target.value)} placeholder="May product launch"/>
          </div>
          <div>
            <label style={_label}>Channels (pick one or more)</label>
            <ChipGrid value={config.channels} onChange={v => set('channels', v)} multi cols={4} options={[
              { k: 'email',     label: 'Email',     sub: '2,412 recipients' },
              { k: 'sms',       label: 'SMS',       sub: '1,184 numbers' },
              { k: 'tiktok',    label: 'TikTok',    sub: 'broadcast post' },
              { k: 'instagram', label: 'Instagram', sub: 'feed + stories' },
              { k: 'facebook',  label: 'Facebook',  sub: '+ ads' },
              { k: 'linkedin',  label: 'LinkedIn',  sub: 'paid + organic' },
              { k: 'whatsapp',  label: 'WhatsApp',  sub: '412 numbers' },
              { k: 'ads',       label: 'Paid ads',  sub: 'Meta + Google' },
            ]}/>
          </div>
        </div>
      )}

      {step === 1 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <div>
            <label style={_label}>Send to</label>
            <ChipGrid value={config.audience} onChange={v => set('audience', v)} cols={2} options={[
              { k: 'all_customers', label: 'All customers',       sub: '2,412 people' },
              { k: 'hot_leads',     label: 'Hot leads',            sub: '184 people · high intent' },
              { k: 'recent_buyers', label: 'Recent buyers',        sub: '412 in last 30 days' },
              { k: 'inactive',      label: 'Inactive · 90 days',   sub: '618 people · win-back' },
              { k: 'tiktok',        label: 'TikTok followers',     sub: '12.4k people' },
              { k: 'custom',        label: 'Custom segment…',      sub: 'Build with filters' },
            ]}/>
          </div>
          <div style={{ padding: 12, borderRadius: 6, background: 'rgba(139,107,255,0.06)', border: '1px solid rgba(139,107,255,0.25)', fontSize: 12 }}>
            <div className="mono" style={{ fontSize: 10, letterSpacing: '0.14em', color: 'var(--violet)', textTransform: 'uppercase', marginBottom: 4 }}>Predicted reach</div>
            <div style={{ display: 'flex', justifyContent: 'space-between' }}>
              <span>Estimated opens · <strong style={{ color: 'var(--cyan)' }}>~1,184</strong></span>
              <span>Estimated replies · <strong style={{ color: 'var(--good)' }}>~142</strong></span>
              <span>Estimated revenue · <strong style={{ color: 'var(--good)' }}>£8,400</strong></span>
            </div>
          </div>
        </div>
      )}

      {step === 2 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <div className="row" style={{ justifyContent: 'space-between' }}>
            <label style={{ ..._label, marginBottom: 0 }}>Message content</label>
            <button className="btn sm" onClick={generateWithAI} data-handled="1" disabled={busy}>
              <span className="gradient-text" style={{ fontWeight: 600 }}>{busy ? 'Writing…' : '✦ Generate with AI'}</span>
            </button>
          </div>
          {config.channels.includes('email') && (
            <div>
              <label style={_label}>Subject line</label>
              <input style={_input} value={config.subject} onChange={e => set('subject', e.target.value)} placeholder="A quick note from us"/>
            </div>
          )}
          <div>
            <label style={_label}>Body</label>
            <textarea style={{ ..._input, minHeight: 140, resize: 'vertical', fontFamily: 'var(--font-ui)' }}
              value={config.body} onChange={e => set('body', e.target.value)}
              placeholder="Write what you want to say. Or click ✦ Generate with AI."/>
          </div>
        </div>
      )}

      {step === 3 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <div>
            <label style={_label}>When to send</label>
            <ChipGrid value={config.schedule} onChange={v => set('schedule', v)} cols={3} options={[
              { k: 'now',      label: 'Send now',           sub: 'Goes out in 30 seconds' },
              { k: 'best',     label: 'Best time (AI)',     sub: 'Tuesday 10:30 AM predicted' },
              { k: 'custom',   label: 'Custom time',        sub: 'Pick a date and time' },
            ]}/>
          </div>
          {config.schedule === 'custom' && (
            <div>
              <label style={_label}>Send at</label>
              <input style={_input} type="datetime-local" value={config.sendDate} onChange={e => set('sendDate', e.target.value)}/>
            </div>
          )}
          <div style={{ padding: 14, borderRadius: 6, background: 'rgba(0,0,0,0.3)', border: '1px solid var(--border)' }}>
            <div className="mono" style={{ fontSize: 10, letterSpacing: '0.14em', color: 'var(--text-faint)', textTransform: 'uppercase', marginBottom: 8 }}>Review</div>
            <div style={{ display: 'grid', gridTemplateColumns: '120px 1fr', gap: 6, fontSize: 12 }}>
              <span className="dim">Name</span><span>{config.name}</span>
              <span className="dim">Channels</span><span>{config.channels.join(' · ')}</span>
              <span className="dim">Audience</span><span>{config.audience.replace(/_/g, ' ')}</span>
              <span className="dim">When</span><span>{config.schedule === 'now' ? 'Now' : config.schedule === 'best' ? 'AI-picked best time' : config.sendDate || 'Custom'}</span>
            </div>
          </div>
        </div>
      )}

      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 22, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn ghost" onClick={() => step > 0 ? setStep(step - 1) : window.closeModal()} data-handled="1">
          {step === 0 ? 'Cancel' : '← Back'}
        </button>
        {step < 3
          ? <button className="btn primary" disabled={!canNext} onClick={() => setStep(step + 1)} data-handled="1">Continue →</button>
          : <button className="btn primary" disabled={busy} onClick={launch} data-handled="1">{busy ? 'Launching…' : '✦ Launch campaign'}</button>}
      </div>
    </div>
  );
}

// ============================================================
// WIZARD: Funnel Creation
// ============================================================
function FunnelWizard() {
  const [step, setStep] = React.useState(0);
  const [c, setC] = React.useState({ name: '', kind: 'lead', goal: '', traffic: ['paid_ads'] });
  const set = (k, v) => setC(o => ({ ...o, [k]: v }));
  const KINDS = {
    lead:    { steps: ['Visit landing page', 'Submit form', 'Email confirmation', 'Discovery call booked'], color: 'var(--cyan)' },
    sales:   { steps: ['View product', 'Add to cart', 'Checkout', 'Purchase confirmed'], color: 'var(--good)' },
    booking: { steps: ['View calendar', 'Pick a slot', 'Confirm details', 'Reminder + show up'], color: 'var(--violet)' },
    winback: { steps: ['Inactive trigger', 'Personal offer email', 'Follow-up SMS', 'Re-engage'], color: 'var(--magenta)' },
  };
  const k = KINDS[c.kind];

  return (
    <div>
      <Stepper steps={['Kind', 'Setup', 'Preview']} current={step}/>

      {step === 0 && (
        <ChipGrid value={c.kind} onChange={v => set('kind', v)} cols={2} options={[
          { k: 'lead',    label: 'Lead capture',         sub: 'Turn cold traffic into qualified leads' },
          { k: 'sales',   label: 'Direct sales',         sub: 'Sell a product or package end-to-end' },
          { k: 'booking', label: 'Appointment booking',  sub: 'Calls, demos, consultations' },
          { k: 'winback', label: 'Reactivation',         sub: 'Bring back inactive customers' },
        ]}/>
      )}

      {step === 1 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <div><label style={_label}>Funnel name</label>
            <input style={_input} value={c.name} onChange={e => set('name', e.target.value)} placeholder="May lead magnet"/>
          </div>
          <div><label style={_label}>What's the goal?</label>
            <input style={_input} value={c.goal} onChange={e => set('goal', e.target.value)} placeholder="Get 200 new leads this month"/>
          </div>
          <div><label style={_label}>Where will traffic come from?</label>
            <ChipGrid value={c.traffic} onChange={v => set('traffic', v)} multi cols={4} options={[
              { k: 'paid_ads',  label: 'Paid ads' },
              { k: 'organic',   label: 'SEO' },
              { k: 'social',    label: 'Social' },
              { k: 'email',     label: 'Email list' },
              { k: 'partners',  label: 'Partners' },
              { k: 'referral',  label: 'Referrals' },
              { k: 'cold',      label: 'Cold outreach' },
              { k: 'event',     label: 'Events' },
            ]}/>
          </div>
        </div>
      )}

      {step === 2 && (
        <div>
          <div className="mono" style={{ fontSize: 10, letterSpacing: '0.14em', color: 'var(--text-faint)', textTransform: 'uppercase', marginBottom: 12 }}>Funnel preview</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            {k.steps.map((s, i) => {
              const drop = 100 - i * 20;
              return (
                <div key={s} style={{ display: 'grid', gridTemplateColumns: '28px 1fr 90px', alignItems: 'center', gap: 12, padding: '10px 14px', background: 'rgba(0,0,0,0.25)', border: '1px solid var(--border)', borderRadius: 6 }}>
                  <div className="mono" style={{ fontSize: 11, color: k.color }}>{String(i + 1).padStart(2, '0')}</div>
                  <div style={{ fontSize: 13 }}>{s}</div>
                  <div style={{ height: 6, background: 'rgba(255,255,255,0.04)', borderRadius: 3, overflow: 'hidden' }}>
                    <div style={{ height: '100%', width: `${drop}%`, background: k.color, opacity: 0.7 }}/>
                  </div>
                </div>
              );
            })}
          </div>
          <div style={{ marginTop: 14, padding: 12, background: 'rgba(139,107,255,0.08)', border: '1px solid rgba(139,107,255,0.25)', borderRadius: 6, fontSize: 12 }}>
            ✦ Demiurge will build the pages, write the copy, and wire the automations. Estimated time live: <strong>4–6 hours</strong>.
          </div>
        </div>
      )}

      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 22, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn ghost" onClick={() => step > 0 ? setStep(step - 1) : window.closeModal()} data-handled="1">{step === 0 ? 'Cancel' : '← Back'}</button>
        {step < 2
          ? <button className="btn primary" onClick={() => setStep(step + 1)} data-handled="1">Continue →</button>
          : <button className="btn primary" data-handled="1" onClick={() => { window.closeModal(); window.toast(`Funnel "${c.name || 'Untitled'}" created`, 'ok', 'Demiurge is building it now · live in ~4h'); }}>✦ Create funnel</button>}
      </div>
    </div>
  );
}

// ============================================================
// WIZARD: Workflow Builder
// ============================================================
function WorkflowBuilder() {
  const [step, setStep] = React.useState(0);
  const [c, setC] = React.useState({ trigger: 'new_lead', actions: ['send_email'], schedule: 'immediately', name: '' });
  const set = (k, v) => setC(o => ({ ...o, [k]: v }));

  return (
    <div>
      <Stepper steps={['Trigger', 'Actions', 'Review']} current={step}/>

      {step === 0 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <label style={_label}>When this happens…</label>
          <ChipGrid value={c.trigger} onChange={v => set('trigger', v)} cols={2} options={[
            { k: 'new_lead',     label: 'New lead arrives',         sub: 'Any form, ad, or DM' },
            { k: 'missed_call',  label: 'Missed phone call',        sub: 'Trigger SMS recovery' },
            { k: 'no_reply',     label: 'Customer hasn\'t replied', sub: '48h since last message' },
            { k: 'review',       label: 'New review posted',         sub: 'Google, Yelp, anywhere' },
            { k: 'booking',      label: 'Appointment booked',        sub: 'Send confirmations' },
            { k: 'cart_abandon', label: 'Cart abandoned',            sub: 'Within 1 hour' },
            { k: 'tag_added',    label: 'Contact tagged',            sub: 'Any custom tag' },
            { k: 'time',         label: 'Time of day',               sub: 'Daily / weekly / monthly' },
          ]}/>
        </div>
      )}

      {step === 1 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <label style={_label}>Do these things (in order)</label>
          <ChipGrid value={c.actions} onChange={v => set('actions', v)} multi cols={2} options={[
            { k: 'send_email',  label: 'Send an email',          sub: 'AI-written, personalized' },
            { k: 'send_sms',    label: 'Send an SMS',            sub: 'Short, on-brand' },
            { k: 'create_task', label: 'Create a task for you',   sub: 'In your inbox' },
            { k: 'add_tag',     label: 'Tag the contact',        sub: 'For segmentation' },
            { k: 'notify_team', label: 'Notify your team',        sub: 'Slack / email' },
            { k: 'ai_call',     label: 'AI calls them',          sub: 'Voice agent dials' },
            { k: 'wait',        label: 'Wait',                   sub: 'Hours, days, or events' },
            { k: 'crm_update',  label: 'Update CRM',              sub: 'Move to next stage' },
          ]}/>
          <div className="mono" style={{ fontSize: 10, color: 'var(--text-faint)', textTransform: 'uppercase', letterSpacing: '0.14em' }}>Selected actions ({c.actions.length})</div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
            {c.actions.map((a, i) => (
              <div key={a} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '8px 12px', background: 'rgba(0,0,0,0.25)', border: '1px solid var(--border)', borderRadius: 6 }}>
                <span className="mono" style={{ fontSize: 11, color: 'var(--cyan)' }}>{String(i + 1).padStart(2, '0')}</span>
                <span style={{ fontSize: 12.5 }}>{a.replace(/_/g, ' ')}</span>
              </div>
            ))}
          </div>
        </div>
      )}

      {step === 2 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <div><label style={_label}>Workflow name</label>
            <input style={_input} value={c.name} onChange={e => set('name', e.target.value)} placeholder="Auto-respond to new leads"/>
          </div>
          <div style={{ padding: 14, borderRadius: 6, background: 'rgba(0,0,0,0.3)', border: '1px solid var(--border)' }}>
            <div className="mono" style={{ fontSize: 10, letterSpacing: '0.14em', color: 'var(--text-faint)', textTransform: 'uppercase', marginBottom: 8 }}>Summary</div>
            <div style={{ fontSize: 13, lineHeight: 1.6 }}>
              When <strong style={{ color: 'var(--cyan)' }}>{c.trigger.replace(/_/g, ' ')}</strong>, Demiurge will{' '}
              {c.actions.map((a, i) => (
                <React.Fragment key={a}>
                  <strong style={{ color: 'var(--violet)' }}>{a.replace(/_/g, ' ')}</strong>
                  {i < c.actions.length - 1 ? (i === c.actions.length - 2 ? ', then ' : ', ') : '.'}
                </React.Fragment>
              ))}
            </div>
          </div>
        </div>
      )}

      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 22, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn ghost" onClick={() => step > 0 ? setStep(step - 1) : window.closeModal()} data-handled="1">{step === 0 ? 'Cancel' : '← Back'}</button>
        {step < 2
          ? <button className="btn primary" onClick={() => setStep(step + 1)} data-handled="1">Continue →</button>
          : <button className="btn primary" data-handled="1" onClick={() => { window.closeModal(); window.toast(`Workflow "${c.name || 'Untitled'}" deployed`, 'ok', 'Live now · monitoring triggers'); }}>✦ Deploy workflow</button>}
      </div>
    </div>
  );
}

// ============================================================
// WIZARD: Agent Spin-up
// ============================================================
function AgentSpinup() {
  const [step, setStep] = React.useState(0);
  const [c, setC] = React.useState({ role: 'sdr', name: '', voice: 'warm', channels: ['email', 'sms'], schedule: '24_7' });
  const set = (k, v) => setC(o => ({ ...o, [k]: v }));
  const ROLES = {
    sdr:        { label: 'Outbound SDR',     hint: 'Prospects, qualifies, books meetings' },
    receptionist: { label: 'AI Receptionist', hint: 'Answers phones, books, takes messages' },
    closer:     { label: 'Closer',           hint: 'Follows up hot leads, sends proposals' },
    support:    { label: 'Customer support',  hint: 'Tier-1 answers, ticket routing' },
    content:    { label: 'Content creator',   hint: 'Writes posts, captions, ads' },
    research:   { label: 'Research analyst',  hint: 'Briefs, market intel, monitoring' },
  };

  return (
    <div>
      <Stepper steps={['Role', 'Voice', 'Channels', 'Deploy']} current={step}/>

      {step === 0 && (
        <ChipGrid value={c.role} onChange={v => set('role', v)} cols={3} options={Object.entries(ROLES).map(([k, v]) => ({ k, label: v.label, sub: v.hint }))}/>
      )}

      {step === 1 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <div><label style={_label}>Operator name</label>
            <input style={_input} value={c.name} onChange={e => set('name', e.target.value)} placeholder="Atlas-2"/>
            <div style={{ ..._hint, marginTop: 4 }}>Pick something memorable. We use mythology names for ours (Atlas, Nyx, Calliope, Orpheus).</div>
          </div>
          <div><label style={_label}>Voice & tone</label>
            <ChipGrid value={c.voice} onChange={v => set('voice', v)} cols={4} options={[
              { k: 'warm',         label: 'Warm' },
              { k: 'professional', label: 'Professional' },
              { k: 'playful',      label: 'Playful' },
              { k: 'bold',         label: 'Direct' },
            ]}/>
          </div>
        </div>
      )}

      {step === 2 && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <div><label style={_label}>Channels this operator runs on</label>
            <ChipGrid value={c.channels} onChange={v => set('channels', v)} multi cols={4} options={[
              { k: 'email',     label: 'Email' },
              { k: 'sms',       label: 'SMS' },
              { k: 'voice',     label: 'Voice call' },
              { k: 'whatsapp',  label: 'WhatsApp' },
              { k: 'instagram', label: 'Instagram DM' },
              { k: 'linkedin',  label: 'LinkedIn' },
              { k: 'tiktok',    label: 'TikTok DM' },
              { k: 'webchat',   label: 'Web chat' },
            ]}/>
          </div>
          <div><label style={_label}>Working hours</label>
            <ChipGrid value={c.schedule} onChange={v => set('schedule', v)} cols={3} options={[
              { k: '24_7',  label: '24 / 7' },
              { k: 'biz',   label: 'Business hours', sub: 'Mon–Fri 9am–6pm' },
              { k: 'custom',label: 'Custom schedule' },
            ]}/>
          </div>
        </div>
      )}

      {step === 3 && (
        <div>
          <div style={{ padding: 16, borderRadius: 6, background: 'rgba(0,0,0,0.3)', border: '1px solid var(--border)' }}>
            <div className="serif" style={{ fontSize: 22, fontStyle: 'italic', marginBottom: 8 }}>{c.name || 'New operator'}</div>
            <div className="mono" style={{ fontSize: 10, color: 'var(--cyan)', textTransform: 'uppercase', letterSpacing: '0.14em', marginBottom: 14 }}>{ROLES[c.role].label} · {c.voice} voice</div>
            <div style={{ display: 'grid', gridTemplateColumns: '120px 1fr', gap: 6, fontSize: 12 }}>
              <span className="dim">Channels</span><span>{c.channels.join(', ')}</span>
              <span className="dim">Schedule</span><span>{c.schedule === '24_7' ? '24 / 7' : c.schedule === 'biz' ? 'Business hours' : 'Custom'}</span>
              <span className="dim">Training</span><span>Will absorb your knowledge base in 60s</span>
              <span className="dim">Compute</span><span className="mono">Provisioning · GPU-7 / Frankfurt</span>
            </div>
          </div>
        </div>
      )}

      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 22, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn ghost" onClick={() => step > 0 ? setStep(step - 1) : window.closeModal()} data-handled="1">{step === 0 ? 'Cancel' : '← Back'}</button>
        {step < 3
          ? <button className="btn primary" onClick={() => setStep(step + 1)} data-handled="1">Continue →</button>
          : <button className="btn primary" data-handled="1" onClick={() => { window.closeModal(); window.toast(`Operator "${c.name || 'new agent'}" deploying`, 'info', 'Provisioning compute · indexing knowledge corpus · live in ~30s'); }}>✦ Spin up agent</button>}
      </div>
    </div>
  );
}

// ============================================================
// MODAL: AI Audit (animated)
// ============================================================
function AIAudit() {
  const [phase, setPhase] = React.useState('running');
  const steps = [
    'Scanning all 13 connected channels…',
    'Reading 24h of customer messages…',
    'Re-analyzing funnel conversion rates…',
    'Cross-referencing ad spend vs revenue…',
    'Checking voice fingerprint drift…',
    'Identifying high-leverage improvements…',
  ];

  if (phase === 'running') {
    return (
      <div>
        <div className="mono dim" style={{ fontSize: 11, marginBottom: 14, textTransform: 'uppercase', letterSpacing: '0.14em' }}>
          Running deep audit · {new Date().toLocaleTimeString()}
        </div>
        <ProgressRunner steps={steps} onDone={() => setPhase('result')} doneLabel="Audit complete. 7 findings · 3 high-priority."/>
      </div>
    );
  }

  const findings = [
    { sev: 'high', title: 'TikTok ROAS is 2.2× higher than Facebook',     reco: 'Shift £200/wk from FB → TikTok', impact: '+£3.4k / month' },
    { sev: 'high', title: 'Lead-response time is 14 min (target: <2 min)', reco: 'Enable AI auto-reply for inbound DMs', impact: '+18% close rate' },
    { sev: 'high', title: 'Calliope sequence "Cold #2" hurting domain rep', reco: 'Pause + regenerate with new prompts', impact: 'Recover sender score' },
    { sev: 'med',  title: 'Funnel step 3 drops 42% of traffic',             reco: 'Rewrite copy + add testimonials', impact: '+£2k / month' },
    { sev: 'med',  title: '18 customers inactive 90+ days',                  reco: 'Launch win-back sequence', impact: '£8k recoverable' },
    { sev: 'low',  title: 'Brand voice drift detected on Atlas',             reco: 'Retrain clone (4 min)', impact: 'Consistency' },
    { sev: 'low',  title: '4 channels missing scheduling',                   reco: 'Auto-fill from content library', impact: '+12 posts/wk' },
  ];
  const COLOR = { high: 'var(--danger)', med: 'var(--warn)', low: 'var(--text-dim)' };
  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14 }}>
        <span className="tag live">7 FINDINGS</span>
        <span className="dim" style={{ fontSize: 12 }}>Estimated upside if all applied: <strong className="up">£13,400 / mo</strong></span>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8, maxHeight: 380, overflowY: 'auto' }}>
        {findings.map((f, i) => (
          <div key={i} style={{ padding: 12, borderRadius: 6, background: 'rgba(255,255,255,0.025)', border: `1px solid ${COLOR[f.sev]}30`, borderLeft: `2px solid ${COLOR[f.sev]}` }}>
            <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8 }}>
              <span className="mono" style={{ fontSize: 9, color: COLOR[f.sev], textTransform: 'uppercase', letterSpacing: '0.14em', padding: '1px 6px', border: `1px solid ${COLOR[f.sev]}40`, borderRadius: 3 }}>{f.sev}</span>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 13, marginBottom: 4 }}>{f.title}</div>
                <div style={{ fontSize: 11.5, color: 'var(--text-dim)' }}>→ {f.reco} · <strong className="up">{f.impact}</strong></div>
              </div>
              <button className="btn sm" data-handled="1" onClick={() => window.toast('Applied', 'ok', f.reco)}>Apply</button>
            </div>
          </div>
        ))}
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 16, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn ghost" onClick={window.closeModal} data-handled="1">Close</button>
        <div style={{ display: 'flex', gap: 8 }}>
          <button className="btn" data-handled="1" onClick={() => window.toast('Audit exported', 'ok', 'PDF in your downloads')}>Export PDF</button>
          <button className="btn primary" data-handled="1" onClick={() => { window.closeModal(); window.toast('Applying all 7 findings…', 'info', 'Demiurge is rolling out changes · ~6 minutes to live'); }}>Apply all (7)</button>
        </div>
      </div>
    </div>
  );
}

// ============================================================
// MODAL: Report Center
// ============================================================
function ReportCenter() {
  const [c, setC] = React.useState({ kind: 'executive', period: 'this_month', format: 'pdf', recipients: 'me' });
  const set = (k, v) => setC(o => ({ ...o, [k]: v }));
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      <div><label style={_label}>Report type</label>
        <ChipGrid value={c.kind} onChange={v => set('kind', v)} cols={2} options={[
          { k: 'executive',  label: 'Executive summary',    sub: 'High-level KPIs · 1 page' },
          { k: 'revenue',    label: 'Revenue deep-dive',    sub: 'By channel, segment, product' },
          { k: 'funnel',     label: 'Funnel performance',    sub: 'Drop-off, conversion, CAC' },
          { k: 'campaign',   label: 'Campaign performance',  sub: 'All active + recent campaigns' },
          { k: 'agent',      label: 'Agent productivity',    sub: 'Per-operator output + impact' },
          { k: 'forecast',   label: '90-day forecast',       sub: 'AI-projected revenue + leads' },
        ]}/>
      </div>
      <div style={_row}>
        <div><label style={_label}>Period</label>
          <ChipGrid value={c.period} onChange={v => set('period', v)} cols={2} options={[
            { k: 'last_7',     label: 'Last 7 days' },
            { k: 'last_30',    label: 'Last 30 days' },
            { k: 'this_month', label: 'This month' },
            { k: 'this_qtr',   label: 'This quarter' },
          ]}/>
        </div>
        <div><label style={_label}>Format</label>
          <ChipGrid value={c.format} onChange={v => set('format', v)} cols={3} options={[
            { k: 'pdf',  label: 'PDF' },
            { k: 'csv',  label: 'CSV' },
            { k: 'live', label: 'Live link' },
          ]}/>
        </div>
      </div>
      <div><label style={_label}>Send to</label>
        <input style={_input} placeholder="reza@belmont.com, board@belmont.com" defaultValue="reza@belmont.com"/>
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn ghost" onClick={window.closeModal} data-handled="1">Cancel</button>
        <button className="btn primary" data-handled="1" onClick={() => { window.closeModal(); window.toast('Report generating…', 'info', `${c.kind.replace(/_/g, ' ')} · ${c.format.toUpperCase()} · ready in ~30s`); }}>✦ Generate report</button>
      </div>
    </div>
  );
}

// ============================================================
// MODAL: Content Distribution Center (Post Everywhere)
// ============================================================
function ContentDistribution() {
  const [c, setC] = React.useState({ platforms: ['tiktok', 'instagram'], content: '', schedule: 'now', when: '' });
  const set = (k, v) => setC(o => ({ ...o, [k]: v }));
  const [busy, setBusy] = React.useState(false);

  const generate = async () => {
    setBusy(true);
    try {
      const t = await window.claude.complete({
        messages: [{ role: 'user', content: `Write a single short social media post (1-3 sentences, no hashtags unless natural) for a small business that builds AI-powered customer engagement. Friendly, punchy. No preamble.` }]
      });
      set('content', t);
    } catch {
      set('content', 'Built something quiet today: a workflow that replies to every DM in under 30 seconds. The customers are noticing.');
    }
    setBusy(false);
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
      <div><label style={_label}>Platforms to post to</label>
        <ChipGrid value={c.platforms} onChange={v => set('platforms', v)} multi cols={4} options={[
          { k: 'tiktok',    label: 'TikTok',    sub: '2 accounts' },
          { k: 'instagram', label: 'Instagram', sub: '3 accounts' },
          { k: 'facebook',  label: 'Facebook',  sub: '2 pages' },
          { k: 'linkedin',  label: 'LinkedIn',  sub: '1 page' },
          { k: 'x',         label: 'X / Twitter', sub: '1 account' },
          { k: 'youtube',   label: 'YouTube',   sub: 'Shorts' },
          { k: 'threads',   label: 'Threads',   sub: '1 account' },
          { k: 'pinterest', label: 'Pinterest', sub: '1 board' },
        ]}/>
      </div>
      <div>
        <div className="row" style={{ justifyContent: 'space-between' }}>
          <label style={{ ..._label, marginBottom: 0 }}>Post content</label>
          <button className="btn sm" onClick={generate} disabled={busy} data-handled="1">
            <span className="gradient-text" style={{ fontWeight: 600 }}>{busy ? 'Writing…' : '✦ Generate with AI'}</span>
          </button>
        </div>
        <textarea style={{ ..._input, minHeight: 100, marginTop: 6, fontFamily: 'var(--font-ui)' }} value={c.content} onChange={e => set('content', e.target.value)} placeholder="What do you want to say? Or click ✦ Generate with AI."/>
        <div className="mono" style={{ fontSize: 10, color: 'var(--text-faint)', marginTop: 6, textAlign: 'right' }}>
          {c.content.length} chars · TikTok caption fit · Twitter {c.content.length <= 280 ? 'fits' : `over by ${c.content.length - 280}`}
        </div>
      </div>
      <div><label style={_label}>Preview by platform</label>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(180px, 1fr))', gap: 8 }}>
          {c.platforms.slice(0, 4).map(p => (
            <div key={p} style={{ padding: 10, borderRadius: 6, background: 'rgba(0,0,0,0.3)', border: '1px solid var(--border)' }}>
              <div className="mono" style={{ fontSize: 9, letterSpacing: '0.14em', color: 'var(--cyan)', textTransform: 'uppercase', marginBottom: 6 }}>{p}</div>
              <div style={{ fontSize: 11.5, color: 'var(--text-dim)', minHeight: 36 }}>{c.content || <span className="faint">Your post will appear here…</span>}</div>
            </div>
          ))}
        </div>
      </div>
      <div><label style={_label}>When to post</label>
        <ChipGrid value={c.schedule} onChange={v => set('schedule', v)} cols={3} options={[
          { k: 'now',    label: 'Post now',         sub: 'All platforms simultaneously' },
          { k: 'best',   label: 'Optimal time (AI)', sub: 'Per-platform sweet spots' },
          { k: 'custom', label: 'Schedule for…' },
        ]}/>
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn ghost" onClick={window.closeModal} data-handled="1">Cancel</button>
        <div style={{ display: 'flex', gap: 8 }}>
          <button className="btn" data-handled="1" onClick={() => window.toast('Saved as draft', 'ok', 'Find it in Channels · Drafts')}>Save draft</button>
          <button className="btn primary" data-handled="1" disabled={!c.content.trim() || c.platforms.length === 0} onClick={() => { window.closeModal(); window.toast('Posted to ' + c.platforms.length + ' platforms', 'ok', c.schedule === 'now' ? 'Live now' : c.schedule === 'best' ? 'Scheduled at AI-optimal times' : 'Scheduled'); }}>
            {c.schedule === 'now' ? `Post to ${c.platforms.length}` : 'Schedule'} →
          </button>
        </div>
      </div>
    </div>
  );
}

// ============================================================
// MODAL: AI Content Studio (Create Content)
// ============================================================
function ContentStudio() {
  const TABS = [
    { k: 'post',     label: 'Social post' },
    { k: 'carousel', label: 'Carousel' },
    { k: 'video',    label: 'Short video' },
    { k: 'image',    label: 'Image prompt' },
    { k: 'caption',  label: 'Caption' },
    { k: 'ad',       label: 'Ad creative' },
    { k: 'email',    label: 'Email' },
    { k: 'sms',      label: 'SMS' },
  ];
  const [tab, setTab] = React.useState('post');
  const [objective, setObjective] = React.useState('awareness');
  const [business, setBusiness] = React.useState('belmont');
  const [output, setOutput] = React.useState('');
  const [busy, setBusy] = React.useState(false);

  const generate = async () => {
    setBusy(true);
    setOutput('');
    const prompt = {
      post:     `Write a single social media post for a ${business} business focused on ${objective}. 1-3 sentences. Friendly. No preamble, no hashtags unless natural.`,
      carousel: `Write a 5-slide carousel script for a ${business} business about ${objective}. Format: Slide 1: ... Slide 2: ... — punchy, 1 sentence per slide.`,
      video:    `Write a 30-second short-form video script (TikTok/Reels) for a ${business} business about ${objective}. Format: HOOK (2s): ... / BODY (20s): ... / CTA (8s): ...`,
      image:    `Write a detailed image generation prompt for a ${business} brand ${objective} visual. Specific, evocative, mention lighting and composition.`,
      caption:  `Write a 1-2 sentence Instagram caption with 3-5 natural hashtags for ${business}, theme: ${objective}.`,
      ad:       `Write a paid ad creative for ${business} with ${objective} as goal. Format: Headline / Primary text / CTA. Keep it punchy.`,
      email:    `Write a marketing email for a ${business} business. Objective: ${objective}. Format: Subject line / Body (3-4 sentences). Friendly.`,
      sms:      `Write a marketing SMS for ${business}. Objective: ${objective}. Max 160 characters. Friendly, on-brand.`,
    }[tab];
    try {
      const t = await window.claude.complete({ messages: [{ role: 'user', content: prompt }] });
      setOutput(t);
    } catch {
      setOutput('Generated content goes here. Press regenerate for a fresh take, or tweak the inputs.');
    }
    setBusy(false);
  };

  return (
    <div>
      {/* Tabs */}
      <div style={{ display: 'flex', gap: 4, borderBottom: '1px solid var(--border)', marginBottom: 16, overflowX: 'auto', paddingBottom: 1 }}>
        {TABS.map(t => (
          <button key={t.k} onClick={() => { setTab(t.k); setOutput(''); }} data-handled="1" style={{
            padding: '8px 14px',
            fontSize: 11, fontFamily: 'var(--font-mono)', letterSpacing: '0.14em', textTransform: 'uppercase',
            color: tab === t.k ? 'var(--text)' : 'var(--text-dim)',
            borderBottom: `2px solid ${tab === t.k ? 'var(--cyan)' : 'transparent'}`,
            marginBottom: -1,
            whiteSpace: 'nowrap',
            cursor: 'pointer',
          }}>{t.label}</button>
        ))}
      </div>
      <div style={_row}>
        <div><label style={_label}>Business</label>
          <select style={_input} value={business} onChange={e => setBusiness(e.target.value)}>
            <option value="belmont">Belmont Dental Group</option>
            <option value="atlas">Atlas Tattoo Studio</option>
            <option value="orpheus">Orpheus Audio Co.</option>
            <option value="nyx">Nyx Wellness</option>
            <option value="calliope">Calliope Coffee</option>
          </select>
        </div>
        <div><label style={_label}>Objective</label>
          <select style={_input} value={objective} onChange={e => setObjective(e.target.value)}>
            <option value="awareness">Brand awareness</option>
            <option value="leads">Generate leads</option>
            <option value="bookings">Drive bookings</option>
            <option value="winback">Win back inactive</option>
            <option value="launch">Product / offer launch</option>
            <option value="reviews">Request reviews</option>
          </select>
        </div>
      </div>
      <div style={{ marginTop: 14 }}>
        <button className="btn primary" onClick={generate} disabled={busy} data-handled="1" style={{ width: '100%' }}>
          {busy ? '✦ Generating…' : output ? '✦ Regenerate' : '✦ Generate content'}
        </button>
      </div>
      {output && (
        <div style={{ marginTop: 16, padding: 14, background: 'rgba(0,0,0,0.3)', border: '1px solid rgba(75,232,255,0.25)', borderRadius: 6 }}>
          <div className="mono" style={{ fontSize: 10, letterSpacing: '0.14em', color: 'var(--cyan)', textTransform: 'uppercase', marginBottom: 8 }}>Output · {TABS.find(t => t.k === tab).label}</div>
          <div style={{ whiteSpace: 'pre-wrap', fontSize: 13, lineHeight: 1.6 }}>{output}</div>
          <div style={{ display: 'flex', gap: 6, marginTop: 12, flexWrap: 'wrap' }}>
            <button className="btn sm" data-handled="1" onClick={() => { navigator.clipboard?.writeText(output); window.toast('Copied to clipboard', 'ok'); }}>Copy</button>
            <button className="btn sm" data-handled="1" onClick={() => window.toast('Opened in editor', 'info', 'Make changes and save when ready')}>Edit</button>
            <button className="btn sm" data-handled="1" onClick={() => window.toast('Scheduled', 'ok', 'Will publish at AI-optimal time')}>Schedule</button>
            <button className="btn sm primary" data-handled="1" onClick={() => { window.closeModal(); window.toast('Posted', 'ok', 'Live across selected channels'); }}>Post now</button>
            <button className="btn sm" data-handled="1" onClick={() => window.toast('Approved', 'ok', 'Sending to operator queue')}>Approve</button>
          </div>
        </div>
      )}
    </div>
  );
}

// ============================================================
// MODAL: Lead Growth Recommendations
// ============================================================
function LeadGrowth() {
  const recos = [
    { title: 'Run TikTok video ads',          impact: '+80–120 leads / mo', cost: '£600 / wk', conf: 'High',  reason: 'Best-performing channel right now (£8.40 ROAS).' },
    { title: 'Add web-chat to your site',     impact: '+40 leads / mo',     cost: 'Free',       conf: 'High',  reason: 'Demiurge handles the conversation 24/7.' },
    { title: 'Activate referral program',     impact: '+24 leads / mo',     cost: '£20 reward', conf: 'Med',   reason: '38% of your customers said they\'d refer.' },
    { title: 'Re-run cold email campaign',    impact: '+18 leads / mo',     cost: '£0',         conf: 'Med',   reason: '2,400 contacts haven\'t heard from you in 90 days.' },
    { title: 'Sponsor a local event',         impact: '+12 leads + brand',  cost: '£800',       conf: 'Low',   reason: 'Belmont Health Fair next month.' },
    { title: 'Partner with @nutritionist_amy', impact: '+30 leads / mo',     cost: '15% commission', conf: 'High', reason: 'Audience match score 0.84 · Demiurge can broker.' },
  ];
  const CONF = { High: 'var(--good)', Med: 'var(--cyan)', Low: 'var(--text-dim)' };
  return (
    <div>
      <div style={{ marginBottom: 14, padding: 12, background: 'rgba(139,107,255,0.08)', border: '1px solid rgba(139,107,255,0.25)', borderRadius: 6 }}>
        <div className="mono" style={{ fontSize: 10, color: 'var(--violet)', textTransform: 'uppercase', letterSpacing: '0.14em', marginBottom: 4 }}>Demiurge analysis · just now</div>
        <div style={{ fontSize: 12.5 }}>You currently get <strong className="up">17 leads / week</strong>. Top 3 actions below could add <strong className="up">~240 leads / month</strong>.</div>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8, maxHeight: 380, overflowY: 'auto' }}>
        {recos.map((r, i) => (
          <div key={i} style={{ padding: 12, borderRadius: 6, background: 'rgba(255,255,255,0.025)', border: '1px solid var(--border)' }}>
            <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12 }}>
              <div style={{ flex: 1 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
                  <span style={{ fontSize: 13, fontWeight: 500 }}>{r.title}</span>
                  <span className="mono" style={{ fontSize: 9, color: CONF[r.conf], padding: '1px 6px', border: `1px solid ${CONF[r.conf]}40`, borderRadius: 3, textTransform: 'uppercase', letterSpacing: '0.14em' }}>{r.conf}</span>
                </div>
                <div style={{ fontSize: 11.5, color: 'var(--text-dim)', marginBottom: 4 }}>{r.reason}</div>
                <div style={{ display: 'flex', gap: 12, fontSize: 11 }}>
                  <span className="up">{r.impact}</span>
                  <span className="dim">·</span>
                  <span className="dim">Cost: {r.cost}</span>
                </div>
              </div>
              <button className="btn sm primary" data-handled="1" onClick={() => window.toast(`Starting: ${r.title}`, 'info', 'Demiurge is setting it up')}>Start</button>
            </div>
          </div>
        ))}
      </div>
      <div style={{ display: 'flex', justifyContent: 'flex-end', marginTop: 16, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn primary" data-handled="1" onClick={() => { window.closeModal(); window.toast('Top 3 in motion', 'ok', 'TikTok ads + web-chat + referral program — Demiurge will keep you updated'); }}>Apply top 3</button>
      </div>
    </div>
  );
}

// ============================================================
// MODAL: Funnel Optimization
// ============================================================
function FunnelOptimization() {
  const optimizations = [
    { step: 'Step 1 · Visit landing page',       drop: '15%',  fix: 'Speed up page load (currently 4.2s)',           lift: '+8% to next step' },
    { step: 'Step 2 · Submit contact form',      drop: '42%',  fix: 'Cut form from 7 fields → 3',                     lift: '+22% completion' },
    { step: 'Step 3 · Confirm email',            drop: '28%',  fix: 'Send confirmation within 30s (was 4 min)',       lift: '+14% confirm rate' },
    { step: 'Step 4 · Book discovery call',      drop: '38%',  fix: 'Show calendar inline + AI handle objections',    lift: '+18% bookings' },
  ];
  return (
    <div>
      <div style={{ marginBottom: 14, padding: 12, background: 'rgba(255,177,75,0.08)', border: '1px solid rgba(255,177,75,0.3)', borderRadius: 6 }}>
        <div className="mono" style={{ fontSize: 10, color: 'var(--warn)', textTransform: 'uppercase', letterSpacing: '0.14em', marginBottom: 4 }}>Drop-off analysis</div>
        <div style={{ fontSize: 12.5 }}>For every <strong>100 people</strong> who visit your funnel, only <strong className="dn">1</strong> becomes a customer. Below: how to lift that to <strong className="up">~3</strong>.</div>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {optimizations.map((o, i) => (
          <div key={i} style={{ padding: 12, borderRadius: 6, background: 'rgba(255,255,255,0.025)', border: '1px solid var(--border)' }}>
            <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12 }}>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 12.5, fontWeight: 500, marginBottom: 4 }}>{o.step}</div>
                <div style={{ fontSize: 11, color: 'var(--text-dim)', marginBottom: 6 }}>Currently losing <strong className="dn">{o.drop}</strong> here</div>
                <div style={{ fontSize: 11.5 }}>→ {o.fix} <span className="up">({o.lift})</span></div>
              </div>
              <button className="btn sm" data-handled="1" onClick={() => window.toast('Applied', 'ok', o.fix)}>Apply fix</button>
            </div>
          </div>
        ))}
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 16, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn ghost" onClick={window.closeModal} data-handled="1">Cancel</button>
        <button className="btn primary" data-handled="1" onClick={() => { window.closeModal(); window.toast('Optimizing your journey', 'info', '4 fixes deploying · expected lift +280% over 30 days'); }}>✦ Apply all (4)</button>
      </div>
    </div>
  );
}

// ============================================================
// MODAL: Connection (Reconnect, Connect new)
// ============================================================
function ConnectionFlow({ name = 'Channel', kind = 'oauth' }) {
  const [phase, setPhase] = React.useState('confirm');
  if (phase === 'confirm') {
    return (
      <div>
        <div style={{ marginBottom: 14, fontSize: 13 }}>
          Demiurge will redirect you to authenticate with <strong>{name}</strong>.
          We'll request the minimum permissions needed to read messages, post on your behalf, and listen for events.
        </div>
        <div style={{ padding: 12, background: 'rgba(0,0,0,0.25)', border: '1px solid var(--border)', borderRadius: 6, marginBottom: 14 }}>
          <div className="mono" style={{ fontSize: 10, color: 'var(--text-faint)', textTransform: 'uppercase', letterSpacing: '0.14em', marginBottom: 8 }}>Scopes requested</div>
          {['Read messages', 'Send messages', 'Post content', 'Read analytics', 'Manage webhooks'].map(s => (
            <div key={s} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '4px 0', fontSize: 12 }}>
              <span style={{ color: 'var(--good)' }}>✓</span>
              <span>{s}</span>
            </div>
          ))}
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between' }}>
          <button className="btn ghost" onClick={window.closeModal} data-handled="1">Cancel</button>
          <button className="btn primary" data-handled="1" onClick={() => setPhase('running')}>Continue to {name}</button>
        </div>
      </div>
    );
  }
  return (
    <ProgressRunner
      steps={[`Opening ${name} OAuth window…`, 'Validating credentials…', 'Provisioning webhook endpoints…', 'Syncing initial state…', 'Indexing into Demiurge memory…']}
      onDone={() => { window.closeModal(); window.toast(`${name} connected`, 'ok', 'Live now · webhooks active'); }}
      doneLabel={`${name} connected`}
    />
  );
}

// ============================================================
// MODAL: Schedule Picker
// ============================================================
function SchedulePicker({ subject = 'this' }) {
  const [when, setWhen] = React.useState('best');
  const [custom, setCustom] = React.useState('');
  return (
    <div>
      <div style={{ marginBottom: 14, fontSize: 13 }}>Pick when to schedule <strong>{subject}</strong>.</div>
      <ChipGrid value={when} onChange={setWhen} cols={2} options={[
        { k: 'now',    label: 'Send now' },
        { k: 'best',   label: 'AI-optimal time', sub: 'Picks per-channel sweet spot' },
        { k: '1h',     label: 'In 1 hour' },
        { k: 'eod',    label: 'End of day' },
        { k: 'tom_am', label: 'Tomorrow 9 AM' },
        { k: 'custom', label: 'Pick custom…' },
      ]}/>
      {when === 'custom' && (
        <input style={{ ..._input, marginTop: 12 }} type="datetime-local" value={custom} onChange={e => setCustom(e.target.value)}/>
      )}
      <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 16, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn ghost" onClick={window.closeModal} data-handled="1">Cancel</button>
        <button className="btn primary" data-handled="1" onClick={() => { window.closeModal(); window.toast('Scheduled', 'ok', when === 'now' ? 'Going out now' : when === 'best' ? 'AI picked optimal time' : 'Will run at chosen time'); }}>Schedule</button>
      </div>
    </div>
  );
}

// ============================================================
// MODAL: Run Workflow (animated execution)
// ============================================================
function WorkflowRunner({ name = 'Workflow' }) {
  return (
    <ProgressRunner
      steps={[
        `Loading ${name} configuration…`,
        'Resolving variables · contact pool…',
        'Pre-flight: API quotas, deliverability, compute…',
        'Firing trigger event…',
        'Action 1 of 4: Send email…',
        'Action 2 of 4: Wait 24h (simulating)…',
        'Action 3 of 4: Send follow-up SMS…',
        'Action 4 of 4: Update CRM stage…',
        'Logging telemetry · all green',
      ]}
      onDone={() => { setTimeout(() => { window.closeModal(); window.toast(`${name} test complete`, 'ok', 'All 4 actions succeeded · 0 errors · 1,284 affected'); }, 800); }}
      doneLabel={`${name} test run complete`}
    />
  );
}

// ============================================================
// MODAL: Export Options
// ============================================================
function ExportOptions({ subject = 'data' }) {
  const [fmt, setFmt] = React.useState('csv');
  const [scope, setScope] = React.useState('current_view');
  return (
    <div>
      <div style={{ marginBottom: 14, fontSize: 13 }}>Export <strong>{subject}</strong>. Choose format and scope below.</div>
      <div style={_row}>
        <div><label style={_label}>Format</label>
          <ChipGrid value={fmt} onChange={setFmt} cols={3} options={[
            { k: 'csv',   label: 'CSV' },
            { k: 'xlsx',  label: 'Excel' },
            { k: 'pdf',   label: 'PDF' },
            { k: 'json',  label: 'JSON' },
            { k: 'parquet', label: 'Parquet' },
            { k: 'gsheet', label: 'Google Sheets' },
          ]}/>
        </div>
        <div><label style={_label}>Scope</label>
          <ChipGrid value={scope} onChange={setScope} cols={1} options={[
            { k: 'current_view', label: 'Current filters' },
            { k: 'all',           label: 'Everything' },
            { k: 'since_30',      label: 'Last 30 days' },
          ]}/>
        </div>
      </div>
      <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 16, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn ghost" onClick={window.closeModal} data-handled="1">Cancel</button>
        <button className="btn primary" data-handled="1" onClick={() => { window.closeModal(); window.toast('Export queued', 'info', `${fmt.toUpperCase()} ready in ~30s · email when done`); }}>Export</button>
      </div>
    </div>
  );
}

// ============================================================
// MODAL: Compose (drawer-style)
// ============================================================
function ComposeModal({ to = '' } = {}) {
  const [c, setC] = React.useState({ channel: 'email', to, subject: '', body: '' });
  const set = (k, v) => setC(o => ({ ...o, [k]: v }));
  const [busy, setBusy] = React.useState(false);
  const gen = async () => {
    setBusy(true);
    try {
      const t = await window.claude.complete({ messages: [{ role: 'user', content: `Write a short, warm ${c.channel} message about: "${c.subject || 'reaching out'}". 2-3 sentences. No preamble.` }] });
      set('body', t);
    } catch { set('body', 'Hi — wanted to reach out. Let me know if a quick call this week works?'); }
    setBusy(false);
  };
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
      <div><label style={_label}>Channel</label>
        <ChipGrid value={c.channel} onChange={v => set('channel', v)} cols={5} options={[
          { k: 'email',    label: 'Email' },
          { k: 'sms',      label: 'SMS' },
          { k: 'whatsapp', label: 'WhatsApp' },
          { k: 'dm',       label: 'DM' },
          { k: 'voice',    label: 'Voice call' },
        ]}/>
      </div>
      <div><label style={_label}>To</label>
        <input style={_input} value={c.to} onChange={e => set('to', e.target.value)} placeholder="contact name, email, or segment"/>
      </div>
      {c.channel === 'email' && (
        <div><label style={_label}>Subject</label>
          <input style={_input} value={c.subject} onChange={e => set('subject', e.target.value)}/>
        </div>
      )}
      <div>
        <div className="row" style={{ justifyContent: 'space-between' }}>
          <label style={{ ..._label, marginBottom: 0 }}>Message</label>
          <button className="btn sm" onClick={gen} disabled={busy} data-handled="1"><span className="gradient-text" style={{ fontWeight: 600 }}>{busy ? 'Writing…' : '✦ Generate'}</span></button>
        </div>
        <textarea style={{ ..._input, minHeight: 120, marginTop: 6, fontFamily: 'var(--font-ui)' }} value={c.body} onChange={e => set('body', e.target.value)}/>
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn ghost" onClick={window.closeModal} data-handled="1">Discard</button>
        <div style={{ display: 'flex', gap: 8 }}>
          <button className="btn" data-handled="1" onClick={() => { window.closeModal(); window.toast('Saved to drafts', 'ok'); }}>Save draft</button>
          <button className="btn primary" data-handled="1" disabled={!c.body.trim()} onClick={() => { window.closeModal(); window.toast('Message sent', 'ok', `Delivered via ${c.channel}`); }}>Send</button>
        </div>
      </div>
    </div>
  );
}

// ============================================================
// MODAL: Logs viewer
// ============================================================
function LogsViewer({ source = 'system' }) {
  const lines = React.useMemo(() => Array.from({ length: 60 }, (_, i) => {
    const ts = new Date(Date.now() - i * 1200).toISOString().slice(11, 19);
    const lvl = ['INFO', 'INFO', 'INFO', 'DEBUG', 'INFO', 'WARN', 'INFO', 'INFO', 'INFO', 'ERROR'][Math.floor(Math.random() * 10)];
    const msgs = [
      'webhook.received instagram.dm id=in_a8f12e',
      'classifier.routing intent=PRICING confidence=0.91',
      'agent.calliope reply.drafted 28 tokens',
      'queue.enqueue priority=HIGH',
      'oauth.refresh tiktok success',
      'rate_limit.warning facebook 82% used',
      'memory.write contact:c_12839 last_touch=now',
      'sequence.advance step=2 → step=3 contact=c_98231',
      'kpi.recalc revenue_today=£18412',
      'error.transient stripe 502 — retrying 3/5',
    ];
    return { ts, lvl, msg: msgs[Math.floor(Math.random() * msgs.length)] };
  }), []);
  const LVL = { INFO: 'var(--text-dim)', DEBUG: 'var(--text-faint)', WARN: 'var(--warn)', ERROR: 'var(--danger)' };
  return (
    <div>
      <div className="row" style={{ marginBottom: 12, justifyContent: 'space-between' }}>
        <div className="mono" style={{ fontSize: 11, color: 'var(--text-dim)' }}>{source} · last 60 events</div>
        <div className="row" style={{ gap: 6 }}>
          <span className="tag live">STREAMING</span>
          <button className="btn sm" data-handled="1">Pause</button>
          <button className="btn sm" data-handled="1" onClick={() => window.runAction('export', { subject: 'logs' })}>Export</button>
        </div>
      </div>
      <div style={{ background: '#03040c', border: '1px solid var(--border)', borderRadius: 6, padding: 12, maxHeight: 400, overflowY: 'auto', fontFamily: 'var(--font-mono)', fontSize: 11, lineHeight: 1.6 }}>
        {lines.map((l, i) => (
          <div key={i} style={{ display: 'grid', gridTemplateColumns: '70px 50px 1fr', gap: 10 }}>
            <span style={{ color: 'var(--text-faint)' }}>{l.ts}</span>
            <span style={{ color: LVL[l.lvl] }}>{l.lvl}</span>
            <span style={{ color: 'var(--text-dim)' }}>{l.msg}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

// ============================================================
// MODAL: Duplicate / Clone
// ============================================================
function CloneModal({ subject = 'this item', defaultName = 'Untitled · copy' }) {
  const [name, setName] = React.useState(defaultName);
  return (
    <div>
      <label style={_label}>New name</label>
      <input style={_input} value={name} onChange={e => setName(e.target.value)}/>
      <div style={{ marginTop: 14, padding: 12, background: 'rgba(0,0,0,0.25)', border: '1px solid var(--border)', borderRadius: 6, fontSize: 12, color: 'var(--text-dim)' }}>
        Everything from the original will be copied: config, triggers, actions, audience, schedule. You can edit anything after.
      </div>
      <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 16, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn ghost" onClick={window.closeModal} data-handled="1">Cancel</button>
        <button className="btn primary" data-handled="1" onClick={() => { window.closeModal(); window.toast(`Duplicated · "${name}"`, 'ok', 'Find it in your list'); }}>Duplicate</button>
      </div>
    </div>
  );
}

// ============================================================
// MODAL: Optimize workflow
// ============================================================
function OptimizeWorkflow({ name = 'workflow' }) {
  const [phase, setPhase] = React.useState('running');
  if (phase === 'running') {
    return <ProgressRunner steps={[
      `Analyzing ${name} traces (last 7 days)…`,
      'Computing per-step latency, drop-off…',
      'Comparing against best-in-class peers…',
      'Searching prompt + action library for upgrades…',
      'Estimating ROI of each upgrade…',
    ]} onDone={() => setPhase('done')} doneLabel="Analysis complete"/>;
  }
  const ups = [
    { title: 'Replace step 2 prompt with v3 template',     impact: '+12% reply rate',  conf: 'High' },
    { title: 'Cut wait from 24h → 6h after first email',   impact: '+8% conversion',   conf: 'Med' },
    { title: 'Add SMS follow-up if email not opened in 4h', impact: '+22% recovery',    conf: 'High' },
    { title: 'Branch on lead score (>70 → fast track)',     impact: '+£4k / mo',        conf: 'High' },
  ];
  return (
    <div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {ups.map((u, i) => (
          <div key={i} style={{ padding: 12, borderRadius: 6, background: 'rgba(255,255,255,0.025)', border: '1px solid var(--border)' }}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <div style={{ flex: 1, fontSize: 13 }}>{u.title}</div>
              <span className="up mono" style={{ fontSize: 11 }}>{u.impact}</span>
              <button className="btn sm" data-handled="1" onClick={() => window.toast('Applied', 'ok', u.title)}>Apply</button>
            </div>
          </div>
        ))}
      </div>
      <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 16, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn ghost" onClick={window.closeModal} data-handled="1">Close</button>
        <button className="btn primary" data-handled="1" onClick={() => { window.closeModal(); window.toast('Workflow optimized', 'ok', '4 upgrades deploying · expected lift +28% over 14 days'); }}>Apply all (4)</button>
      </div>
    </div>
  );
}

// ============================================================
// MODAL: API key / Rotate
// ============================================================
function APIKeyModal() {
  const [key] = React.useState('dem_sk_' + Math.random().toString(36).slice(2, 18) + '_' + Math.random().toString(36).slice(2, 12));
  return (
    <div>
      <div style={{ padding: 14, background: 'rgba(255,177,75,0.08)', border: '1px solid rgba(255,177,75,0.3)', borderRadius: 6, fontSize: 12.5, marginBottom: 14 }}>
        ⚠ This is the only time we'll show this key in full. Copy and store it in a secret manager.
      </div>
      <label style={_label}>New key</label>
      <div style={{ display: 'flex', gap: 6 }}>
        <input style={{ ..._input, fontFamily: 'var(--font-mono)', fontSize: 12 }} readOnly value={key}/>
        <button className="btn" data-handled="1" onClick={() => { navigator.clipboard?.writeText(key); window.toast('Copied to clipboard', 'ok'); }}>Copy</button>
      </div>
      <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 16, paddingTop: 16, borderTop: '1px solid var(--border)' }}>
        <button className="btn primary" data-handled="1" onClick={() => { window.closeModal(); window.toast('Key rotated', 'ok', 'Old key revoked · update your integrations'); }}>Done</button>
      </div>
    </div>
  );
}

// ============================================================
// MODAL: Test Connection (animated)
// ============================================================
function TestConnection({ name = 'Integration' }) {
  return <ProgressRunner
    steps={[`Ping ${name} endpoint…`, 'Validate auth token…', 'Pull last 10 events…', 'Echo write/delete (rollback)…', 'Latency baseline…']}
    onDone={() => { setTimeout(() => { window.closeModal(); window.toast(`${name} healthy`, 'ok', 'Round-trip 142ms · 0 errors · webhook OK'); }, 600); }}
    doneLabel="All checks passed"
  />;
}

// ============================================================
// MODAL: Deep Analysis
// ============================================================
function DeepAnalysis() {
  const [phase, setPhase] = React.useState('running');
  if (phase === 'running') {
    return <ProgressRunner steps={[
      'Pulling 90 days of telemetry…',
      'Building per-channel attribution model…',
      'Running CAC / LTV sensitivity analysis…',
      'Detecting anomalies (z-score sweep)…',
      'Computing 24 segment ROAS deltas…',
      'Synthesizing executive summary…',
    ]} onDone={() => setPhase('done')} doneLabel="Analysis complete"/>;
  }
  return (
    <div>
      <div style={{ marginBottom: 12 }}>
        <div className="serif" style={{ fontSize: 18, fontStyle: 'italic' }}>The story your numbers tell</div>
        <div className="dim" style={{ fontSize: 12 }}>90 days · all channels · all segments</div>
      </div>
      {[
        { h: 'TikTok is your engine',         t: '£8.40 returned per £1 spent. 38% of new revenue. Scale spend before competitors notice.' },
        { h: 'CAC dropped 12% month-over-month', t: 'Driven by AI auto-reply + better targeting. £184 → £162.' },
        { h: 'Customer LTV up 8%',             t: 'Loyalty workflow + review-request automation. Expect +£24k by Q3.' },
        { h: 'One worrying signal',             t: 'Calliope sequence "Cold #2" hurting domain reputation. Pause + regenerate. Recoverable.' },
      ].map((s, i) => (
        <div key={i} style={{ padding: 12, borderLeft: '2px solid var(--cyan)', background: 'rgba(75,232,255,0.04)', marginBottom: 6, borderRadius: 4 }}>
          <div style={{ fontSize: 13, fontWeight: 500 }}>{s.h}</div>
          <div style={{ fontSize: 11.5, color: 'var(--text-dim)', marginTop: 3 }}>{s.t}</div>
        </div>
      ))}
      <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 8, marginTop: 14 }}>
        <button className="btn" data-handled="1" onClick={() => window.toast('Exported PDF', 'ok')}>Export PDF</button>
        <button className="btn primary" data-handled="1" onClick={() => { window.closeModal(); window.demiurgeNav?.('analytics'); }}>Open analytics</button>
      </div>
    </div>
  );
}

// ============================================================
// ACTION REGISTRY
// ============================================================
window.actions = {
  // Major CTAs
  launchCampaign:    () => window.openModal({ title: 'Launch a campaign',         subtitle: 'Email, SMS, social — Demiurge will deliver and track', icon: 'Megaphone', width: 680, body: <CampaignBuilder/> }),
  createCampaign:    () => window.actions.launchCampaign(),
  newCampaign:       () => window.actions.launchCampaign(),
  editCampaign:      (o) => window.openModal({ title: 'Edit campaign',            subtitle: o?.name || 'Untitled', icon: 'Megaphone', width: 680, body: <CampaignBuilder defaults={o}/> }),
  createFunnel:      () => window.openModal({ title: 'Create a funnel',           subtitle: 'A path that turns strangers into customers', icon: 'Funnel', width: 680, body: <FunnelWizard/> }),
  newFunnel:         () => window.actions.createFunnel(),
  deployWorkflow:    () => window.openModal({ title: 'Deploy a workflow',         subtitle: 'Triggers + actions · runs forever', icon: 'Flow', width: 680, body: <WorkflowBuilder/> }),
  newWorkflow:       () => window.actions.deployWorkflow(),
  newAutomation:     () => window.actions.deployWorkflow(),
  spinUpAgent:       () => window.openModal({ title: 'Spin up an operator',       subtitle: 'A new AI agent on your team', icon: 'Agent', width: 720, body: <AgentSpinup/> }),
  newAgent:          () => window.actions.spinUpAgent(),
  deployOperator:    () => window.actions.spinUpAgent(),
  runAIAudit:        () => window.openModal({ title: 'AI Audit',                  subtitle: 'Cross-channel scan · finds high-leverage improvements', icon: 'Sparkles', width: 640, body: <AIAudit/> }),
  generateReport:    () => window.openModal({ title: 'Generate a report',         subtitle: 'Pick type and we will compile it', icon: 'Chart', width: 600, body: <ReportCenter/> }),
  postEverywhere:    () => window.openModal({ title: 'Content distribution',      subtitle: 'One post · every platform · scheduled or now', icon: 'Globe', width: 720, body: <ContentDistribution/> }),
  createContent:     () => window.openModal({ title: 'AI Content Studio',         subtitle: 'Generate posts, ads, emails, scripts, captions', icon: 'Sparkles', width: 680, body: <ContentStudio/> }),
  leadGrowth:        () => window.openModal({ title: 'How to get more leads',     subtitle: 'Personalised recommendations · ranked by impact', icon: 'Bolt', width: 680, body: <LeadGrowth/> }),
  improveFunnel:     () => window.openModal({ title: 'Improve your funnel',       subtitle: 'Where you lose customers · how to fix it', icon: 'Funnel', width: 640, body: <FunnelOptimization/> }),

  // Navigate
  bookLeads:         () => window.demiurgeNav?.('inbox'),
  messageCustomers:  () => window.demiurgeNav?.('inbox'),
  messageLeads:      () => window.demiurgeNav?.('inbox'),
  seeAppointments:   () => window.demiurgeNav?.('calendar'),
  blockTime:         () => window.openModal({ title: 'Block off time',            subtitle: 'Keep your calendar protected', icon: 'Calendar', width: 480, body: <SchedulePicker subject="time off"/> }),
  goAnalytics:       () => window.demiurgeNav?.('analytics'),
  askAI:             () => window.demiurgeOpenAI?.(),

  // Channel ops
  reconnect:         (o) => window.openModal({ title: `Reconnect ${o?.name || 'channel'}`, subtitle: 'Re-authenticate and resync', icon: 'Plug', width: 520, body: <ConnectionFlow name={o?.name || 'channel'}/> }),
  connect:           (o) => window.openModal({ title: `Connect ${o?.name || 'a channel'}`, subtitle: 'OAuth + initial sync',   icon: 'Plug', width: 520, body: <ConnectionFlow name={o?.name || 'integration'}/> }),
  rotateKey:         () => window.openModal({ title: 'Rotate API key',            subtitle: 'Issue a new key · revoke the old', icon: 'Code', width: 520, body: <APIKeyModal/> }),
  testConnection:    (o) => window.openModal({ title: `Test ${o?.name || 'connection'}`, subtitle: 'Round-trip validation',     icon: 'Plug', width: 480, body: <TestConnection name={o?.name || 'integration'}/> }),
  compose:           (o) => window.openModal({ title: 'Compose',                  subtitle: 'New outbound message', icon: 'Mail',   width: 600, body: <ComposeModal {...(o || {})}/> }),
  schedule:          (o) => window.openModal({ title: 'Schedule',                  subtitle: o?.subject || 'Pick a time', icon: 'Calendar', width: 460, body: <SchedulePicker subject={o?.subject || 'this'}/> }),
  viewLogs:          (o) => window.openModal({ title: 'Logs',                      subtitle: o?.source || 'Live event stream', icon: 'Code', width: 720, body: <LogsViewer source={o?.source || 'system'}/> }),

  // Workflow ops
  runWorkflow:       (o) => window.openModal({ title: `Run "${o?.name || 'workflow'}"`, subtitle: 'Live execution preview',  icon: 'Bolt', width: 540, body: <WorkflowRunner name={o?.name}/> }),
  cloneWorkflow:     (o) => window.openModal({ title: 'Duplicate workflow',        subtitle: 'Copy with all config', icon: 'Plus', width: 480, body: <CloneModal subject="workflow" defaultName={(o?.name || 'Workflow') + ' · copy'}/> }),
  duplicate:         (o) => window.actions.cloneWorkflow(o),
  optimizeWorkflow:  (o) => window.openModal({ title: 'Optimize with AI',          subtitle: o?.name || 'Suggested upgrades', icon: 'Sparkles', width: 600, body: <OptimizeWorkflow name={o?.name}/> }),
  launchTest:        (o) => window.openModal({ title: 'Launch split test',         subtitle: 'A vs B · Demiurge picks the winner', icon: 'Bolt', width: 540, body: <WorkflowRunner name="Split test"/> }),

  // Analytics ops
  deepAnalysis:      () => window.openModal({ title: 'Run deep analysis',         subtitle: '90 days · all channels · all segments', icon: 'Chart', width: 640, body: <DeepAnalysis/> }),
  exportIntel:       () => window.openModal({ title: 'Export intelligence',        subtitle: 'Pick format and scope', icon: 'Chart', width: 520, body: <ExportOptions subject="analytics"/> }),
  export:            (o) => window.openModal({ title: 'Export',                    subtitle: o?.subject || 'Choose format', icon: 'Code', width: 480, body: <ExportOptions subject={o?.subject || 'data'}/> }),
};

// ============================================================
// runAction(key, opts) — entry point used by smart-click + cmdk + ai panel
// ============================================================
window.runAction = (key, opts) => {
  const a = window.actions[key];
  if (typeof a === 'function') { a(opts); return true; }
  return false;
};

// ============================================================
// Map button text → action key (used by smart-click handler)
// ============================================================
window.actionForText = (txt) => {
  const t = txt.toLowerCase().trim();
  const exact = {
    'launch campaign': 'launchCampaign',
    'create campaign': 'createCampaign',
    'new campaign':    'newCampaign',
    'edit campaign':   'editCampaign',
    'create funnel':   'createFunnel',
    'new funnel':      'newFunnel',
    'deploy workflow': 'deployWorkflow',
    'new workflow':    'newWorkflow',
    'new automation':  'newAutomation',
    'spin up agent':   'spinUpAgent',
    'deploy operator': 'deployOperator',
    'deploy new operator': 'deployOperator',
    'new operator':    'deployOperator',
    'run ai audit':    'runAIAudit',
    'ai audit':        'runAIAudit',
    'generate report': 'generateReport',
    'view report':     'generateReport',
    'view reports':    'generateReport',
    'book leads':      'bookLeads',
    'see appointments': 'seeAppointments',
    'block off time':  'blockTime',
    'message customers': 'messageCustomers',
    'message leads':   'messageLeads',
    'ask ai assistant':'askAI',
    'ask demiurge':    'askAI',
    'get more leads':  'leadGrowth',
    'improve funnel':  'improveFunnel',
    'improve my journey': 'improveFunnel',
    'improve my funnel':  'improveFunnel',
    'post everywhere': 'postEverywhere',
    'create content':  'createContent',
    'write me a campaign': 'launchCampaign',
    'post to social':  'postEverywhere',
    'reconnect':       'reconnect',
    'connect':         'connect',
    'install':         'connect',
    'install mcp server': 'connect',
    'fix':             'connect',
    'manage':          'connect',
    'rotate api key':  'rotateKey',
    'new key':         'rotateKey',
    'test connection': 'testConnection',
    'compose':         'compose',
    'view logs':       'viewLogs',
    'show logs':       'viewLogs',
    'schedule':        'schedule',
    'send proposal':   'compose',
    'email owner':     'compose',
    'add contact':     'compose',
    'invite':          'compose',
    'run workflow':    'runWorkflow',
    'run test':        'launchTest',
    'launch test':     'launchTest',
    'clone workflow':  'cloneWorkflow',
    'optimize workflow': 'optimizeWorkflow',
    'optimize':        'optimizeWorkflow',
    'run deep analysis': 'deepAnalysis',
    'deep analysis':   'deepAnalysis',
    'export intelligence': 'exportIntel',
    'see the breakdown':   'deepAnalysis',
    'see the details':     'goAnalytics',
    'see marketing details': 'goAnalytics',
    'see your leads':      'messageLeads',
    'see your calendar':   'seeAppointments',
    'reply now':           'messageCustomers',
    'add customer':        'compose',
  };
  return exact[t] || null;
};

window.CampaignBuilder = CampaignBuilder;
window.FunnelWizard = FunnelWizard;
window.WorkflowBuilder = WorkflowBuilder;
window.AgentSpinup = AgentSpinup;
window.AIAudit = AIAudit;
window.ContentStudio = ContentStudio;
window.LeadGrowth = LeadGrowth;
window.ProgressRunner = ProgressRunner;
