function CrmOutreachWorkflowEditor({ lang, navigate }) {
  const de = lang === 'de';
  const t = (german, english) => de ? german : english;
  const engine = window.MesperOutreachWorkflow;
  const blank = () => ({ schema: 1, enabled: false, pitch: { delay: { value: 0, unit: 'hours' }, reminders: [] }, followups: [] });
  const [campaigns, setCampaigns] = React.useState([]);
  const [campaignId, setCampaignId] = React.useState('');
  const [form, setForm] = React.useState(blank);
  const [loading, setLoading] = React.useState(true);
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState(null);
  const [notice, setNotice] = React.useState('');
  const pending = React.useRef(null);
  const pendingMessaging = React.useRef(null);
  const [messagingText, setMessagingText] = React.useState('');
  const [linkedin, setLinkedin] = React.useState({ accountUrl: '', detection: false, autoSend: false });
  const [linkedinStatus, setLinkedinStatus] = React.useState({ devices: [], sends: [] });
  const [pairSend, setPairSend] = React.useState(false);
  const [pairBundle, setPairBundle] = React.useState('');
  const pendingLinkedin = React.useRef(null);
  const pendingPair = React.useRef(null);
  const selected = campaigns.find(c => c.id === campaignId);
  async function load() {
    setLoading(true); setError(null);
    try {
      const rows = (await window.MesperOutreachDB.campaigns()).filter(c => c.channel === 'linkedin_outbound');
      const row = rows.find(c => c.id === campaignId) || rows.find(c => c.settings?.native) || rows[0];
      setCampaigns(rows); setCampaignId(row?.id || '');
      setForm(row?.settings?.workflow ? structuredClone(row.settings.workflow) : blank()); pending.current = null;
      setMessagingText(row?.settings?.messagingApproach?.text || ''); pendingMessaging.current = null;
      setLinkedin(row?.settings?.linkedin || { accountUrl: '', detection: false, autoSend: false });
      pendingLinkedin.current = null; pendingPair.current = null; setPairBundle('');
      setLinkedinStatus(await window.MesperOutreachDB.linkedinStatus());
    } catch (e) { setError(e); } finally { setLoading(false); }
  }
  React.useEffect(() => { load(); }, []);
  function change(next) { setForm(next); setNotice(''); setError(null); pending.current = null; }
  function choose(id) {
    setCampaignId(id); const row = campaigns.find(c => c.id === id);
    change(row?.settings?.workflow ? structuredClone(row.settings.workflow) : blank());
    setMessagingText(row?.settings?.messagingApproach?.text || ''); pendingMessaging.current = null;
    setLinkedin(row?.settings?.linkedin || { accountUrl: '', detection: false, autoSend: false });
    pendingLinkedin.current = null; pendingPair.current = null; setPairBundle('');
  }
  async function linkedinAction(action, payload) {
    const result = await window.MesperOutreachDB.command({ operationId: crypto.randomUUID(), memberId: null, expectedVersion: 0, action, payload });
    setLinkedinStatus(await window.MesperOutreachDB.linkedinStatus()); return result;
  }
  async function saveLinkedin() {
    setBusy(true); setError(null); setNotice('');
    try {
      if (!pendingLinkedin.current) pendingLinkedin.current = { operationId: crypto.randomUUID(), memberId: null, expectedVersion: selected?.settings?.linkedin?.revision || 0, action: 'save_linkedin_settings', payload: { campaignId, accountUrl: linkedin.accountUrl.trim(), detection: linkedin.detection, autoSend: linkedin.autoSend } };
      const result = await window.MesperOutreachDB.command(pendingLinkedin.current);
      setLinkedin(result.linkedin); setCampaigns(rows => rows.map(c => c.id === campaignId ? { ...c, settings: { ...c.settings, linkedin: result.linkedin } } : c));
      pendingLinkedin.current = null; setNotice(t('LinkedIn-Einstellungen gespeichert. Kontakte bleiben unverändert.', 'LinkedIn settings saved. Contacts remain unchanged.'));
    } catch (e) { setError(e); } finally { setBusy(false); }
  }
  async function pairLinkedin() {
    setBusy(true); setError(null); setNotice('');
    try {
      if (!pendingPair.current) pendingPair.current = { operationId: crypto.randomUUID(), memberId: null, expectedVersion: 0, action: 'pair_linkedin_device', payload: { accountUrl: linkedin.accountUrl.trim(), detection: true, send: pairSend, credential: crypto.randomUUID() + crypto.randomUUID() } };
      const request = pendingPair.current;
      const result = await window.MesperOutreachDB.command(request);
      setPairBundle(JSON.stringify({ projectUrl: 'https://wtqtldsjgqebywnkunxa.supabase.co', deviceId: result.deviceId, accountUrl: result.accountUrl, credential: request.payload.credential }));
      pendingPair.current = null; setLinkedinStatus(await window.MesperOutreachDB.linkedinStatus());
    } catch (e) { setError(e); } finally { setBusy(false); }
  }
  async function revokeLinkedin(deviceId) {
    setBusy(true); setError(null);
    try { await linkedinAction('revoke_linkedin_device', { deviceId }); setNotice(t('Gerät gesperrt. Neue Erkennung und Send-Permits sind gesperrt.', 'Device revoked. New observations and send permits are blocked.')); }
    catch (e) { setError(e); } finally { setBusy(false); }
  }
  function patchLinkedin(patch) { setLinkedin(v => ({ ...v, ...patch })); pendingLinkedin.current = null; pendingPair.current = null; setPairBundle(''); }
  const patchPitch = patch => change({ ...form, pitch: { ...form.pitch, ...patch } });
  const patchStep = (index, patch) => change({ ...form, followups: form.followups.map((s, i) => i === index ? { ...s, ...patch } : s) });
  function move(index, direction) {
    const rows = [...form.followups]; const other = index + direction;
    [rows[index], rows[other]] = [rows[other], rows[index]]; change({ ...form, followups: rows });
  }
  async function save() {
    if (engine.validate(form).length) { setError({ message: t('Ungültige Einstellungen. Abstände müssen ganze Zahlen sein; Reminder müssen aufsteigend sein.', 'Invalid settings. Delays must be whole numbers; reminders must be ascending.') }); return; }
    setBusy(true); setError(null); setNotice('');
    try {
      if (!pending.current) pending.current = { operationId: crypto.randomUUID(), memberId: null, expectedVersion: selected?.settings?.workflowRevision || 0, action: 'save_workflow', payload: { campaignId, workflow: structuredClone(form) } };
      const result = await window.MesperOutreachDB.command(pending.current);
      setCampaigns(rows => rows.map(c => c.id === campaignId ? { ...c, settings: { ...c.settings, workflow: result.workflow, workflowRevision: result.workflowRevision } } : c));
      pending.current = null; setNotice(t('Workflow gespeichert. Keine Nachricht versendet.', 'Workflow saved. No message sent.'));
    } catch (e) { setError(e); } finally { setBusy(false); }
  }
  async function saveMessaging() {
    setBusy(true); setError(null); setNotice('');
    try {
      if (!pendingMessaging.current) pendingMessaging.current = { operationId: crypto.randomUUID(), memberId: null, expectedVersion: selected?.settings?.messagingApproach?.revision || 0, action: 'save_messaging_approach', payload: { campaignId, text: messagingText } };
      const result = await window.MesperOutreachDB.command(pendingMessaging.current);
      setCampaigns(rows => rows.map(c => c.id === campaignId ? { ...c, settings: { ...c.settings, messagingApproach: result.messagingApproach } } : c));
      setMessagingText(result.messagingApproach.text); pendingMessaging.current = null;
      setNotice(t('Messaging-Ansatz gespeichert. Neue Drafts und Reviews nutzen diese Fassung.', 'Messaging approach saved. New drafts and reviews use this version.'));
    } catch (e) { setError(e); } finally { setBusy(false); }
  }
  function delayFields(delay, label, update) {
    return <div className="crm-workflow-delay">
      <label className="crm-outreach-field"><span>{t('Abstand', 'Delay')}</span><input aria-label={`${label}${label === 'Pitch' ? '-' : ' '}${t('Abstand', 'delay')}`} type="number" min="0" max="365" step="1" value={delay.value} onChange={e => update({ ...delay, value: e.target.value === '' ? '' : Number(e.target.value) })} /></label>
      <label className="crm-outreach-field"><span>{t('Einheit', 'Unit')}</span><select aria-label={`${label}${label === 'Pitch' ? '-' : ' '}${t('Einheit', 'unit')}`} value={delay.unit} onChange={e => update({ ...delay, unit: e.target.value })}><option value="hours">{t('Stunden', 'Hours')}</option><option value="days">{t('Tage (24h)', 'Days (24h)')}</option><option value="business_days">{t('Werktage (Mo–Fr)', 'Business days (Mon–Fri)')}</option></select></label>
    </div>;
  }
  return <section className="crm-outreach-shell crm-workflow-editor">
    <div className="crm-outreach-header"><div><button className="crm-outreach-back" onClick={() => navigate('/crm/outreach')}>← Outreach</button><h1 className="crm-outreach-title">LinkedIn Workflow</h1><p className="crm-outreach-muted">{t('Deine Strecke. Deine Abstände. Freigabe vor jedem echten Versand.', 'Your sequence. Your timing. Approval before any actual send.')}</p></div><button type="button" className="crm-outreach-button" onClick={save} disabled={loading || busy || !selected}>{busy ? t('Speichert…', 'Saving…') : t('Workflow speichern', 'Save workflow')}</button></div>
    {loading && <p role="status">{t('Lädt…', 'Loading…')}</p>}
    {error && <div role="alert" className="crm-outreach-state crm-outreach-state-error">{error.code === 'VERSION_CONFLICT' ? t('Workflow wurde geändert. Neu laden und deine Änderungen erneut prüfen.', 'The workflow changed. Reload and review your changes.') : error.message}<button className="crm-outreach-button crm-outreach-button-secondary" onClick={load} disabled={busy}>{t('Neu laden', 'Reload')}</button></div>}
    {notice && <p role="status" className="crm-outreach-notice">{notice}</p>}
    {!loading && !campaigns.length && <p>{t('Keine LinkedIn-Kampagne vorhanden.', 'No LinkedIn campaign available.')}</p>}
    {!loading && selected && <fieldset className="crm-workflow-fieldset" disabled={busy}>
      <div className="crm-workflow-settings crm-outreach-card">
        <label className="crm-outreach-field"><span>{t('Kampagne', 'Campaign')}</span><select aria-label={t('Workflow-Kampagne', 'Workflow campaign')} value={campaignId} onChange={e => choose(e.target.value)}>{campaigns.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}</select></label>
        <label className="crm-outreach-checkbox"><input type="checkbox" checked={form.enabled} onChange={e => change({ ...form, enabled: e.target.checked })} />{t('Plan für neue Strecken verwenden', 'Use plan for new sequences')}</label>
        <p className="crm-outreach-muted">{t('Speichern aktiviert keine Kontakte oder Kampagnen. Laufende Aufgaben behalten ihren gespeicherten Plan.', 'Saving does not activate contacts or campaigns. Existing tasks retain their saved plan.')}</p>
        <button type="button" className="crm-outreach-button crm-outreach-button-secondary" onClick={() => change(engine.example())}>{t('Früheres 24h/4/7-Beispiel laden', 'Load previous 24h/4/7 example')}</button>
      </div>
      <section className="crm-outreach-card" aria-label={t('Messaging-Learning', 'Messaging learning')}>
        <div className="crm-outreach-card-header"><h2>{t('So sollen meine Nachrichten klingen', 'How my messages should sound')}</h2><span>{t('Version', 'Version')} {selected.settings?.messagingApproach?.revision || 0}</span></div>
        <label className="crm-outreach-field"><span>{t('Korrigierter Messaging-Ansatz', 'Corrected messaging approach')}</span><textarea aria-label={t('Korrigierter Messaging-Ansatz', 'Corrected messaging approach')} rows="8" maxLength="4096" value={messagingText} onChange={e => { setMessagingText(e.target.value); pendingMessaging.current = null; setNotice(''); }} placeholder={t('Dein korrigierter Ansatz, gute Formulierungen und Beispiele. Was soll anders sein als im bisherigen Draft?', 'Your corrected approach, wording and examples. What should change compared with the previous draft?')} /></label>
        <p className="crm-outreach-muted">{t('Gilt für neue Drafts und Reviews dieser Kampagne. Deine neueste gespeicherte Fassung hat Vorrang vor allgemeinen Voice-Regeln. Beispiele sind Stilreferenzen, keine belegten Aussagen über andere Kontakte.', 'Applies to new drafts and reviews in this campaign. Your latest saved version takes priority over generic voice rules. Examples guide style, not facts about other contacts.')}</p>
        <p className="crm-outreach-muted">{t('Speichern bricht offene Agent-Jobs mit der alten Vorgabe ab. Bestehende Texte und Freigaben bleiben unverändert. Leer speichern entfernt die aktive Vorgabe. Kein Modelltraining, keine Versandfreigabe.', 'Saving cancels pending agent jobs using the old approach. Existing messages and approvals stay unchanged. Save empty to remove the active guidance. No model training or send approval.')}</p>
        <div className="crm-outreach-inline-actions"><button type="button" className="crm-outreach-button" onClick={saveMessaging}>{t('Messaging-Ansatz speichern', 'Save messaging approach')}</button><span className="crm-outreach-muted">{messagingText.length}/4096</span></div>
      </section>
      <section className="crm-outreach-card" aria-label={t('LinkedIn-Anbindung', 'LinkedIn connection')}>
        <div className="crm-outreach-card-header"><h2>{t('LinkedIn-Anbindung', 'LinkedIn connection')}</h2><span>Chrome · Staging</span></div>
        <label className="crm-outreach-field"><span>{t('Eigenes LinkedIn-Profil', 'Own LinkedIn profile')}</span><input type="url" aria-label={t('Eigenes LinkedIn-Profil', 'Own LinkedIn profile')} value={linkedin.accountUrl} placeholder="https://www.linkedin.com/in/…/" onChange={e => patchLinkedin({ accountUrl: e.target.value })} /></label>
        <label className="crm-outreach-checkbox"><input type="checkbox" checked={linkedin.detection} onChange={e => patchLinkedin({ detection: e.target.checked })} />{t('Annahme für aktive Kontakte automatisch erkennen', 'Automatically detect acceptance for active contacts')}</label>
        <label className="crm-outreach-checkbox"><input type="checkbox" checked={linkedin.autoSend} onChange={e => patchLinkedin({ autoSend: e.target.checked })} />{t('Konkrete freigegebene Nachrichten bei Fälligkeit automatisch senden', 'Automatically send specifically approved messages when due')}</label>
        <p className="crm-outreach-muted">{t('Auto-Send braucht Review und menschliche Freigabe der aktuellen Nachricht. Änderungen brauchen neue Freigabe. Speichern aktiviert keine Kontakte. Alternativ im Kontakt „Über LinkedIn senden“ wählen.', 'Auto-send requires review and human approval of the current message. Changes need new approval. Saving does not activate contacts. Alternatively select “Send via LinkedIn” on a contact.')}</p>
        <button type="button" className="crm-outreach-button" onClick={saveLinkedin} disabled={busy || !linkedin.accountUrl}>{t('LinkedIn-Einstellungen speichern', 'Save LinkedIn settings')}</button>
        <details><summary>{t('Chrome koppeln und Geräte verwalten', 'Pair Chrome and manage devices')}</summary>
          <p className="crm-outreach-muted">{t('Eigene Extension unter extensions/outreach-linkedin über „Entpackte Erweiterung laden“ in Chrome installieren. LinkedIn kann automatisierte Nutzung einschränken. Die Kopplung gilt 30 Tage und nur für dein hinterlegtes Konto.', 'Install the extension from extensions/outreach-linkedin using “Load unpacked” in Chrome. LinkedIn may restrict automated use. Pairing lasts 30 days and binds to your specified account.')}</p>
          <label className="crm-outreach-checkbox"><input type="checkbox" checked={pairSend} onChange={e => { setPairSend(e.target.checked); pendingPair.current = null; }} />{t('Diesem Gerät zusätzlich LinkedIn-Versand erlauben', 'Also allow LinkedIn sending on this device')}</label>
          <button type="button" className="crm-outreach-button crm-outreach-button-secondary" onClick={pairLinkedin} disabled={busy || !linkedin.accountUrl}>{t('Neue Chrome-Kopplung erstellen', 'Create Chrome pairing')}</button>
          {pairBundle && <><label className="crm-outreach-field"><span>{t('Kopplung nur in die Mesper-Extension einfügen', 'Paste pairing only into the Mesper extension')}</span><textarea rows="6" readOnly aria-label={t('Chrome-Kopplung', 'Chrome pairing')} value={pairBundle} /></label><button type="button" className="crm-outreach-button crm-outreach-button-secondary" onClick={() => setPairBundle('')}>{t('Kopplung ausblenden', 'Hide pairing')}</button></>}
          {linkedinStatus.devices.map(d => <div className="crm-outreach-agent-device" key={d.deviceId}><div><strong>{d.accountUrl}</strong><span>{d.revokedAt ? t('Gesperrt', 'Revoked') : new Date(d.expiresAt) <= new Date() ? t('Abgelaufen', 'Expired') : t('Gekoppelt', 'Paired')} · {d.send ? t('Erkennung + Versand', 'Detection + sending') : t('Nur Erkennung', 'Detection only')}</span><span>{t('Letzte Prüfung', 'Last check')}: {d.lastSeenAt ? new Date(d.lastSeenAt).toLocaleString(de ? 'de-DE' : 'en-GB') : t('Noch kein Check', 'No check yet')}</span></div>{!d.revokedAt && <button type="button" className="crm-outreach-button crm-outreach-button-danger" disabled={busy} onClick={() => revokeLinkedin(d.deviceId)}>{t('Gerät sperren', 'Revoke device')}</button>}</div>)}
        </details>
        <p className="crm-outreach-muted">{t('Erkennung startet Fristen bei „erstmals erkannt“, falls der tatsächliche Annahmezeitpunkt fehlt. Chrome muss laufen, der Mac darf nicht schlafen. Kein 24/7-Cloudversand.', 'Detection starts deadlines at “first detected” when actual acceptance time is missing. Chrome must run and the Mac must be awake. No 24/7 cloud sending.')}</p>
        {linkedinStatus.sends.length > 0 && <div>{linkedinStatus.sends.map(s => <p key={s.sendId}><a href={`#/crm/outreach/m/${s.memberId}`} onClick={e => { e.preventDefault(); navigate(`/crm/outreach/m/${s.memberId}`); }}>{t('Kontakt öffnen', 'Open contact')}</a> · {s.state}{s.state === 'unknown' ? t(' · Versand unklar. Auf LinkedIn prüfen. Kein automatischer Retry.', ' · Send outcome unknown. Check LinkedIn. No automatic retry.') : ''}{['queued','claimed'].includes(s.state) && <button type="button" className="crm-outreach-button crm-outreach-button-secondary" onClick={async () => { try { await linkedinAction('cancel_linkedin_send', { sendId: s.sendId }); } catch (e) { setError(e); } }}>{t('Queue abbrechen', 'Cancel queue')}</button>}</p>)}</div>}
      </section>
      <ol className="crm-workflow-steps">
        <li className="crm-workflow-step"><span className="crm-workflow-number">1</span><div><h2>{t('Kontaktanfrage', 'Connection request')}</h2><p className="crm-outreach-muted">{t('LinkedIn öffnen, Anfrage senden und dokumentieren. Automatischer Versand ist nicht angeschlossen.', 'Open LinkedIn, send and record the invitation. Automatic sending is not connected.')}</p><span className="crm-outreach-status-chip">connecting / pending</span></div></li>
        <li className="crm-workflow-step"><span className="crm-workflow-number">2</span><div><h2>{t('Auf Annahme warten', 'Wait for acceptance')}</h2><p className="crm-outreach-muted">{t('Die gekoppelte Chrome-Extension prüft aktive pending Kontakte. Belegter Annahmezeitpunkt oder deutlich gekennzeichnete erste Erkennung startet den Timer.', 'The paired Chrome extension checks active pending contacts. Verified acceptance time or clearly labeled first detection starts the timer.')}</p><span className="crm-outreach-status-chip">ready / connected</span></div></li>
        <li className="crm-workflow-step"><span className="crm-workflow-number">3</span><div><h2>{t('Erste LinkedIn-DM', 'First LinkedIn DM')}</h2><p className="crm-outreach-muted">{t('Ab Annahme. Entwurf und Review vorbereiten, anschließend menschlich freigeben. Keine Freigabe, kein Versand.', 'From acceptance. Prepare draft and review, then obtain human approval. No approval, no send.')}</p>
          {delayFields(form.pitch.delay, 'Pitch', d => patchPitch({ delay: d }))}
          <h3>{t('Reminder ab Annahme', 'Reminders from acceptance')}</h3>
          <div className="crm-workflow-reminders">{form.pitch.reminders.map((r, i) => <div className="crm-workflow-reminder" key={r.id}>
            <label className="crm-outreach-field"><span>{t('Nach Stunden', 'After hours')}</span><input aria-label={`${t('Reminder', 'Reminder')} ${i + 1} ${t('Stunden', 'hours')}`} type="number" min="0" max="8760" step="1" value={r.hours} onChange={e => patchPitch({ reminders: form.pitch.reminders.map((x, n) => n === i ? { ...x, hours: e.target.value === '' ? '' : Number(e.target.value) } : x) })} /></label>
            <label className="crm-outreach-field"><span>{t('Dringlichkeit', 'Urgency')}</span><select aria-label={`Reminder ${i + 1} ${t('Dringlichkeit', 'urgency')}`} value={r.urgency} onChange={e => patchPitch({ reminders: form.pitch.reminders.map((x, n) => n === i ? { ...x, urgency: e.target.value } : x) })}><option value="normal">{t('Normal', 'Normal')}</option><option value="high">{t('Hoch', 'High')}</option></select></label>
            <button type="button" className="crm-outreach-button crm-outreach-button-secondary" aria-label={`Reminder ${i + 1} ${t('entfernen', 'remove')}`} onClick={() => patchPitch({ reminders: form.pitch.reminders.filter((_, n) => n !== i) })}>{t('Entfernen', 'Remove')}</button>
          </div>)}</div>
          <button type="button" className="crm-outreach-button crm-outreach-button-secondary" disabled={form.pitch.reminders.length >= 10} onClick={() => patchPitch({ reminders: [...form.pitch.reminders, { id: 'reminder_' + crypto.randomUUID(), hours: form.pitch.reminders.length ? form.pitch.reminders.at(-1).hours + 1 : 0, urgency: 'normal' }] })}>{t('Reminder hinzufügen', 'Add reminder')}</button>
        </div></li>
        {form.followups.map((s, i) => <li className="crm-workflow-step" key={s.id}><span className="crm-workflow-number">{i + 4}</span><div><h2>Follow-up {i + 1} · LinkedIn</h2>
          <label className="crm-outreach-field"><span>{t('Schrittname', 'Step name')}</span><input aria-label={`Follow-up ${i + 1} ${t('Name', 'name')}`} maxLength="150" value={s.label} onChange={e => patchStep(i, { label: e.target.value })} /></label>
          <p className="crm-outreach-muted">{t('Ab tatsächlichem Versand der vorherigen Nachricht, nur ohne Antwort.', 'From actual sending of the preceding message, only without a reply.')}</p>
          {delayFields(s.delay, `Follow-up ${i + 1}`, d => patchStep(i, { delay: d }))}
          <label className="crm-outreach-field"><span>{t('Freigabe', 'Approval')}</span><select aria-label={`Follow-up ${i + 1} ${t('Freigabe', 'approval')}`} value={s.approval} onChange={e => patchStep(i, { approval: e.target.value })}><option value="each">{t('Jedes Mal prüfen und freigeben', 'Review and approve each time')}</option><option value="preapproved">{t('Konkrete Nachricht vorab freigeben', 'Pre-approve the specific message')}</option></select></label>
          {s.approval === 'preapproved' && <p className="crm-outreach-muted">{t('Vorabfreigabe gilt nur für den konkreten finalen Text. Textänderungen brauchen neue Freigabe. Auto-Send braucht aktivierte Kopplung, Kampagne und aktuelle Fälligkeit.', 'Pre-approval applies only to the specific final text. Changes require new approval. Auto-send needs active pairing, campaign and current due time.')}</p>}
          <div className="crm-outreach-inline-actions"><button type="button" className="crm-outreach-button crm-outreach-button-secondary" disabled={i === 0} onClick={() => move(i, -1)} aria-label={`Follow-up ${i + 1} ${t('nach oben', 'move up')}`}>{t('Nach oben', 'Move up')}</button><button type="button" className="crm-outreach-button crm-outreach-button-secondary" disabled={i === form.followups.length - 1} onClick={() => move(i, 1)} aria-label={`Follow-up ${i + 1} ${t('nach unten', 'move down')}`}>{t('Nach unten', 'Move down')}</button><button type="button" className="crm-outreach-button crm-outreach-button-danger" onClick={() => change({ ...form, followups: form.followups.filter((_, n) => n !== i) })} aria-label={`Follow-up ${i + 1} ${t('entfernen', 'remove')}`}>{t('Entfernen', 'Remove')}</button></div>
        </div></li>)}
      </ol>
      <button type="button" className="crm-outreach-button crm-outreach-button-secondary" disabled={form.followups.length >= 10} onClick={() => change({ ...form, followups: [...form.followups, { id: 'step_' + crypto.randomUUID(), label: `Follow-up ${form.followups.length + 1}`, delay: { value: 0, unit: 'hours' }, approval: 'each' }] })}>{t('Follow-up hinzufügen', 'Add follow-up')}</button>
      <section className="crm-outreach-card crm-workflow-stops"><h2>{t('Stop-Regeln', 'Stop rules')}</h2><p>{t('Antwort, Meeting, Do-not-contact, Pause, Abschluss oder Kill Switch stoppen weitere Ansprache. Diese Schutzregeln sind nicht abschaltbar.', 'Reply, meeting, do-not-contact, pause, closure or kill switch stop further outreach. These protections cannot be disabled.')}</p><p className="crm-outreach-muted">{t('Am letzten Schritt pausiert der Workflow. Freigabe, Kopieren oder LinkedIn öffnen zählen nicht als Versand.', 'The workflow pauses after its final step. Approval, copy or opening LinkedIn do not count as sending.')}</p></section>
    </fieldset>}
  </section>;
}
