    try { const d = await GET("/campaigns/list?page_size=100"); campaigns = d.campaigns || []; }
    catch { campaigns = []; }
  }

  function renderFilters() {
    const f = $("#filters");
    const campOpts = [{ v: "", t: "All campaigns" }].concat(
      campaigns.map(c => ({ v: String(c.id), t: `#${c.id} — ${c.name}`.slice(0, 60) })));
    if (tab === "attempts") {
      f.innerHTML =
        sel("fCamp", campOpts, st._camp || "") +
        sel("fOutcome", OUTCOMES.map(o => ({ v: o, t: o ? o.replace("_", " ") : "All outcomes" })), st._out || "") +
        `<input id="fSearch" placeholder="Search email or message id…" value="${esc(st._q || "")}">` +
        `<button class="btn sm" id="fGo">Apply</button>`;
      $("#fGo").onclick = applyFilters;
      $("#fSearch").onkeydown = e => { if (e.key === "Enter") applyFilters(); };
    } else if (tab === "events") {
      f.innerHTML =
        sel("fCamp", campOpts, st._camp || "") +
        sel("fEvType", ["", "queued", "submitted", "accepted", "failed", "retry_scheduled",
                        "suppressed", "unsubscribed", "bounced", "dlq"].map(o =>
          ({ v: o, t: o ? o.replace("_", " ") : "All event types" })), st._ev || "") +
        `<button class="btn sm" id="fGo">Apply</button>`;
      $("#fGo").onclick = applyFilters;
    } else if (tab === "audit") {
      f.innerHTML =
        sel("fAction", ["", "auth.login", "auth.register", "campaign.create", "campaign.start",
                        "campaign.pause", "campaign.resume", "campaign.cancel",
                        "recipients.import", "recipients.manual_add", "subjects.import",
                        "templates.upload", "attachments.upload", "phones.import",
                        "suppression.add", "gmail.connect", "gmail.disconnect", "gmail.import_config",
                        "settings.save_batch", "settings.reset"].map(o =>
          ({ v: o, t: o ? o.replace(/\./g, " › ") : "All actions" })), st._act || "") +
        `<button class="btn sm" id="fGo">Apply</button>`;
      $("#fGo").onclick = applyFilters;
    } else {
      f.innerHTML = `<span class="muted small">Jobs that exhausted all retries and were moved to the dead-letter queue (dlq:send).</span>`;
    }
  }

  function applyFilters() {
    if (tab === "attempts") {
      st._camp = $("#fCamp").value; st._out = $("#fOutcome").value; st._q = $("#fSearch").value.trim();
    } else if (tab === "events") {
      st._camp = $("#fCamp").value; st._ev = $("#fEvType").value;
    } else if (tab === "audit") {
      st._act = $("#fAction").value;
    }
    st[tab] = 1;
    load();
  }

  function pagerHTML(total, page, key) {
    const pages = Math.max(1, Math.ceil(total / PS));
    if (pages <= 1) return "";
    return `<button class="btn sm secondary" ${page <= 1 ? "disabled" : ""} data-pg="${page - 1}">‹ Prev</button>
