// Source: index.html script block (extracted). Loaded via <script type="text/babel"> in index.html.
function Queue({ tasks, activeId, setActive, openEditor, onNewTask, taskStats, onTasksLoaded, user }) {
  const isManager = !!(user && user.kind === "manager");
  const { t } = useLang();
  const [filter, setFilter] = React.useState("all");
  const [q, setQ] = React.useState("");
  const [visible, setVisible] = React.useState(500);
  const [exporting, setExporting] = React.useState(false);
  const [selected, setSelected] = React.useState(() => new Set());
  const [showBulkAssign, setShowBulkAssign] = React.useState(false);
  const [bulkBusy, setBulkBusy] = React.useState(false);
  const [bulkProgress, setBulkProgress] = React.useState(null); // { done, total }
  const [toast, setToast] = React.useState(null);
  const toastTimerRef = React.useRef(0);
  const showToast = (msg, ms = 2500) => {
    setToast(msg);
    if (toastTimerRef.current) clearTimeout(toastTimerRef.current);
    toastTimerRef.current = window.setTimeout(() => setToast(null), ms);
  };

  // Server-side search: when tasksApi is online, the Queue fetches filtered
  // rows from /api/tasks with a 250ms debounce on q. Results live in
  // `serverItems` and `serverCursor`; when offline we fall back to filtering
  // the in-memory `tasks` prop (prior behavior). A cheap "online" flag drives
  // which branch renders.
  const [apiOnline, setApiOnline] = React.useState(
    () => !!(window.tasksApi && window.tasksApi.OFFLINE === false),
  );
  React.useEffect(() => {
    const onOffline = () => setApiOnline(false);
    window.addEventListener("caa-tasks-api-offline", onOffline);
    return () => window.removeEventListener("caa-tasks-api-offline", onOffline);
  }, []);
  const [serverItems, setServerItems] = React.useState(null); // null = haven't fetched yet
  const [serverCursor, setServerCursor] = React.useState(null);
  const [serverTotal, setServerTotal] = React.useState(null);
  const [serverLoading, setServerLoading] = React.useState(false);

  // Sidebar items (Mine / cohort list) dispatch a "caa-queue-prefilter" event
  // before routing here. Apply on first mount (in case we're navigating in)
  // and on every subsequent event (in case user is already on queue).
  React.useEffect(() => {
    const apply = (pf) => {
      if (pf === null || pf === undefined) { setFilter("all"); setQ(""); return; }
      if (pf.status) { setFilter(pf.status); setQ(""); }
      else if (pf.domain) { setFilter("all"); setQ(pf.domain); }
    };
    apply(window.__caaQueuePrefilter);
    window.__caaQueuePrefilter = undefined;
    const onEvent = (e) => apply(e.detail);
    window.addEventListener("caa-queue-prefilter", onEvent);
    return () => window.removeEventListener("caa-queue-prefilter", onEvent);
  }, []);
  // Reset pagination whenever filters change.
  React.useEffect(() => { setVisible(500); }, [filter, q]);
  // Filter change means the id set on screen changes — drop any stale selection.
  React.useEffect(() => { setSelected(new Set()); }, [filter, q]);

  // Debounced server fetch. Runs whenever filters change and the api is online.
  React.useEffect(() => {
    if (!apiOnline) { setServerItems(null); return; }
    let cancelled = false;
    const handle = setTimeout(async () => {
      setServerLoading(true);
      try {
        const res = await window.tasksApi.list({
          status: filter === "all" ? undefined : filter,
          q: q || undefined,
          limit: 500,
        });
        if (cancelled) return;
        const items = Array.isArray(res && res.items) ? res.items : [];
        setServerItems(items);
        setServerCursor(res && res.next_cursor ? res.next_cursor : null);
        setServerTotal(res && typeof res.total === "number" ? res.total : null);
        // Bubble loaded rows up to App so Editor/Simulator can find them by id.
        if (onTasksLoaded) onTasksLoaded(items);
      } catch (err) {
        if (cancelled) return;
        if (!(err && err.offline)) console.warn("tasksApi.list failed:", err && err.message || err);
        setServerItems(null); // let caller fall back
      } finally {
        if (!cancelled) setServerLoading(false);
      }
    }, 250);
    return () => { cancelled = true; clearTimeout(handle); };
  }, [apiOnline, filter, q, onTasksLoaded]);

  const loadMoreFromServer = React.useCallback(async () => {
    if (!apiOnline || !serverCursor) return;
    setServerLoading(true);
    try {
      const res = await window.tasksApi.list({
        status: filter === "all" ? undefined : filter,
        q: q || undefined,
        limit: 500,
        cursor: serverCursor,
      });
      const items = (res && res.items) || [];
      setServerItems(prev => [...(prev || []), ...items]);
      setServerCursor(res && res.next_cursor ? res.next_cursor : null);
      if (onTasksLoaded) onTasksLoaded(items);
    } catch (err) {
      if (!(err && err.offline)) console.warn("tasksApi.list (next page) failed:", err && err.message || err);
    } finally {
      setServerLoading(false);
    }
  }, [apiOnline, serverCursor, filter, q, onTasksLoaded]);

  const localList = tasks || window.TASKS || [];
  const useServer = apiOnline && serverItems !== null;
  const list = useServer ? serverItems : localList;
  const filtered = useServer ? list : list.filter(t => {
    if (filter !== "all" && t.status !== filter) return false;
    if (q && !(t.id+" "+t.chief+" "+t.diagnosis+" "+t.domain).toLowerCase().includes(q.toLowerCase())) return false;
    return true;
  });
  const active = localList.find(t => t.id === activeId)
    || filtered.find(t => t.id === activeId)
    || filtered[0];

  // ---- selection + bulk assign ---------------------------------------------
  const visibleList = filtered.slice(0, visible);
  const visibleIds = visibleList.map(tk => tk.id);
  const allVisibleSelected = visibleIds.length > 0 && visibleIds.every(id => selected.has(id));
  const someVisibleSelected = visibleIds.some(id => selected.has(id));
  const toggleSelect = (id) => {
    setSelected(prev => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id);
      else next.add(id);
      return next;
    });
  };
  const toggleSelectAllVisible = () => {
    setSelected(prev => {
      const next = new Set(prev);
      if (allVisibleSelected) visibleIds.forEach(id => next.delete(id));
      else visibleIds.forEach(id => next.add(id));
      return next;
    });
  };

  const reloadServer = React.useCallback(async () => {
    if (!apiOnline) return;
    try {
      const res = await window.tasksApi.list({
        status: filter === "all" ? undefined : filter,
        q: q || undefined,
        limit: 500,
      });
      const items = Array.isArray(res && res.items) ? res.items : [];
      setServerItems(items);
      setServerCursor(res && res.next_cursor ? res.next_cursor : null);
      setServerTotal(res && typeof res.total === "number" ? res.total : null);
      if (onTasksLoaded) onTasksLoaded(items);
    } catch (err) {
      if (!(err && err.offline)) console.warn("tasksApi.list (reload) failed:", err && err.message || err);
    }
  }, [apiOnline, filter, q, onTasksLoaded]);

  const doBulkAssign = async (email) => {
    if (bulkBusy) return;
    const ids = Array.from(selected);
    if (ids.length === 0) return;
    setBulkBusy(true);
    setBulkProgress(null);
    const cap = window.ASSIGN_CAP || 50000;
    try {
      let n = 0;
      if (ids.length <= cap) {
        const res = await window.tasksApi.assignBulk({ task_ids: ids, email });
        n = (res && res.updated) || 0;
      } else if (window.assignIdsChunked) {
        // Selection exceeds server cap — chunk via shared helper.
        const res = await window.assignIdsChunked({
          ids,
          strategy: "assign_all",
          email,
          onProgress: (p) => setBulkProgress({ done: p.done || 0, total: p.total || 0 }),
        });
        n = (res && res.updated) || 0;
      } else {
        throw new Error(`selection exceeds cap (${cap}) and chunking helper unavailable`);
      }
      showToast(email ? `Assigned ${n} task${n === 1 ? "" : "s"} to ${email}` : `Unassigned ${n} task${n === 1 ? "" : "s"}`);
      setSelected(new Set());
      setShowBulkAssign(false);
      if (window.tasksApi.invalidateStats) window.tasksApi.invalidateStats();
      await reloadServer();
    } catch (e) {
      const missing = e && e.body && e.body.missing;
      showToast(`Assign failed: ${(e && e.body && e.body.error) || e?.message || e}${missing && missing.length ? ` (${missing.join(", ")})` : ""}`);
    } finally {
      setBulkBusy(false);
      setBulkProgress(null);
    }
  };

  return (
    <div className="queue">
      <div className="queue-left">
        <div className="queue-header">
          <div style={{display:"flex", alignItems:"center", gap:8}}>
            <h2 style={{flex:1}}>{t("queue_title")}</h2>
            {isManager && onNewTask && (
              <button className="btn primary" style={{padding:"4px 9px", fontSize:11.5}} onClick={onNewTask} title={t("q_new_task_hint") || "Create a new empty task"}>
                {Ico.plus()} {t("q_new_task")}
              </button>
            )}
            {isManager && (
            <button
              className="btn"
              style={{padding:"4px 9px", fontSize:11.5}}
              title={t("export_approved_hint")}
              disabled={exporting || !list.some(x=>x.status==='approved')}
              onClick={async ()=>{
                const approved = list.filter(x=>x.status==='approved');
                if (!approved.length) return;
                setExporting(true);
                try {
                  const approvedIds = new Set(approved.map(x => x.id));
                  const byId = {};
                  // 1) Seed from localStorage, grouped by task_id.
                  try {
                    const local = JSON.parse(localStorage.getItem("caa_submitted_trajectories") || "[]");
                    if (Array.isArray(local)) {
                      for (const tr of local) {
                        if (tr && approvedIds.has(tr.task_id)) {
                          (byId[tr.task_id] = byId[tr.task_id] || []).push(tr);
                        }
                      }
                    }
                  } catch {}
                  // 2) Merge server records (server wins by id).
                  let serverAvailable = true;
                  for (const tk of approved) {
                    if (!serverAvailable) break;
                    let summaries = null;
                    try {
                      const res = await fetch(`/api/trajectories?task_id=${encodeURIComponent(tk.id)}&limit=500`);
                      const ct = res.headers.get("content-type") || "";
                      if (!res.ok || !ct.includes("application/json")) { serverAvailable = false; break; }
                      const data = await res.json();
                      summaries = Array.isArray(data.items) ? data.items : [];
                    } catch { serverAvailable = false; break; }
                    const fulls = [];
                    for (const s of summaries) {
                      if (!s || !s.id) continue;
                      try {
                        const r = await fetch(`/api/trajectories/${s.id}`);
                        const ct = r.headers.get("content-type") || "";
                        if (!r.ok || !ct.includes("application/json")) { serverAvailable = false; break; }
                        fulls.push(await r.json());
                      } catch { serverAvailable = false; break; }
                    }
                    if (!serverAvailable) break;
                    const merged = new Map();
                    for (const tr of (byId[tk.id] || [])) if (tr && tr.id) merged.set(tr.id, tr);
                    for (const tr of fulls) if (tr && tr.id) merged.set(tr.id, tr); // server wins
                    const arr = Array.from(merged.values());
                    if (arr.length) byId[tk.id] = arr;
                  }
                  if (!serverAvailable) {
                    const ok = confirm("Server unavailable — export will include only locally cached trajectories. Continue?");
                    if (!ok) return;
                  }
                  const stamp = new Date().toISOString().slice(0,10);
                  exportTasksJson(approved, `tau2_clinical_approved_${stamp}.json`, byId);
                } finally {
                  setExporting(false);
                }
              }}
            >
              {Ico.download ? Ico.download() : "⤓"} {exporting ? "Exporting…" : t("export_approved")}
            </button>
            )}
          </div>
          <div className="queue-stats">
            {/* Prefer D1-backed counts (true totals). Fall back to the */}
            {/* in-memory list when the stats endpoint hasn't responded yet. */}
            <span><b>{(taskStats && taskStats.by_status && taskStats.by_status['needs-review']) ?? localList.filter(t=>t.status==='needs-review').length}</b> {t("filter_needs_review").toLowerCase()}</span>
            <span className="sep">·</span>
            <span><b>{(taskStats && taskStats.by_status && taskStats.by_status['in-progress']) ?? localList.filter(t=>t.status==='in-progress').length}</b> {t("filter_in_progress").toLowerCase()}</span>
            <span className="sep">·</span>
            <span><b>{(taskStats && taskStats.by_status && taskStats.by_status['approved']) ?? localList.filter(t=>t.status==='approved').length}</b> {t("filter_approved").toLowerCase()}</span>
          </div>
          <div className="search">
            {Ico.search()}
            <input placeholder={t("queue_search_ph")} value={q} onChange={e=>setQ(e.target.value)} />
            <span className="chip-kbd">/</span>
          </div>
          <div className="filter-row">
            {[["all","filter_all"],["needs-review","filter_needs_review"],["in-progress","filter_in_progress"],["approved","filter_approved"],["rejected","filter_rejected"]].map(([k,lk])=> (
              <button key={k} className="filter-pill" data-active={filter===k} onClick={()=>setFilter(k)}>{t(lk)}</button>
            ))}
          </div>
          {isManager && (
            <div className="queue-select-head" style={{display:"flex", alignItems:"center", gap:8, padding:"6px 14px", borderTop:"1px solid var(--line)", fontSize:11.5, color:"var(--ink-mute)", fontFamily:"var(--font-mono)"}}>
              <input
                type="checkbox"
                data-bulk-checkbox
                aria-label="select all visible"
                checked={allVisibleSelected}
                ref={el => { if (el) el.indeterminate = !allVisibleSelected && someVisibleSelected; }}
                onChange={toggleSelectAllVisible}
                onClick={e=>e.stopPropagation()}
              />
              <span>Select all visible ({visibleIds.length.toLocaleString()})</span>
            </div>
          )}
          {isManager && selected.size > 0 && (() => {
            const cap = window.ASSIGN_CAP || 50000;
            const chunkSize = window.ASSIGN_CHUNK_SIZE || 5000;
            const willChunk = selected.size > cap;
            const batchCount = willChunk ? Math.ceil(selected.size / chunkSize) : 1;
            const assignLabel = bulkBusy
              ? (bulkProgress && bulkProgress.total
                  ? `Assigning (${bulkProgress.done}/${bulkProgress.total})…`
                  : "Assigning…")
              : "Assign ▾";
            return (
              <div className="queue-bulk-bar">
                <span><b>{selected.size.toLocaleString()}</b> selected</span>
                <span className="sep" style={{color:"var(--line-strong)"}}>·</span>
                <span style={{position:"relative", display:"inline-block"}}>
                  <button
                    className="btn primary"
                    style={{padding:"3px 10px", fontSize:11.5}}
                    disabled={bulkBusy}
                    onClick={()=>setShowBulkAssign(v => !v)}
                  >{assignLabel}</button>
                  {showBulkAssign && (
                    <AssignDropdown
                      onPick={doBulkAssign}
                      onClose={()=>setShowBulkAssign(false)}
                      allowClear={true}
                    />
                  )}
                </span>
                <button
                  className="btn ghost"
                  style={{padding:"3px 10px", fontSize:11.5}}
                  onClick={()=>{ setSelected(new Set()); setShowBulkAssign(false); }}
                  disabled={bulkBusy}
                >Clear selection</button>
                {willChunk && (
                  <span style={{color:"var(--ink-mute)", fontSize:11.5, marginLeft:4}}>
                    exceeds cap ({cap.toLocaleString()}) — will submit in {batchCount} batches of {chunkSize.toLocaleString()}
                  </span>
                )}
              </div>
            );
          })()}
        </div>
        <div className="queue-list">
          {visibleList.map(tk => (
            <div
              key={tk.id}
              className="queue-row"
              data-active={active && active.id===tk.id}
              style={isManager ? {gridTemplateColumns:"18px 14px 1fr auto"} : undefined}
              onClick={(e)=>{
                if (e.target.closest && e.target.closest("[data-bulk-checkbox]")) return;
                setActive(tk.id);
              }}
            >
              {isManager && (
                <input
                  type="checkbox"
                  data-bulk-checkbox
                  aria-label={`select ${tk.id}`}
                  checked={selected.has(tk.id)}
                  onChange={()=>toggleSelect(tk.id)}
                  onClick={e=>e.stopPropagation()}
                  style={{margin:0, marginTop:2}}
                />
              )}
              <div className="queue-row-dot" data-status={tk.status}/>
              <div className="queue-row-main">
                <div className="queue-row-title">{tk.chief} <span style={{color:"var(--ink-mute)"}}>· {tk.diagnosis}</span></div>
                <div className="queue-row-meta">
                  <span>{tk.id}</span><span className="sep">/</span>
                  <span>{tk.domain}</span><span className="sep">/</span>
                  <span>{tk.age}{(tk.gender||"u")[0].toUpperCase()}</span><span className="sep">/</span>
                  <span>{tk.severity}</span>
                  {isManager && tk.assigneeEmail && (
                    <><span className="sep">/</span><span style={{color:"var(--ink-mute)"}} title={tk.assigneeEmail}>
                      {tk.assigneeEmail.length > 22 ? tk.assigneeEmail.slice(0, 20) + "…" : tk.assigneeEmail}
                    </span></>
                  )}
                  {tk.issues && tk.issues.length>0 && <><span className="sep">/</span><span style={{color:"var(--amber)"}}>⚑ {tk.issues.length}</span></>}
                </div>
              </div>
              <div className="queue-row-right">
                <div className="quality-bar"><span style={{width: (tk.quality*100)+"%"}}/></div>
                <span style={{fontSize:10.5, fontFamily:"var(--font-mono)", color:"var(--ink-mute)"}}>{tk.lastEdited}</span>
              </div>
            </div>
          ))}
          {(filtered.length > visible || (useServer && serverCursor)) && (
            <div style={{padding:"12px 14px", fontSize:11.5, color:"var(--ink-mute)", fontFamily:"var(--font-mono)", borderTop:"1px dashed var(--line)", display:"flex", alignItems:"center", gap:10}}>
              <span>
                showing {Math.min(visible, filtered.length).toLocaleString()} of {filtered.length.toLocaleString()}
                {useServer && typeof serverTotal === "number" && serverTotal > filtered.length
                  ? ` (${serverTotal.toLocaleString()} total)` : ""}
              </span>
              <button className="btn ghost" style={{padding:"2px 10px", fontSize:11}}
                disabled={serverLoading}
                onClick={async () => {
                  if (useServer && visible >= filtered.length && serverCursor) {
                    await loadMoreFromServer();
                  }
                  setVisible(v => v + 500);
                }}>
                {serverLoading ? "loading…" : "load 500 more"}
              </button>
              {!useServer && (
                <button className="btn ghost" style={{padding:"2px 10px", fontSize:11}}
                  onClick={() => setVisible(filtered.length)}
                  title="Warning: rendering thousands of rows may slow the browser">
                  load all ({filtered.length.toLocaleString()})
                </button>
              )}
            </div>
          )}
        </div>
      </div>

      <div className="queue-right">
        {active && <QueueDetail t={active} openEditor={openEditor} />}
      </div>
      {toast && (
        <div style={{position:"fixed", bottom:20, right:20, background:"var(--ink)", color:"var(--bg)", padding:"10px 14px", fontSize:12, borderRadius:4, zIndex:100, fontFamily:"var(--font-mono)"}}>
          {toast}
        </div>
      )}
    </div>
  );
}

function QueueDetail({ t, openEditor }) {
  const { t: tr } = useLang();
  return (
    <>
      <div className="qr-head">
        <div>
          <div style={{display:"flex", alignItems:"center", gap:8, marginBottom:4}}>
            <span className="tag">{t.domain}</span>
            <span className={"tag "+ (t.status==='approved'?'green':t.status==='in-progress'?'accent':t.status==='rejected'?'red':'amber')}>
              {t.status}
            </span>
            {t.issues && t.issues.length>0 && <span className="tag amber">⚑ {t.issues.length} {t.issues.length>1?tr("qd_issue_count_many"):tr("qd_issue_count_one")}</span>}
          </div>
          <h1>{t.chief}</h1>
          <div className="qr-id">{t.id} · {tr("qd_path_len")} {t.pathLen} · {tr("qd_generated_on")}</div>
        </div>
        <div className="qr-actions">
          <button className="btn ghost">{Ico.reset()} {tr("qr_reset")}</button>
          <button className="btn" onClick={()=>openEditor("simulate")}>{Ico.play()} {tr("qr_simulate")}</button>
          <button className="btn primary" onClick={()=>openEditor("editor")}>{Ico.edit()} {tr("qr_open_editor")} <span className="kbd">E</span></button>
        </div>
      </div>

      <div style={{display:"grid", gridTemplateColumns:"1.3fr 1fr", gap:24}}>
        <div>
          <div className="section">
            <div className="section-head"><h3>{tr("qd_h_gen_summary")}</h3><span className="section-hint">{tr("qd_h_gen_source")}</span></div>
            <div className="section-body">
              <p style={{margin:"0 0 10px", fontFamily:"var(--font-serif)", fontSize:18, lineHeight:1.35, color:"var(--ink)"}}>
                {tr("qd_summary_line").replace("{age}", t.age).replace("{gender}", t.gender)}<b>{t.chief.toLowerCase()}</b>{tr("qd_summary_for")}{t.duration}{tr("qd_summary_sev")}<i>{t.diagnosis}</i>。
              </p>
              <p style={{margin:0, color:"var(--ink-dim)", fontSize:12.5}}>
                {tr("qd_path_info")}{t.pathLen>2?tr("qd_path_drug"):""}{tr("qd_info_partial")}{t.minTurns}–{t.maxTurns}。
              </p>
            </div>
          </div>

          {t.issues && t.issues.length>0 && (
            <div className="section">
              <div className="section-head"><h3>{tr("qd_h_findings")}</h3><span className="section-hint">{tr("qd_findings_hint")}</span></div>
              <div className="section-body" style={{padding:0}}>
                {t.issues.map((iss,i)=>(
                  <div key={i} style={{display:"grid", gridTemplateColumns:"18px 220px 1fr", gap:10, padding:"10px 14px", borderBottom: i<t.issues.length-1?"1px solid var(--line)":"none", alignItems:"start"}}>
                    <span style={{color: iss.kind==='err'?'var(--red)':'var(--amber)', marginTop:2}}>{iss.kind==='err'?Ico.x():Ico.warn()}</span>
                    <code style={{fontFamily:"var(--font-mono)", fontSize:11.5, color:"var(--ink-dim)"}}>{iss.field}</code>
                    <span style={{fontSize:12.5}}>{iss.msg}</span>
                  </div>
                ))}
              </div>
            </div>
          )}

          <div className="section">
            <div className="section-head"><h3>{tr("qd_h_ref_dialogue")}</h3><span className="section-hint">{tr("qd_ref_hint")}</span></div>
            <div className="section-body">
              {(t.refDialogue && t.refDialogue.length>0) ? t.refDialogue.map((m,i)=>(
                <div key={i} style={{display:"grid", gridTemplateColumns:"80px 1fr", gap:10, padding:"6px 0", borderBottom:"1px dashed var(--line)"}}>
                  <span style={{fontFamily:"var(--font-mono)", fontSize:11, color: m.role==='assistant'?'var(--accent-ink)':'var(--ink-mute)'}}>{m.role}</span>
                  <span style={{fontSize:13}}>{m.text}</span>
                </div>
              )) : <div style={{color:"var(--ink-mute)", fontSize:12}}>{tr("qd_ref_empty")}</div>}
            </div>
          </div>
        </div>

        <div>
          <div className="section">
            <div className="section-head"><h3>{tr("qd_h_patient")}</h3></div>
            <div className="section-body" style={{fontSize:12.5}}>
              <div style={{display:"grid", gridTemplateColumns:"100px 1fr", rowGap:6}}>
                <span style={{color:"var(--ink-dim)"}}>{tr("qd_name")}</span><span>Patient_{t.id.slice(-4)}</span>
                <span style={{color:"var(--ink-dim)"}}>{tr("qd_mrn")}</span><span style={{fontFamily:"var(--font-mono)"}}>MRN{t.id.slice(-6)}</span>
                <span style={{color:"var(--ink-dim)"}}>{tr("qd_age_sex")}</span><span>{t.age} · {t.gender}</span>
                <span style={{color:"var(--ink-dim)"}}>{tr("qd_chief")}</span><span>{t.chief}</span>
                <span style={{color:"var(--ink-dim)"}}>{tr("qd_duration")}</span><span>{t.duration}</span>
                <span style={{color:"var(--ink-dim)"}}>{tr("qd_severity")}</span><span>{t.severity}</span>
                <span style={{color:"var(--ink-dim)"}}>{tr("qd_allergies")}</span><span style={{color:"var(--ink-mute)"}}>{tr("qd_none_rec")}</span>
                <span style={{color:"var(--ink-dim)"}}>{tr("qd_meds")}</span><span style={{color:"var(--ink-mute)"}}>{tr("qd_none_rec")}</span>
              </div>
            </div>
          </div>

          <div className="section">
            <div className="section-head"><h3>{tr("qd_h_lifecycle")}</h3></div>
            <div className="section-body" style={{fontSize:12.5}}>
              <div style={{display:"grid", gridTemplateColumns:"100px 1fr", rowGap:6}}>
                <span style={{color:"var(--ink-dim)"}}>{tr("qd_status")}</span><span>{t.status}</span>
                <span style={{color:"var(--ink-dim)"}}>{tr("qd_annotator")}</span><span>{t.annotator || tr("qd_unassigned")}</span>
                <span style={{color:"var(--ink-dim)"}}>{tr("qd_edits")}</span><span style={{fontFamily:"var(--font-mono)"}}>{t.edits}</span>
                <span style={{color:"var(--ink-dim)"}}>{tr("qd_last_edit")}</span><span>{t.lastEditor} · {t.lastEdited}</span>
                <span style={{color:"var(--ink-dim)"}}>{tr("qd_sim_runs")}</span><span style={{fontFamily:"var(--font-mono)"}}>{t.simRuns}</span>
                <span style={{color:"var(--ink-dim)"}}>{tr("qd_quality")}</span><span style={{fontFamily:"var(--font-mono)"}}>{(t.quality*5).toFixed(2)} / 5.00</span>
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

window.Queue = Queue;