// monitor.js
// Scope: display and active state — what is seen, what is happening.
// Requires mgrSNP.js loaded first (window.SNP).
// Input surfaces: chat input field + transport buttons only.
// Everything else is poll → receive → display.

// ── ACTION PRIMITIVES (2-4 Letter Ecosystem Grammar) ──────────────────────────

const ACT = {
  // 2 Letters
  go:   'navigate',
  ld:   'load',

  // 3 Letters
  inj:  'inject',
  cpy:  'copy',
  run:  'run',
  syn:  'sync',
  chk:  'check',
  cls:  'clear',
  opn:  'open',

  // 4 Letters
  upd:  'update',
  remv: 'remove',
  exec: 'execute',
  appr: 'approve'
};

// ── CONFIG ────────────────────────────────────────────────────────────────────

let DECK_URL = DeckConnection.getURL();

// ── ACTIVE STATE (5 system booleans) ─────────────────────────────────────────
// These drive the LED indicators and monitor message display.

let recorderRunning    = false;  // RECORD solid — active recording/execution
let deckOnline          = false;  // DEAD meter until the deck status route responds
let aiEngaged          = false;  // RECORD flashing — local AI thinking
let yesItemsReady      = false;  // PLAY solid — approved YES queue ready
let proposalsAwaiting  = false;  // reviewable proposals exist, not queue
let recentChatManifest = null;   // PLAY flashing — new review item window
let recentChatTimer    = null;
let recentChatBlink    = null;
let runnableDubFlashUntil = 0;    // PLAY flashing — recent runnable item arrived
let runnableDubBlink      = null;
let lastRunnableDubKey    = '';
let recordActivityFlashUntil = 0;
let recordActivityBlink      = null;

// ── UI STATE ──────────────────────────────────────────────────────────────────

let pollTimer              = null;
let pollBusy               = false;
let pollCycle              = 0;
let logLines               = [];
let systemLogSeeded        = false;
let lastSidebarLine        = '';
let lastSidebarActivityAt  = Date.now();
let systemLogGroupCounter  = 0;
let currentSidebarGroup    = 'system-group-0';
let dubFilters             = new Set(['error', 'diagnostic', 'enhancement', 'run']);
let latestDubTape          = [];
let latestDubViewItems     = [];
let expandedDubKey         = null;
let selectedDubIndex       = -1;
let selectedDubManifest    = null;
let selectedDubKind        = 'diagnostic';
let selectedDubSource      = 'monitor';
let selectedTapeIndex      = -1;
let selectedSystemGroupIdx = -1;
let selectedProjectUnitIndex = -1;
let currentSidebarGroupTime = 0;
let sidebarRunMeta = new Map();
const ACTIVITY_CLUSTER_MS = 3 * 60 * 1000;
let connectedPortRevealTimer = null;
const HISTORY_WINDOW_STEPS = [
  { label: '48 hours', ms: 48 * 60 * 60 * 1000 },
  { label: '1 week', ms: 7 * 24 * 60 * 60 * 1000 },
  { label: '2 weeks', ms: 14 * 24 * 60 * 60 * 1000 }
];
let historyWindowStep = 0;
let historyExtraMonths = 0;
let historyStreamSignatures = new Map();
let historyArchiveDepths = new Map();
let historyClickCheckTimer = null;

let agreementGateActive = false;
let agreementPolicyVersion = 'beta-agreement-v1';
let projectSettings = [];
let pendingActivationId = '';
let pendingActivationUrl = '';
let activationPollTimer = null;
const ACCOUNT_PORTAL_URL = 'https://nodarama.com/account/';

function openAccountPortalWindow() {
  const url = `${ACCOUNT_PORTAL_URL}?source=verbatim`;
  const features = 'popup=yes,width=980,height=760,resizable=yes,scrollbars=yes,noopener,noreferrer';
  const win = window.open(url, 'nodarama-account', features);
  if (win) {
    win.focus?.();
    return;
  }
  window.open(url, '_blank', 'noopener,noreferrer');
}

async function refreshAccountFromPortal() {
  const auth = await syncAccount();
  const signedIn = verifyAuth(auth);
  const accepted = Boolean(byId('agreement-accept-check')?.checked);
  if (accepted && signedIn) {
    await saveAgreement({ user: auth, tier: auth?.tier }, auth?.email || '');
    toggleGate(false);
    toast('Account status refreshed');
    if (window.LaunchState && typeof renderLaunchState === 'function') {
      LaunchState.auth = auth;
      LaunchState.settings = await SettingsStore.load();
      LaunchState.backstage = typeof isBackstageAuth === 'function' ? isBackstageAuth(auth) : false;
      LaunchState.projects = typeof fetchLaunchProjects === 'function' ? await fetchLaunchProjects() : LaunchState.projects;
      await renderLaunchState();
    }
    return auth;
  }
  toast(signedIn ? 'Check agreement acceptance.' : 'Still signed out.');
  return auth;
}

function initAccountPortalUI() {
  on('account-open-portal-btn', 'click', openAccountPortalWindow);
  on('account-refresh-btn', 'click', () => { void syncAccount(); });
  on('agreement-open-account-btn', 'click', openAccountPortalWindow);
  on('agreement-refresh-status-btn', 'click', () => { void refreshAccountFromPortal(); });
}

// ── HELPERS ───────────────────────────────────────────────────────────────────

function byId(id) { return document.getElementById(id); }

function on(id, event, fn) {
  const el = byId(id);
  if (el) el.addEventListener(event, fn);
}

function toast(msg, dur = 2500) {
  const el = byId('toast');
  if (!el) return;
  el.textContent = msg;
  el.classList.add('show');
  clearTimeout(el._t);
  el._t = setTimeout(() => el.classList.remove('show'), dur);
}

function esc(s) {
  return String(s ?? '')
    .replace(/&/g, '&amp;').replace(/</g, '&lt;')
    .replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}

function downloadText(text, filename) {
  const a = Object.assign(document.createElement('a'), {
    href: URL.createObjectURL(new Blob([text], { type: 'text/plain' })),
    download: filename
  });
  a.click();
  URL.revokeObjectURL(a.href);
}

function safeTriggerEQActivity(level) {
  try {
    if (typeof triggerEQActivity === 'function') triggerEQActivity(level);
  } catch {}
}

async function api(path, method = 'GET', body = null) {
  const verb = String(method || 'GET').toUpperCase();
  const route = String(path || '');
  const isPollingRead = verb === 'GET' && /^(\/status|\/logs\/|\/dubs\/playback|\/playback|\/projects|\/auth\/status|\/policy\/combined)/.test(route);
  const isExplicitFileRead = /^\/read\//.test(route);

  if (/^\/record/.test(route)) safeTriggerEQActivity(ACT.run);
  else if (/^\/eq\/chat/.test(route)) safeTriggerEQActivity('chat');
  else if (/^\/playback\/approve/.test(route)) safeTriggerEQActivity(ACT.appr);
  else if (isExplicitFileRead) safeTriggerEQActivity('readfile');
  else if (verb !== 'GET' && !isPollingRead) safeTriggerEQActivity('medium');

  try {
    const opts = { method, headers: {} };
    if (body !== null) {
      opts.headers['Content-Type'] = 'application/json';
      opts.body = JSON.stringify(body);
    }
    const res = await fetch(DECK_URL + path, opts);
    return await res.json();
  } catch (e) {
    return { ok: false, error: e.message };
  }
}

function formatAuthFailure(result, fallback = 'Auth failed') {
  const connected = result?.connected === true ? 'connected' : result?.connected === false ? 'not connected' : '';
  const status = result?.remoteStatus || result?.status || '';
  const type = String(result?.failureType || '').replace(/_/g, ' ');
  const detail = result?.message || result?.error || fallback;
  return [detail, type, status ? String(status) : '', connected].filter(Boolean).join(' · ');
}

function resolveDefaultTabFromAuth(auth) {
  const hasUser = Boolean(auth?.userId || auth?.email);
  const isSignedIn = auth?.status === "signed_in" || (hasUser && auth?.tier && auth.tier !== "limited");

  return isSignedIn ? "project" : "settings";
}



function activateTabNow(tabName) {
  document.querySelectorAll('#tabs [data-tab]').forEach(btn => {
    btn.classList.toggle('active', btn.dataset.tab === tabName);
  });

  document.querySelectorAll('.Panel.Dx').forEach(panel => {
    panel.classList.toggle('active', panel.id === `panel-${tabName}`);
  });

  if (tabName === 'editor' && typeof window.__bootEditor === 'function') {
    window.__bootEditor();
    window.__bootEditor = null;
  }

  if (tabName === 'dubs') readDubs();
  if (tabName === 'history') readTape();
  if (tabName === 'settings' && typeof refreshSettingsProjectsList === 'function') {
    void refreshSettingsProjectsList();
  }
}

async function activateTab(tabName) {
  const currentTab = document.querySelector('#tabs [data-tab].active')?.dataset.tab || '';

  if (currentTab === 'editor' && tabName !== 'editor' && typeof window.__editorBeforeExit === 'function') {
    const allowed = await window.__editorBeforeExit();
    if (!allowed) return false;
  }

  activateTabNow(tabName);
  return true;
}

function openAccountPortalWindow() {
  const url = `${ACCOUNT_PORTAL_URL}?source=verbatim`;
  const features = 'popup=yes,width=980,height=760,resizable=yes,scrollbars=yes,noopener,noreferrer';
  const win = window.open(url, 'nodarama-account', features);

  if (win) {
    win.focus?.();
    return true;
  }

  window.open(url, '_blank', 'noopener,noreferrer');
  return true;
}

async function refreshAfterAccountPortal() {
  const auth = await syncAccount();
  if (window.LaunchState) LaunchState.auth = auth;
  return auth;
}

function viewAccount(auth) {
  const statusEl = byId('account-status');
  const tierEl = byId('account-tier');
  const emailEl = byId('set-auth-email');
  const passwordEl = byId('set-auth-password');

  const signedIn = verifyAuth(auth);
  const tier = auth?.tier || 'limited';
  const email = auth?.email || '';

  if (statusEl) statusEl.textContent = signedIn ? 'Signed in' : 'Signed out';
  if (tierEl) tierEl.textContent = tier;

  if (emailEl) {
    if ('value' in emailEl) {
      if (!emailEl.value) emailEl.value = email;
    } else {
      emailEl.textContent = email || '—';
    }
  }

  if (signedIn && passwordEl && 'value' in passwordEl) passwordEl.value = '';
}

function toggleGate(visible) {
  agreementGateActive = Boolean(visible);
  const modal = byId('agreement-gate-modal');
  if (modal) modal.style.display = visible ? 'flex' : 'none';

  if (!window.__agreementEscBound) {
    window.__agreementEscBound = 'YES';
    document.addEventListener('keydown', event => {
      if (event.key !== 'Escape') return;
      const activeModal = byId('agreement-gate-modal');
      if (activeModal && activeModal.style.display !== 'none') toggleGate(false);
      try { window.__accountPortalWindow?.close?.(); } catch {}
    });
  }
}
function verifyAuth(auth) {
  return Boolean(auth?.status === 'signed_in' || auth?.userId || auth?.email);
}

function agreementAccepted(settings) {
  return Boolean(settings?.agreement?.accepted && settings?.agreement?.acceptedAt);
}

function prepareAgreementScreen() {
  const check = byId('agreement-accept-check');
  const agree = byId('agreement-agree-btn')
    || byId('agreement-accept-btn')
    || byId('agreement-ok-btn');

  if (agree) agree.disabled = !Boolean(check?.checked);

  if (check && !check.dataset.boundAgreement) {
    check.dataset.boundAgreement = 'YES';
    check.addEventListener('change', () => {
      const currentAgree = byId('agreement-agree-btn')
        || byId('agreement-accept-btn')
        || byId('agreement-ok-btn');

      if (currentAgree) currentAgree.disabled = !check.checked;
    });
  }

  if (agree && !agree.dataset.boundAgreement) {
    agree.dataset.boundAgreement = 'YES';
    agree.addEventListener('click', () => void acceptAgreementOnly());
  }
}

async function enforceGate(settings, auth) {
  const accepted = Boolean(settings?.agreement?.accepted && settings?.agreement?.acceptedAt);
  if (accepted) {
    toggleGate(false);
    return false;
  }

  const check = byId('agreement-accept-check');
  const agree = byId('agreement-agree-btn') || byId('agreement-accept-btn') || byId('agreement-ok-btn');

  if (agree) agree.disabled = !Boolean(check?.checked);
  if (check && !check.dataset.boundAgreement) {
    check.dataset.boundAgreement = 'YES';
    check.addEventListener('change', () => {
      const button = byId('agreement-agree-btn') || byId('agreement-accept-btn') || byId('agreement-ok-btn');
      if (button) button.disabled = !check.checked;
    });
  }
  if (agree && !agree.dataset.boundAgreement) {
    agree.dataset.boundAgreement = 'YES';
    agree.addEventListener('click', () => void acceptAgreementOnly());
  }

  toggleGate(true);
  return false;
}
async function saveAgreement() {
  await SettingsStore.save({
    agreement: {
      version: agreementPolicyVersion || 'local-agreement-v1',
      acceptedAt: Date.now(),
      accepted: true
    }
  });
}

async function acceptAgreementOnly() {
  const accepted = Boolean(byId('agreement-accept-check')?.checked);

  if (!accepted) {
    toast('Check the agreement box first.');
    return false;
  }

  await saveAgreement();
  toggleGate(false);

  if (window.LaunchState) {
    LaunchState.settings = await SettingsStore.load();
    await renderLaunchState?.();
  }

  toast('Agreement accepted.');
  return true;
}

async function loginGate(createAccount = false) {
  openAccountPortalWindow();
  toast(createAccount ? 'Account page opened.' : 'Sign-in page opened.');
}
async function syncAccount() {
  const status = await api('/auth/status');

  if (status?.ok) {
    const signedIn = Boolean(status.authenticated || status.email);
    const authState = {
      userId: status.userId || '',
      email: status.email || '',
      tier: status.accessTier || status.tier || 'limited',
      status: signedIn ? 'signed_in' : 'signed_out'
    };

    viewAccount(authState);

    await SettingsStore.save({
      authEmail: authState.email,
      authUserId: authState.userId,
      authTier: authState.tier,
      authStatus: authState.status
    });

    return authState;
  }

  const settings = await SettingsStore.load();
  if (!settings) return null;

  const fallback = {
    userId: settings.authUserId,
    email: settings.authEmail,
    tier: settings.authTier,
    status: settings.authStatus
  };

  viewAccount(fallback);
  return fallback;
}

async function refreshAccountPortalStatus() {
  const auth = await syncAccount();

  if (window.LaunchState) {
    LaunchState.auth = auth;
    LaunchState.settings = await SettingsStore.load();
    LaunchState.backstage = typeof isBackstageAuth === 'function' ? isBackstageAuth(auth) : false;
  }

  toast(verifyAuth(auth) ? 'Account status refreshed.' : 'Still signed out.');
  return auth;
}

async function acceptAgreementFromExternalStatus() {
  return await acceptAgreementOnly();
}
function bindStandaloneAccountControls() {
  on('account-open-window-btn', 'click', openAccountPortalWindow);
  on('account-refresh-btn', 'click', () => { void refreshAccountPortalStatus(); });
  on('agreement-open-account-btn', 'click', openAccountPortalWindow);
  on('agreement-refresh-status-btn', 'click', () => { void refreshAccountPortalStatus(); });
  on('agreement-continue-btn', 'click', () => { void acceptAgreementFromExternalStatus(); });
}

function checkRunnable(item) {
  return Boolean(item && item.status === 'proposal' && item.manifest);
}

function parseKey(item) {
  if (!item) return '';
  return `${item.type || ''}:${item.dubID || ''}:${item.action || ''}:${item.filePath || ''}`;
}

// ── REFACTORED TO SHORT DATA SCHEMAS ──────────────────────────────────────────

function checkSelected() {
  const item = latestDubViewItems[selectedDubIndex] || null;
  return Boolean(selectedDubManifest && checkRunnable(item));
}

function checkFlashWindow() {
  return Date.now() < runnableDubFlashUntil;
}

function readSelected() {
  const item = latestDubViewItems[selectedDubIndex] || null;
  return checkRunnable(item) ? item : null;
}

function readLatest() {
  return latestDubViewItems.find(checkRunnable) || compileItems(latestDubTape).find(checkRunnable) || null;
}

function reviewItemLabel(item) {
  return item?.type === 'enhancement' ? 'ENHANCEMENT' : 'DIAGNOSTIC';
}

async function approveItem(item, sourceLabel = 'monitor') {
  if (!item?.manifest) return null;
  const kind = item.type === 'enhancement' ? 'enhancement' : item.type === 'error' ? 'error' : 'diagnostic';
  const data = await api('/playback/approve', 'POST', {
    manifest: item.manifest,
    source: item.source || sourceLabel,
    kind
  });
  if (data?.ok) {
    viewNotice(data);
    appendLog(`▶ ${sourceLabel} manifest ${ACT.appr}d${data.dubID ? ` → dubID:${data.dubID}` : ''}`, 'pass');
    selectedDubManifest = null;
    await readStatus();
    await readDubs();
    await readTape();
  } else {
    viewNotice(data);
    toast('Approve failed: ' + (data?.message || data?.error || 'unknown'));
    appendLog(`✗ approve failed: ${data?.message || data?.error || 'unknown'}`, 'fail');
  }
  return data;
}

async function rejectItem(item, sourceLabel = 'monitor') {
  if (!item?.dubID && !item?.manifest) return null;
  const data = await api('/playback/reject', 'POST', {
    dubID: item.dubID || '',
    manifest: item.manifest || null,
    source: item.source || sourceLabel
  });
  if (data?.ok) {
    appendLog(`⏹ ${sourceLabel} manifest set NO${data.dubID ? ` → dubID:${data.dubID}` : ''}`, 'neutral');
    selectedDubManifest = null;
    await readDubs();
    await readTape();
  } else {
    toast('Reject failed: ' + (data?.message || data?.error || 'unknown'));
    appendLog(`✗ reject failed: ${data?.message || data?.error || 'unknown'}`, 'fail');
  }
  return data;
}

const monitorTickerTape = [];
const MONITOR_TICKER_LIMIT = 8;
const TICKER_SEPARATOR = '          •          ';
let monitorTickerRendered = '';
let monitorTickerPendingRendered = '';
let monitorTickerSwapBound = false;

function applyMonitorTickerRendered(el, rendered) {
  if (!el || !rendered || rendered === monitorTickerRendered) return;
  monitorTickerRendered = rendered;
  monitorTickerPendingRendered = '';
  el.textContent = rendered;
}

function bindMonitorTickerSwap(el) {
  if (!el || monitorTickerSwapBound) return;
  monitorTickerSwapBound = true;
  el.addEventListener('animationiteration', () => {
    if (!monitorTickerPendingRendered || monitorTickerPendingRendered === monitorTickerRendered) return;
    applyMonitorTickerRendered(el, monitorTickerPendingRendered);
  });
}

function setMonitorTicker(text) {
  const el = byId('monitor-message');
  if (!el) return;
  bindMonitorTickerSwap(el);

  const clean = String(text || '').trim();
  if (!clean) return;

  if (monitorTickerTape[monitorTickerTape.length - 1] !== clean) {
    monitorTickerTape.push(clean);
    while (monitorTickerTape.length > MONITOR_TICKER_LIMIT) monitorTickerTape.shift();
  }

  const line = monitorTickerTape.join(TICKER_SEPARATOR);
  const rendered = `${line}${TICKER_SEPARATOR}${line}`;
  if (rendered === monitorTickerRendered || rendered === monitorTickerPendingRendered) return;

  if (!monitorTickerRendered || !String(el.textContent || '').trim()) {
    applyMonitorTickerRendered(el, rendered);
    return;
  }

  monitorTickerPendingRendered = rendered;
}
function syncLeds() {
  const led    = byId('play-led');
  const recLed = byId('deck-status-dot');
  const monMsg = byId('monitor-message');
  const playBtn = byId('play-Eo');
  const recBtn  = byId('record-Eo');

  if (recentChatBlink) {
    clearInterval(recentChatBlink);
    recentChatBlink = null;
  }
  if (runnableDubBlink) {
    clearInterval(runnableDubBlink);
    runnableDubBlink = null;
  }
  if (recordActivityBlink) {
    clearInterval(recordActivityBlink);
    recordActivityBlink = null;
  }
  if (recLed?._blink) {
    clearInterval(recLed._blink);
    recLed._blink = null;
  }

  const selectedRunnable = readSelected();
  const latestRunnable = readLatest();
  const hasNewReviewItem = Boolean(recentChatManifest || checkFlashWindow());
  const hasRecorderActivity = Boolean(aiEngaged || Date.now() < recordActivityFlashUntil);

  if (led) led.classList.remove('active');
  if (recLed) recLed.classList.remove('active');

  if (recorderRunning) {
    if (recLed) recLed.classList.add('active');
    if (monMsg) setMonitorTicker('RECORDING IN PROGRESS');
    if (playBtn) playBtn.title = hasNewReviewItem ? 'PLAY — view newest item' : 'PLAY — review manifests';
    if (recBtn) recBtn.title = 'RECORD — recorder is running';
  } else if (hasRecorderActivity) {
    let on = false;
    recordActivityBlink = setInterval(() => {
      on = !on;
      if (recLed) recLed.classList.toggle('active', on);
      if (!aiEngaged && Date.now() >= recordActivityFlashUntil) {
        clearInterval(recordActivityBlink);
        recordActivityBlink = null;
        syncLeds();
      }
    }, 340);
    if (monMsg) setMonitorTicker(aiEngaged ? 'LOCAL AI THINKING' : 'RECORDER CHECKED');
    if (recBtn) recBtn.title = aiEngaged ? 'RECORD — local AI thinking' : 'RECORD — recently inspected';
  }

  if (hasNewReviewItem) {
    let on = false;
    runnableDubBlink = setInterval(() => {
      on = !on;
      if (led) led.classList.toggle('active', on);
      if (!recentChatManifest && !checkFlashWindow()) {
        clearInterval(runnableDubBlink);
        runnableDubBlink = null;
        syncLeds();
      }
    }, 260);
    if (monMsg && !recorderRunning && !hasRecorderActivity) {
      const newest = latestRunnable || selectedRunnable;
      setMonitorTicker(`NEW ${reviewItemLabel(newest)} RECEIVED — PRESS PLAY TO VIEW`);
    }
    if (playBtn) playBtn.title = 'PLAY — view newest item';
    return;
  }

  if (yesItemsReady) {
    if (led) led.classList.add('active');
    if (monMsg && !recorderRunning && !hasRecorderActivity) setMonitorTicker('READY TO RECORD — PRESS RECORD TO RUN');
    if (playBtn) playBtn.title = 'PLAY — view manifests';
    if (recBtn) recBtn.title = 'RECORD — run YES queue';
    return;
  }

  if (selectedRunnable) {
    const label = reviewItemLabel(selectedRunnable);
    if (monMsg && !recorderRunning && !hasRecorderActivity) {
      setMonitorTicker(selectedRunnable.recorderStatus === 'YES' ? `${label} ACCEPTED — PRESS RECORD TO RUN` : `${label} SELECTED — PRESS PLAY TO ACCEPT`);
    }
    if (playBtn) playBtn.title = selectedRunnable.recorderStatus === 'YES' ? 'PLAY — view manifests' : 'PLAY — accept selected item';
    if (recBtn) recBtn.title = 'RECORD — run YES queue';
    return;
  }

  if (latestRunnable || proposalsAwaiting) {
    if (monMsg && !recorderRunning && !hasRecorderActivity) setMonitorTicker('MANIFESTS READY TO REVIEW');
    if (playBtn) playBtn.title = 'PLAY — review manifests';
    if (recBtn) recBtn.title = 'RECORD — check approved queue';
    return;
  }

  if (monMsg && !recorderRunning && !hasRecorderActivity) setMonitorTicker('SYSTEM READY');
  if (playBtn) playBtn.title = 'PLAY — review manifests';
  if (recBtn) recBtn.title = 'RECORD — check approved queue';
}
function viewMessage(text, durationMs = 4000) {
  const monMsg = byId('monitor-message');
  if (!monMsg) return;
  setMonitorTicker(text);
  clearTimeout(monMsg._t);
  monMsg._t = setTimeout(() => syncLeds(), durationMs);
}

function parsePort() {
  try {
    const url = new URL(DeckConnection.getURL());
    return url.port || (url.protocol === 'https:' ? '443' : url.protocol === 'http:' ? '80' : 'unknown');
  } catch {
    return 'unknown';
  }
}

function hidePort() {
  const el = byId('connected-port-display');
  if (el) el.textContent = 'port: *****';
}

function revealPort() {
  const el = byId('connected-port-display');
  if (!el) return;
  el.textContent = `port: ${parsePort()}`;
  clearTimeout(connectedPortRevealTimer);
  connectedPortRevealTimer = setTimeout(hidePort, 500);
}

// ── TABS ──────────────────────────────────────────────────────────────────────

document.querySelectorAll('#tabs [data-tab]').forEach(btn => {
  btn.addEventListener('click', () => {
    activateTab(btn.dataset.tab);
  });
});

document.querySelectorAll('.htab-btn').forEach(btn => {
  btn.addEventListener('click', () => {
    document.querySelectorAll('.htab-btn').forEach(b => b.classList.remove('active'));
    document.querySelectorAll('.hpanel').forEach(p => p.classList.remove('active'));
    btn.classList.add('active');
    const panel = byId('hpanel-' + btn.dataset.htab);
    if (panel) panel.classList.add('active');
    loadStream(btn.dataset.htab);
  });
});

function viewNotice(payload) {
  const notice = payload?.notice || null;
  const usage = payload?.usage || null;
  const code = notice?.code || payload?.error || usage?.code || '';
  const message = notice?.message || payload?.message || usage?.message || '';

  if (!message && !code) return;

  if (code === 'limited_bonus_runs_granted' || code === 'limited_bonus_run_available') {
    toast(message || 'Bonus day: you have 5 extra RECORD runs today. Launch sooner — keep going.', 9000);
    appendLog('★ bonus RECORD runs active: ' + (message || '5 extra runs today'), 'pass');
    return;
  }

  if (code === 'limited_daily_record_warning') {
    toast(message || 'You used your 5 RECORD runs today. Upgrade for unlimited runs and launch sooner.', 8000);
    appendLog('ⓘ limited RECORD runs used: ' + (message || '5/5 today'), 'neutral');
    return;
  }

  if (code === 'limited_daily_record_limit_reached' || code === 'limited_bonus_runs_exhausted') {
    toast(message || 'Daily RECORD limit reached. Upgrade to Standard for unlimited runs.', 100);
    appendLog('✗ RECORD limit reached: ' + (message || code), 'fail');
  }
}

function openAccountPortalWindow() {
  const opener = typeof openStandaloneAccountWindow === 'function' ? openStandaloneAccountWindow : null;
  if (opener) return opener();
  const win = window.open(ACCOUNT_PORTAL_URL + '?source=verbatim', 'nodarama-account', 'popup=yes,width=980,height=760,resizable=yes,scrollbars=yes,noopener,noreferrer');
  if (win) win.focus?.();
}

async function refreshAuthFromPortal() {
  const auth = await syncAccount();
  if (window.LaunchState) {
    LaunchState.auth = auth;
    LaunchState.settings = await SettingsStore.load();
  }
  toast(auth?.status === 'signed_in' ? 'Account status refreshed' : 'Still signed out');
  return auth;
}

async function acceptAgreementFromStatus() {
  const accepted = Boolean(byId('agreement-accept-check')?.checked);
  if (!accepted) { toast('Accept the agreement first.'); return; }
  const auth = await refreshAuthFromPortal();
  if (!verifyAuth(auth)) {
    toast('Sign in through the account window, then refresh.');
    return;
  }
  await SettingsStore.save({
    agreement: { version: agreementPolicyVersion, acceptedAt: Date.now(), accepted: true },
    authEmail: auth.email || '',
    authUserId: auth.userId || '',
    authTier: auth.tier || 'limited',
    authStatus: 'signed_in'
  });
  toggleGate(false);
  await loadSettingsUI();
  await loadProjectSelector();
  if (window.LaunchState) {
    LaunchState.auth = auth;
    LaunchState.settings = await SettingsStore.load();
    LaunchState.backstage = isBackstageAuth(LaunchState.auth);
    LaunchState.projects = await fetchLaunchProjects();
    await renderLaunchState();
  }
  toast('Agreement accepted. Account active.');
}

function openAccountPortalWindow() {
  const opener = typeof openStandaloneAccountWindow === 'function' ? openStandaloneAccountWindow : null;
  if (opener) return opener();
  const win = window.open(ACCOUNT_PORTAL_URL + '?source=verbatim', 'nodarama-account', 'popup=yes,width=980,height=760,resizable=yes,scrollbars=yes,noopener,noreferrer');
  if (win) win.focus?.();
}

async function refreshAuthFromPortal() {
  const auth = await syncAccount();
  if (window.LaunchState) {
    LaunchState.auth = auth;
    LaunchState.settings = await SettingsStore.load();
  }
  toast(auth?.status === 'signed_in' ? 'Account status refreshed' : 'Still signed out');
  return auth;
}

async function acceptAgreementFromStatus() {
  const accepted = Boolean(byId('agreement-accept-check')?.checked);
  if (!accepted) { toast('Accept the agreement first.'); return; }
  const auth = await refreshAuthFromPortal();
  if (!verifyAuth(auth)) {
    toast('Sign in through the account window, then refresh.');
    return;
  }
  await SettingsStore.save({
    agreement: { version: agreementPolicyVersion, acceptedAt: Date.now(), accepted: true },
    authEmail: auth.email || '',
    authUserId: auth.userId || '',
    authTier: auth.tier || 'limited',
    authStatus: 'signed_in'
  });
  toggleGate(false);
  await loadSettingsUI();
  await loadProjectSelector();
  if (window.LaunchState) {
    LaunchState.auth = auth;
    LaunchState.settings = await SettingsStore.load();
    LaunchState.backstage = isBackstageAuth(LaunchState.auth);
    LaunchState.projects = await fetchLaunchProjects();
    await renderLaunchState();
  }
  toast('Agreement accepted. Account active.');
}

function passGate() {
  if (!agreementGateActive) return true;
  toast('Accept the agreement and log in first.');
  activateTab('settings');
  return false;
}

function flashRecordActivity(durationMs = 1600) {
  recordActivityFlashUntil = Date.now() + durationMs;
  syncLeds();
}

function findReviewIndex(preferNewest = false) {
  if (!latestDubViewItems.length) return -1;
  if (preferNewest && lastRunnableDubKey) {
    const newestIndex = latestDubViewItems.findIndex(item => parseKey(item) === lastRunnableDubKey);
    if (newestIndex >= 0) return newestIndex;
  }
  const unapprovedIndex = latestDubViewItems.findIndex(item => checkRunnable(item) && item.recorderStatus !== 'YES');
  if (unapprovedIndex >= 0) return unapprovedIndex;
  return latestDubViewItems.findIndex(checkRunnable);
}

async function viewReviewItem(preferNewest = false) {
  activateTab('dubs');
  await readDubs();
  const index = findReviewIndex(preferNewest);
  if (index < 0) {
    toast('No manifests to review');
    return false;
  }
  selectedDubIndex = index;
  const item = latestDubViewItems[index];
  expandedDubKey = `${item.type}:${item.dubID}:${item.action}:${item.filePath}`;
  await readDubs();
  mapElement([...document.querySelectorAll('#dubs-list .dub-item')].filter(el => !el.classList.contains(ACT.run)), selectedDubIndex);
  syncManifest();
  clearWindow();
  toast('Manifest selected for review');
  return true;
}

// ── TRANSPORT CONTROLS ────────────────────────────────────────────────────────

on('send-manifest', 'click', () => { void runChat(); });
on('chat-input', 'keydown', event => {
  if ((event.ctrlKey || event.metaKey) && event.key === 'Enter') {
    event.preventDefault();
    void runChat();
  }
});
on('run-now-btn', 'click', async () => {
  const input = byId('manifest-input');
  const raw = input?.value.trim() || '';
  if (!raw) { toast('Enter manifest JSON'); return; }
  try {
    const parsed = JSON.parse(raw);
    const data = await api('/record', 'POST', parsed);
    if (data.ok) {
      viewNotice(data);
      if (input) input.value = '';
      appendLog(`⏺ sent manifest${data.dubID ? ` → dubID:${data.dubID}` : ''}`, 'pass');
      await readStatus();
      await readDubs();
      await readTape();
    } else {
      viewNotice(data);
      toast('Error: ' + (data.message || data.error || 'unknown'));
      appendLog(`✗ manifest failed: ${data.message || data.error || 'unknown'}`, 'fail');
    }
  } catch (err) {
    toast('JSON syntax error — ' + String(err?.message || err).slice(0, 80));
    appendLog(`✗ JSON parse error: ${err?.message || err}`, 'fail');
  }
});

on('pause-Eo', 'click', async () => {
  if (!passGate()) return;
  if (window.SysMenu) window.SysMenu.toggle();
});

on('eject-Eo', 'click', async () => {
  if (!passGate()) return;

  const confirmed = window.confirm('Clear queue and stored enhancements and diagnostics?');
  if (!confirmed) return;

  const data = await api('/playback/clear', 'POST', { kinds: ['diagnostic', 'enhancement'] });
  appendLog(`⏏ clear enhancements/diagnostics → ${data.ok ? 'ok' : data.error || 'failed'}`, data.ok ? 'pass' : 'fail');
  toast(data.ok ? 'Enhancements and diagnostics cleared' : 'Clear failed');
  await readStatus();
  await readDubs();
  await readTape();
});

on('record-Eo', 'click', async () => {
  if (!passGate()) return;

  flashRecordActivity(1800);
  const data = await api('/record/check', 'POST');
  appendLog(`⏺ record queue → ${data.ok ? data.state || 'ok' : data.error}`, data.ok ? 'pass' : 'fail');
  await readStatus();
  await readDubs();
});

on('play-Eo', 'click', async () => {
  if (!passGate()) return;

  const preferNewest = Boolean(recentChatManifest || checkFlashWindow());
  const viewed = await viewReviewItem(preferNewest);
  if (!viewed) toast('No pending or proposed recording sheets to review');
});

async function navWorkspaceTab(direction) {
  if (!passGate()) return;

  const tabs = [...document.querySelectorAll('#tabs [data-tab]')].filter(btn => !btn.disabled && btn.offsetParent !== null);
  if (!tabs.length) return;

  const currentIndex = Math.max(0, tabs.findIndex(btn => btn.classList.contains('active')));
  const nextIndex = (currentIndex + direction + tabs.length) % tabs.length;
  await activateTab(tabs[nextIndex].dataset.tab);
}

on('prev-Eo', 'click', () => navWorkspaceTab(-1));
on('next-Eo', 'click', () => navWorkspaceTab(1));
on('connected-port-display', 'click', revealPort);
on('qc-refresh', 'click', () => { if (typeof syncAll === 'function') void syncAll(); });
on('qc-status',  'click', () => { if (typeof readStatus === 'function') void readStatus(); });

// ── NAVIGATION ────────────────────────────────────────────────────────────────

function parseStamp(line) {
  const match = String(line || '').match(/^(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})/);
  if (!match) return 0;
  const dt = new Date(`${match[1]}T${match[2]}`);
  return Number.isFinite(dt.getTime()) ? dt.getTime() : 0;
}

function mapClusters(items) {
  const clusters = [];
  let current = [];
  let lastTime = 0;

  for (const item of items || []) {
    const time = parseStamp(item.textContent || '');
    if (current.length && time && lastTime && time - lastTime > ACTIVITY_CLUSTER_MS) {
      clusters.push(current);
      current = [];
    }
    current.push(item);
    if (time) lastTime = time;
  }

  if (current.length) clusters.push(current);
  return clusters;
}

function selectCluster(clusters, index) {
  clusters.flat().forEach(el => el.classList.remove('selected'));
  const cluster = clusters[index] || [];
  cluster.forEach(el => el.classList.add('selected'));
  cluster[0]?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
}

function mapNav(direction) {
  const tab = document.querySelector('#tabs [data-tab].active')?.dataset.tab || 'project';
  if (tab === 'editor')  navEditor(direction);
  else if (tab === 'dubs')    navDubs(direction);
  else if (tab === 'history') navHistory(direction);
  else if (tab === 'project') navProject(direction);
  else navGroups(direction);
}

function mapClamp(index, length, direction) {
  if (!length) return -1;
  if (index < 0) return direction > 0 ? 0 : length - 1;
  const next = index + direction;
  if (next < 0) return length - 1;
  if (next >= length) return 0;
  return next;
}

function mapElement(items, index) {
  items.forEach((el, i) => el.classList.toggle('selected', i === index));
  items[index]?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
}

function navDubs(direction) {
  const items = [...document.querySelectorAll('#dubs-list .dub-item')].filter(el => !el.classList.contains(ACT.run));
  if (!items.length) return navGroups(direction);
  selectedDubIndex = mapClamp(selectedDubIndex, items.length, direction);
  mapElement(items, selectedDubIndex);
  items[selectedDubIndex]?.classList.add('expanded');
  syncManifest();
}

function navHistory(direction) {
  const activePanel = document.querySelector('#panel-history .hpanel.active');
  const isTape = activePanel?.id === 'hpanel-tape';
  const items = isTape
    ? [...document.querySelectorAll('#tape-list .tape-item')]
    : [...(activePanel?.querySelectorAll('.log-stream-line') || [])];

  if (!items.length) return navGroups(direction);

  if (isTape) {
    selectedTapeIndex = mapClamp(selectedTapeIndex, items.length, direction);
    mapElement(items, selectedTapeIndex);
    items[selectedTapeIndex]?.classList.add('expanded');
    return;
  }

  const clusters = mapClusters(items);
  if (!clusters.length) return navGroups(direction);
  selectedTapeIndex = mapClamp(selectedTapeIndex, clusters.length, direction);
  selectCluster(clusters, selectedTapeIndex);
}

function navEditor(direction) {
  const textarea = byId('editor-textarea');
  if (!textarea) return navGroups(direction);
  const lines = textarea.value.split('\n');
  const ranges = [];
  let offset = 0;
  const patterns = [
    /^\s*function\s+\w+\s*\(/,
    /^\s*(const|let|var)\s+\w+\s*=\s*(async\s*)?\([^)]*\)\s*=>/,
    /^\s*(const|let|var)\s+\w+\s*=\s*(async\s*)?function\s*\(/,
    /^\s*(async\s+)?\w+\s*\([^)]*\)\s*\{/,
    /^\s*class\s+\w+/
  ];
  for (let i = 0; i < lines.length; i++) {
    if (patterns.some(p => p.test(lines[i]))) ranges.push({ start: offset, end: offset + lines[i].length });
    offset += lines[i].length + 1;
  }
  if (!ranges.length) return navGroups(direction);
  const pos = textarea.selectionStart || 0;
  let cur = ranges.findIndex((r, idx) => pos >= r.start && pos < (ranges[idx + 1]?.start ?? Infinity));
  if (cur < 0) cur = direction > 0 ? -1 : 0;
  const target = ranges[mapClamp(cur, ranges.length, direction)];
  textarea.focus();
  textarea.setSelectionRange(target.start, target.end);
  textarea.scrollTop = Math.max(0, (textarea.value.slice(0, target.start).split('\n').length - 2) * 20);
}

function navGroups(direction) {
  const rows = [...document.querySelectorAll('#system-log .log-line')];
  const groups = [];
  let cur = [], curGroup = null;
  for (const row of rows) {
    const g = row.dataset.runGroup || 'system-group-0';
    if (g !== curGroup) { if (cur.length) groups.push(cur); cur = [row]; curGroup = g; }
    else cur.push(row);
  }
  if (cur.length) groups.push(cur);
  if (!groups.length) return;
  selectedSystemGroupIdx = mapClamp(selectedSystemGroupIdx, groups.length, direction);
  groups.forEach((g, gi) => g.forEach(r => r.classList.toggle('selected', gi === selectedSystemGroupIdx)));
  groups[selectedSystemGroupIdx]?.[0]?.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
}

function cleanResponse(value) {
  const raw = String(value ?? '').trim();
  if (!raw) return '';
  try {
    const parsed = JSON.parse(raw);
    if (parsed && typeof parsed === 'object') {
      return String(parsed.Response || parsed.response || parsed.summary || '').trim() || raw;
    }
  } catch {}
  const match = raw.match(/"Response"\s*:\s*"((?:\\"|[^"])*)"/i);
  if (match?.[1]) {
    return match[1].replace(/\\"/g, '"').replace(/\\n/g, '\n').trim();
  }
  return raw;
}

async function runChat() {
  if (agreementGateActive) {
    toast('Accept the agreement and log in first.');
    activateTab('settings');
    return;
  }

  const input = byId('chat-input');
  const raw = input?.value.trim() || '';
  if (!raw) return;

  // valid JSON → /record
  if (raw.startsWith('{') || raw.startsWith('[')) {
    let parsed;
    try { parsed = JSON.parse(raw); } catch (e) {
      toast('JSON syntax error — ' + String(e.message).slice(0, 80));
      appendLog(`✗ JSON parse error: ${e.message}`, 'fail');
      return;
    }
    const manifests = Array.isArray(parsed) ? parsed : [parsed];
    const data = await api('/record', 'POST', parsed);
    if (data.ok) {
      viewNotice(data);
      appendLog(
        manifests.length > 1
          ? `⏺ sent ${data.accepted || manifests.length} manifest${(data.accepted || manifests.length) !== 1 ? 's' : ''}`
          : `⏺ ${ACT.inj}ect → dubID:${data.dubID || '?'} ${data.status || 'running'}`,
        'pass'
      );
      if (input) input.value = '';
    } else {
      viewNotice(data);
      appendLog(`✗ inject failed: ${data.message || data.error}`, 'fail');
      toast('Error: ' + (data.message || data.error));
    }
    await readStatus();
    readDubs();
    return;
  }

  // everything else → /eq/chat
  appendLog(`CHAT OUT → ${raw.slice(0, 120)}${raw.length > 120 ? '…' : ''}`, 'chat-out');
  if (input) input.value = '';
  aiEngaged = true;
  syncLeds();
  try {
    const data = await api('/eq/chat', 'POST', { message: raw });
    if (!data.ok) {
      appendLog(`✗ chat failed: ${data.error || 'unknown'}`, 'fail');
      toast('Chat error: ' + (data.error || 'unknown'));
      return;
    }
    if (data.reply) {
      const reply = cleanResponse(data.reply);
      appendLog(`CHAT IN ← ${reply}`, 'chat-in');
    }
  } finally {
    aiEngaged = false;
    clearEQSustain('chat');
    safeTriggerEQActivity('low');
    syncLeds();
  }
}

async function runFile() {
  const raw = byId('chat-input')?.value.trim() || '';
  if (!raw) { toast('Enter a file path'); return; }
  const data = await api('/read/file', 'POST', { path: raw });
  if (data.ok && data.files?.[0]) {
    const f = data.files[0];
    if (f.ok) { 
      const input = byId('chat-input'); 
      if (input) input.value = (f.content || '').slice(0, 2000); 
      appendLog(`📄 read ${f.FilePath}`, 'pass'); 
    }
    else appendLog(`✗ read failed: ${f.error}`, 'fail');
  }
}

// ── CHAT MANIFEST WINDOW ──────────────────────────────────────────────────────

function openWindow(entry) {
  clearWindow();
  if (!entry?.manifest) return;
  recentChatManifest = entry;
  recentChatTimer = setTimeout(() => clearWindow(), 20000);
  syncLeds();
}

function clearWindow() {
  if (recentChatTimer) clearTimeout(recentChatTimer);
  if (recentChatBlink) clearInterval(recentChatBlink);
  recentChatTimer = null;
  recentChatBlink = null;
  recentChatManifest = null;
  syncLeds();
}

// ── DUB TAPE ──────────────────────────────────────────────────────────────────

function syncManifest() {
  const item = latestDubViewItems[selectedDubIndex] || null;
  if (!item?.manifest || item.status !== 'proposal' || !checkRunnable(item)) {
    selectedDubManifest = null;
    selectedDubKind = 'diagnostic';
    selectedDubSource = 'monitor';
  } else {
    selectedDubManifest = item.manifest;
    selectedDubKind = item.type === 'enhancement' ? 'enhancement' : item.type === 'error' ? 'error' : 'diagnostic';
    selectedDubSource = item.source || 'monitor';
  }
  syncLeds();
}

async function readDubs() {
  const data = await api('/dubs/playback');
  if (!data.ok) return;

  latestDubTape = data.tape || [];
  const latestCompletedDub = latestDubTape.slice().reverse().find(item => item?.status === 'done' || item?.status === 'error') || null;
  const latestCompletedKey = latestCompletedDub
    ? `${latestCompletedDub.status || ''}:${latestCompletedDub.dubID || ''}:${latestCompletedDub.timestamp || ''}`
    : '';
  if (!lastCompletedDubKey && latestCompletedKey) {
    lastCompletedDubKey = latestCompletedKey;
  } else if (latestCompletedKey && latestCompletedKey !== lastCompletedDubKey) {
    lastCompletedDubKey = latestCompletedKey;
    clearEQSustain();
    if (latestCompletedDub.status === 'done') {
      safeTriggerEQActivity('medium');
      viewMessage('✓ RUN COMPLETE', 5000);
      appendLog('✓ run complete', 'pass');
    } else {
      safeTriggerEQActivity('high');
      viewMessage('✗ RUN FAILED', 6000);
      appendLog('✗ run failed', 'fail');
    }
  }

  const proposals = latestDubTape.filter(i => i.status === 'proposal' && String(i.source || '') !== 'typecheck');
  yesItemsReady    = proposals.some(i => i.recorderStatus === 'YES');
  proposalsAwaiting = proposals.some(i => i.recorderStatus === 'NO');
  renderCurrentIssues(latestDubTape);

  const items   = compileItems(latestDubTape);
  const visible = items.filter(i => dubFilters.has(i.type) || (i.type === ACT.run && dubFilters.has(ACT.run)));
  latestDubViewItems = visible;

  const latestRunnable = items.find(checkRunnable) || null;
  const latestRunnableKey = parseKey(latestRunnable);
  if (latestRunnableKey && latestRunnableKey !== lastRunnableDubKey) {
    lastRunnableDubKey = latestRunnableKey;
    runnableDubFlashUntil = Date.now() + 20000;
  }

  const list  = byId('dubs-list');
  const empty = byId('dubs-empty');
  if (!list || !empty) { syncLeds(); return; }

  const currentIssues = currentIssueItems(latestDubTape);
  const counts = { error: currentIssues.length, diagnostic: 0, enhancement: 0, run: 0 };
  items.forEach(i => { if (i.type in counts) counts[i.type]++; });

  list.innerHTML = '';
  selectedDubIndex = visible.length ? Math.min(selectedDubIndex, visible.length - 1) : -1;
  const set = (id, val) => { const el = byId(id); if (el) el.textContent = String(val); };

  set('dubs-count', items.length + currentIssues.length);
  set('dubs-count-error', counts.error);
  set('dubs-count-diagnostic', counts.diagnostic);
  set('dubs-count-enhancement', counts.enhancement);
  set('dubs-count-run', counts.run);

  const tabStar = byId('dubs-tab-star');
  if (tabStar) tabStar.style.display = counts.diagnostic > 0 ? '' : 'none';

  const monMsg = byId('monitor-message');
  if (!recorderRunning && !aiEngaged && !recentChatManifest && !yesItemsReady && monMsg) {
    if (counts.diagnostic > 0) setMonitorTicker('DIAGNOSTIC REPAIR READY');
    else if (counts.enhancement > 0) setMonitorTicker('ENHANCEMENTS SUGGESTED');
    else if (!proposalsAwaiting) setMonitorTicker('SYSTEM READY');
  }

  document.querySelectorAll('#dubs-categories .dub-cat').forEach(el => {
    el.classList.toggle('inactive', !dubFilters.has(el.dataset.kind));
  });

  if (!visible.length) {
    empty.style.display = '';
    selectedDubManifest = null;
    syncLeds();
    return;
  }
  empty.style.display = 'none';

  for (let index = 0; index < visible.length; index++) {
    const item = visible[index];
    const div = document.createElement('div');
    const itemKey = `${item.type}:${item.dubID}:${item.action}:${item.filePath}`;
    div.className = ['dub-item', item.tone, item.type, item.status, checkRunnable(item) ? 'pending-manifest' : ''].filter(Boolean).join(' ');
    div.dataset.index = String(index);
    if (expandedDubKey === itemKey) div.classList.add('expanded');
    if (selectedDubIndex === index) div.classList.add('selected');
    div.innerHTML = `
      <span class="dub-id">${esc(String(item.dubID || '').slice(-8))}</span>
      <span>
        <div class="dub-action"><span class="dub-label ${item.tone}">${esc(item.label)}</span> ${esc(item.action || '—')}${item.filePath ? ` (${esc(item.filePath.replace(/\\/g, '/').split('/').pop())})` : ''}</div>
        ${item.task ? `<div class="dub-summary">${esc(item.task)}</div>` : ''}
        ${item.status === 'proposal' ? `<div class="dub-summary">Recorder: ${esc(item.recorderStatus || 'NO')}</div>` : ''}
        <div class="dub-summary">${esc(item.summary || '')}</div>
        <div class="dub-detail"><pre>${esc(JSON.stringify(item.detail, null, 2))}</pre></div>
      </span>
      <span class="dub-meta">${esc(item.time || '')}</span>
    `;
    div.addEventListener('click', () => {
      const willExpand = !div.classList.contains('expanded');
      list.querySelectorAll('.dub-item.expanded').forEach(el => el.classList.remove('expanded'));
      list.querySelectorAll('.dub-item.selected').forEach(el => el.classList.remove('selected'));
      div.classList.add('selected');
      selectedDubIndex = index;
      expandedDubKey = willExpand ? itemKey : null;
      if (willExpand) div.classList.add('expanded');
      syncManifest();
    });
    list.appendChild(div);
  }
  syncManifest();
}

function checkAccepted(item) {
  return Boolean(
    item && item.status === 'done' && 
    (item.kind === 'diagnostic' || item.kind === 'enhancement') && 
    item.result && (item.result.acceptedFromTape || item.result.correctedByLocalAI || item.recorderStatus === 'RETRIEVED')
  );
}

function verifyStamp(item) {
  return checkAccepted(item) ? '✓ ' : '';
}

function currentIssueItems(tape) {
  return (tape || []).filter(item => item?.kind === 'error' && String(item?.source || '') === 'typecheck');
}
function renderCurrentIssues(tape) {
  const host = byId('dubs-issues-list');
  if (!host) return;
  const issues = currentIssueItems(tape);
  if (!issues.length) {
    host.innerHTML = '<div class="dub-issue-empty">No current issues.</div>';
    return;
  }
  host.innerHTML = issues.map(item => {
    const result = item.result || {};
    const loc = [result.filePath || '', result.line ? `:${result.line}` : '', result.column ? `:${result.column}` : ''].join('');
    const code = result.code ? `${result.code} ` : '';
    return `<div class="dub-issue-item"><div class="dub-issue-path">${esc(loc || 'TypeScript')}</div><div class="dub-issue-text">${esc(code + (result.error || result.summary || 'Issue'))}</div></div>`;
  }).join('');
}
function copyCurrentIssues() {
  const text = byId('dubs-issues-list')?.innerText || '';
  if (!text.trim() || text.includes('No current issues.')) { toast('No current issues to copy'); return; }
  navigator.clipboard?.writeText(text).then(() => toast('Current issues copied')).catch(() => downloadText(text, `current-issues-${Date.now()}.txt`));
}

function compileItems(tape) {
  const out = [];
  for (const item of (tape || []).slice().reverse()) {
    if (item?.kind === 'error' && String(item?.source || '') === 'typecheck') continue;
    const manifest = item.manifest || {}, result = item.result || {};
    const time = item.timestamp ? new Date(item.timestamp).toLocaleTimeString() : '';
    const action = manifest.Action || result.kind || '—';
    const task = manifest.Task || '';
    const filePath = manifest.FilePath || result.filePath || '';

    if (item.status === 'proposal') {
      const type = item.kind === 'enhancement' ? 'enhancement' : item.kind === 'error' ? 'error' : 'diagnostic';
      out.push({
        type, tone: type, dubID: item.dubID, action, task, filePath, time,
        label: type === 'enhancement' ? 'Enhancement' : type === 'error' ? 'Error Report' : 'Diagnostic Repair',
        summary: result.summary || task || 'Proposal saved to tape.',
        source: item.source || 'eq', recorderStatus: item.recorderStatus || 'NO', status: item.status, manifest,
        detail: { manifest, result, recorderStatus: item.recorderStatus, source: item.source }
      });
    } else {
      const completedKind = item.kind === 'diagnostic' || item.kind === 'enhancement' ? item.kind : (item.status === 'error' ? 'error' : ACT.run);
      const acceptedCheck = verifyStamp(item);
      out.push({
        type: completedKind, tone: completedKind,
        label: item.status === 'error' ? 'RUN ERROR' : completedKind === 'enhancement' ? `${acceptedCheck}Enhancement Run` : completedKind === 'diagnostic' ? `${acceptedCheck}Diagnostic Run` : `${acceptedCheck}RUN`,
        dubID: item.dubID, action, task, filePath, time,
        summary: item.status === 'error' ? (result.error || result.message || 'Run failed.') : (result.message || 'Execution completed.'),
        source: item.source || 'recorder', recorderStatus: item.recorderStatus || 'RETRIEVED', status: item.status, manifest,
        acceptedCompleted: checkAccepted(item),
        detail: { manifest, result, recorderStatus: item.recorderStatus, source: item.source, kind: item.kind }
      });
    }
  }
  return out;
}

document.querySelectorAll('#dubs-categories .dub-cat').forEach(el => {
  el.addEventListener('click', () => {
    const kind = el.dataset.kind;
    if (!kind) return;
    if (dubFilters.has(kind)) dubFilters.delete(kind);
    else dubFilters.add(kind);
    readDubs();
  });
});

on('dubs-clear-btn', 'click', async () => {
  const data = await api('/dubs/clear', 'POST');
  if (data.ok) {
    selectedDubIndex = -1;
    selectedDubManifest = null;
    expandedDubKey = null;
    await readDubs();
  }
});

on('dubs-issues-copy-btn', 'click', copyCurrentIssues);

// ── HISTORY / PLAYBACK DISPLAY ───────────────────────────────────────────────

function formatTapeTime(value) {
  const stamp = Number(value || 0);
  if (!stamp) return '';
  try { return new Date(stamp).toLocaleString(); } catch { return ''; }
}

function formatTapeAction(item) {
  const manifest = item?.manifest || {};
  const result = item?.result || {};
  return String(manifest.Task || manifest.Action || result.kind || item?.kind || 'Tape item').trim();
}

function formatTapePath(item) {
  const manifest = item?.manifest || {};
  const result = item?.result || {};
  return String(manifest.FilePath || result.filePath || '').replace(/\\/g, '/');
}

function formatTapeSummary(item) {
  const result = item?.result || {};
  return String(result.message || result.summary || result.error || item?.status || '').trim();
}

function renderTapeItem(item, index) {
  const row = document.createElement('div');
  const status = String(item?.status || '').toLowerCase();
  row.className = ['tape-item', status === 'error' ? 'error' : status === 'done' ? 'done' : 'proposal'].filter(Boolean).join(' ');
  row.dataset.index = String(index);
  row.innerHTML = `
    <div class="tape-row1">
      <span class="tape-dubid">${esc(String(item?.dubID || '').slice(-10) || 'no-id')}</span>
      <span class="tape-status-dot ${esc(status)}">${status === 'error' ? '● ERROR' : status === 'done' ? '● DONE' : '● PROPOSAL'}</span>
    </div>
    <div class="tape-action">${esc(formatTapeAction(item))}</div>
    ${formatTapePath(item) ? `<div class="tape-path">${esc(formatTapePath(item))}</div>` : ''}
    ${formatTapeSummary(item) ? `<div class="tape-time">${esc(formatTapeSummary(item))}</div>` : ''}
    <div class="tape-time">${esc(formatTapeTime(item?.timestamp))}</div>
    <div class="tape-detail"><pre>${esc(JSON.stringify(item || {}, null, 2))}</pre></div>
  `;
  row.addEventListener('click', () => {
    document.querySelectorAll('#tape-list .tape-item').forEach(el => el.classList.remove('selected', 'expanded'));
    row.classList.add('selected', 'expanded');
    selectedTapeIndex = index;
  });
  return row;
}

async function readTape() {
  const host = byId('tape-list');
  if (!host) return;
  host.innerHTML = '<div class="log-stream-line neutral">Loading tape…</div>';
  const data = await api('/playback');
  if (!data?.ok) {
    host.innerHTML = `<div class="log-stream-line fail">Playback unavailable: ${esc(data?.message || data?.error || 'unknown')}</div>`;
    return;
  }
  const tape = Array.isArray(data.tape) ? data.tape.slice().reverse() : [];
  host.innerHTML = '';
  if (!tape.length) {
    host.innerHTML = '<div class="log-stream-line neutral">No tape history yet.</div>';
    return;
  }
  tape.forEach((item, index) => host.appendChild(renderTapeItem(item, index)));
  historyStreamSignatures.set('tape', historySignature(tape.map(item => JSON.stringify(item))));
}

function lineTone(text) {
  const clean = String(text || '').toLowerCase();
  if (/fail|error|blocked|invalid|missing|rejected/.test(clean)) return 'fail';
  if (/done|complete|success|ready|created|saved|ok|pass|started/.test(clean)) return 'pass';
  if (/\[ai:|chat/.test(clean)) return 'ai';
  if (/\[code\]|@@|^[-+]/.test(clean)) return 'code';
  return 'neutral';
}

function renderLogLines(host, lines, emptyText = 'No log entries yet.') {
  host.innerHTML = '';
  if (!Array.isArray(lines) || !lines.length) {
    host.innerHTML = `<div class="log-stream-line neutral">${esc(emptyText)}</div>`;
    return;
  }
  lines.forEach(line => {
    const div = document.createElement('div');
    div.className = `log-stream-line ${lineTone(line)}`;
    div.textContent = String(line || '');
    host.appendChild(div);
  });
}

async function loadTimeline() {
  const host = byId('log-stream-timeline');
  if (!host) return;
  host.innerHTML = '<div class="log-stream-line neutral">Loading timeline…</div>';
  const data = await api('/recovery/timeline?limit=80');
  if (!data?.ok) {
    host.innerHTML = `<div class="log-stream-line fail">Timeline unavailable: ${esc(data?.message || data?.error || 'unknown')}</div>`;
    return;
  }
  const items = Array.isArray(data?.details?.entries)
    ? data.details.entries
    : Array.isArray(data.items)
      ? data.items
      : Array.isArray(data.timeline)
        ? data.timeline
        : [];
  const lines = items.map(formatTimelineEntry);
  renderLogLines(host, lines, 'No timeline entries yet.');
  historyStreamSignatures.set('timeline', historySignature(lines));
}

function formatTimelineEntry(item) {
  if (typeof item === 'string') return item;
  const stamp = Number(item?.ts || 0) ? new Date(Number(item.ts)).toLocaleString() : '';
  const kind = String(item?.kind || 'timeline').trim();
  const label = String(item?.label || '').trim();
  const status = String(item?.status || '').trim();
  const filePath = String(item?.filePath || '').replace(/\\/g, '/').trim();
  return [stamp, kind, status, label, filePath].filter(Boolean).join(' · ');
}
async function loadStream(stream, resetArchive = false) {
  const clean = String(stream || 'system').trim();
  if (clean === 'tape') return readTape();
  if (clean === 'timeline') return loadTimeline();
  if (resetArchive) resetHistoryArchiveDepth(clean);

  const host = byId(`log-stream-${clean}`);
  if (!host) return;
  host.innerHTML = '<div class="log-stream-line neutral">Loading log…</div>';

  const archiveDepth = historyArchiveDepth(clean);
  const data = await api(`/logs/${encodeURIComponent(clean)}?limit=600&archiveDepth=${archiveDepth}`);
  if (!data?.ok) {
    host.innerHTML = `<div class="log-stream-line fail">Log unavailable: ${esc(data?.message || data?.error || 'unknown')}</div>`;
    return;
  }

  const lines = data.lines || [];
  renderLogLines(host, lines, 'No log entries yet.');
  historyStreamSignatures.set(clean, historySignature(lines));
}
function activeHistoryStream() {
  return document.querySelector('#history-tabs .htab-btn.active')?.dataset.htab || 'tape';
}

function historyHostForStream(stream) {
  if (stream === 'tape') return byId('tape-list');
  if (stream === 'timeline') return byId('log-stream-timeline');
  return byId(`log-stream-${stream}`);
}

function historyArchiveDepth(stream) {
  return Math.max(0, Number(historyArchiveDepths.get(String(stream || 'system')) || 0));
}
function resetHistoryArchiveDepth(stream) {
  historyArchiveDepths.set(String(stream || 'system'), 0);
}
async function loadMoreHistoryStream(stream = activeHistoryStream()) {
  const clean = String(stream || 'system').trim();
  if (clean === 'tape' || clean === 'timeline') {
    toast('More history is not available for this view yet.');
    return;
  }
  historyArchiveDepths.set(clean, historyArchiveDepth(clean) + 1);
  await loadStream(clean);
  toast('More history loaded');
}

async function refreshActiveHistory() {
  const stream = activeHistoryStream();
  if (stream === 'tape') await readTape();
  else await loadStream(stream);
}

function historySignature(lines) {
  const list = Array.isArray(lines) ? lines.map(line => String(line || '')) : [];
  return JSON.stringify({ count: list.length, newest: list[list.length - 1] || '', oldest: list[0] || '' });
}

async function readHistoryStreamLines(stream) {
  const clean = String(stream || 'system').trim();
  if (clean === 'tape') {
    const data = await api('/playback');
    const tape = Array.isArray(data?.tape) ? data.tape.slice().reverse() : [];
    return tape.map(item => JSON.stringify(item));
  }
  if (clean === 'timeline') {
    const data = await api('/recovery/timeline?limit=80');
    const items = Array.isArray(data?.details?.entries)
      ? data.details.entries
      : Array.isArray(data?.items)
        ? data.items
        : Array.isArray(data?.timeline)
          ? data.timeline
          : [];
    return items.map(formatTimelineEntry);
  }
  const data = await api(`/logs/${encodeURIComponent(clean)}?limit=600&archiveDepth=${historyArchiveDepth(clean)}`);
  return Array.isArray(data?.lines) ? data.lines : [];
}

async function checkActiveHistoryForUpdates() {
  if (!document.querySelector('#tabs [data-tab="history"].active')) return;
  const stream = activeHistoryStream();
  const lines = await readHistoryStreamLines(stream);
  const nextSignature = historySignature(lines);
  if (historyStreamSignatures.get(stream) === nextSignature) return;
  historyStreamSignatures.set(stream, nextSignature);
  await loadStream(stream);
}

function copyHistoryStream(stream = activeHistoryStream()) {
  const host = historyHostForStream(stream);
  const text = host?.innerText || '';
  if (!text.trim()) { toast('Nothing to copy'); return; }
  navigator.clipboard?.writeText(text).then(() => toast('History copied')).catch(() => downloadText(text, `${stream}-history.txt`));
}

function archiveHistoryStream(stream = activeHistoryStream()) {
  const host = historyHostForStream(stream);
  const text = host?.innerText || '';
  if (!text.trim()) { toast('Nothing to archive'); return; }
  downloadText(text, `${stream}-history-${Date.now()}.txt`);
}

function bindHistoryControls() {
  const refreshMap = {
    'tape-refresh-btn': 'tape',
    'syslog-refresh-btn': 'system',
    'ai-chatlog-refresh-btn': 'ai-chat',
    'ai-diagnosticlog-refresh-btn': 'ai-diagnostic',
    'codelog-refresh-btn': 'code',
    'timelinelog-refresh-btn': 'timeline'
  };
  Object.entries(refreshMap).forEach(([id, stream]) => on(id, 'click', () => loadStream(stream, true)));

  const moreMap = {
    'syslog-more-btn': 'system',
    'ai-chatlog-more-btn': 'ai-chat',
    'ai-diagnosticlog-more-btn': 'ai-diagnostic',
    'codelog-more-btn': 'code'
  };
  Object.entries(moreMap).forEach(([id, stream]) => on(id, 'click', () => loadMoreHistoryStream(stream)));

  on('tape-archive-btn', 'click', () => archiveHistoryStream('tape'));
  on('syslog-copy-btn', 'click', () => copyHistoryStream('system'));
  on('syslog-archive-btn', 'click', () => archiveHistoryStream('system'));
  on('ai-chatlog-copy-btn', 'click', () => copyHistoryStream('ai-chat'));
  on('ai-chatlog-archive-btn', 'click', () => archiveHistoryStream('ai-chat'));
  on('ai-diagnosticlog-copy-btn', 'click', () => copyHistoryStream('ai-diagnostic'));
  on('ai-diagnosticlog-archive-btn', 'click', () => archiveHistoryStream('ai-diagnostic'));
  on('codelog-copy-btn', 'click', () => copyHistoryStream('code'));
  on('codelog-archive-btn', 'click', () => archiveHistoryStream('code'));
  on('timelinelog-copy-btn', 'click', () => copyHistoryStream('timeline'));
  on('timelinelog-archive-btn', 'click', () => archiveHistoryStream('timeline'));
}
function bindHistoryPassiveUpdate() {
  const panel = byId('panel-history');
  if (!panel || panel.dataset.passiveHistoryUpdate === 'true') return;
  panel.dataset.passiveHistoryUpdate = 'true';
  panel.addEventListener('click', () => {
    clearTimeout(historyClickCheckTimer);
    historyClickCheckTimer = setTimeout(() => {
      void checkActiveHistoryForUpdates();
    }, 120);
  });
}

bindHistoryControls();
bindHistoryPassiveUpdate();

// ── LEFT SYSTEM LOG DISPLAY ──────────────────────────────────────────────────

function logTone(text, fallback = 'neutral') {
  const value = String(text || '').toLowerCase();
  if (/chat out|\[ai:out\]/.test(value)) return 'chat-out';
  if (/chat in|\[ai:in\]/.test(value)) return 'chat-in';
  if (/\b(aux inquiry|manifold|eq call failed|ai call failed|typecheck clear)\b/.test(value)) return 'neutral';
  if (/\b(typecheck issues|typecheck failed|recorder error|record failed|run failed|call unsuccessful|execute failed)\b/.test(value)) return 'fail';
  if (/\b(recorded|record complete|run complete|revision complete|revised)\b/.test(value)) return 'pass';
  if (/fail|error|blocked|invalid|missing|rejected|unavailable/.test(value)) return 'fail';
  if (/done|complete|success|ready|created|saved|ok|pass|started|switched/.test(value)) return 'pass';
  return fallback || 'neutral';
}
function decorateLogLine(el, rawText) {
  const text = String(rawText || '');
  const fileMatch = text.match(/\b(filePath|file):([^\s]+)/i);
  const taskMatch = text.match(/\bTask:([^\n]+)$/i);
  if (!fileMatch && !taskMatch) {
    el.textContent = text;
    return;
  }

  let html = esc(text);
  html = html.replace(/\b(Task:)([^\n]+)/i, '<span class="log-task-prefix">$1</span><span class="log-task-name">$2</span>');
  html = html.replace(/\b(filePath|file):([^\s]+)/i, '<span class="log-task-at">$1:</span><span class="log-file-path">$2</span>');
  el.innerHTML = html;
  if (taskMatch) el.classList.add('task-log-line');
}

function appendLog(text, tone = 'neutral') {
  if (window.__visualizerSystemLogTakeover) return;
  const host = byId('log-window') || byId('system-log');
  if (!host) return;
  if (host.id === 'log-window' && host.textContent === 'Waiting for system activity…') host.innerHTML = '';
  const line = document.createElement('div');
  const raw = String(text || '');
  const finalTone = logTone(raw, tone);
  line.className = `log-line ${finalTone}`;

  if (/\bMANIFOLD\b/i.test(raw)) line.classList.add('log-manifold');
  if (/\bEQ CALL FAILED\b|\bAI CALL FAILED\b/i.test(raw)) line.classList.add('log-eq-soft');
  if (/\bTYPECHECK CLEAR\b/i.test(raw)) line.classList.add('log-typecheck-clear');
  if (/\bTYPECHECK ISSUES\b|\bTYPECHECK FAILED\b/i.test(raw)) line.classList.add('log-typecheck-error');
  if (/\bRECORDED\b|\bRECORDER ERROR\b|\bRECORD QUEUE\b|\bRUN COMPLETE\b|\bRUN FAILED\b/i.test(raw)) line.classList.add('recorder-note');
  if (/\bRECORDER ERROR\b|\bRUN FAILED\b/i.test(raw)) line.classList.add('recorder-failed');

  line.dataset.runGroup = currentSidebarGroup || 'system-group-0';
  decorateLogLine(line, raw);
  host.appendChild(line);
  logLines.push(raw);
  if (logLines.length > 600) {
    logLines = logLines.slice(-600);
    while (host.children.length > 600) host.removeChild(host.firstChild);
  }
  const shell = byId('system-log');
  if (shell) shell.scrollTop = shell.scrollHeight;
}
function logValue(text, key) {
  const match = String(text || '').match(new RegExp(`\\b${key}:([^\\s]+)`, 'i'));
  return match?.[1] ? match[1] : '';
}

function logTextAfter(text, key) {
  const match = String(text || '').match(new RegExp(`\\b${key}:([^]+?)(?=\\s+[A-Za-z][A-Za-z0-9_]*:|\\s+tag:|$)`, 'i'));
  return match?.[1] ? match[1].trim() : '';
}

function compactSidebarSystemLine(raw) {
  const text = String(raw || '').trim();
  if (!text) return '';

  const stampMatch = text.match(/^(\d{4}-\d{2}-\d{2})\s+(\d{2}:\d{2}:\d{2})/);
  const date = stampMatch?.[1] || '';
  const time = stampMatch?.[2] || '';
  const keepDate = /\b(login|sign[-_ ]?in|auth)\b/i.test(text);
  const at = time ? `${keepDate && date ? `${date} ` : ''}${time} ` : '';
  const tag = text.match(/\[([^\]]+)\]/)?.[1] || '';
  const source = tag ? tag.toUpperCase() : 'SYSTEM';
  const target = logValue(text, 'target');
  const request = logValue(text, 'request');
  const filePath = (logValue(text, 'filePath') || logValue(text, 'file')).replace(/^C:\/NV\//i, '').replace(/\\/g, '/');
  const task = logTextAfter(text, 'Task');
  const action = logValue(text, 'Action');
  const dubID = logValue(text, 'dubID');

  if (/\binquiry_start\b/.test(text)) return '';
  if (/\bactive_on\b|\bactive_off\b/.test(text)) return '';
  if (/\bproject_context_entered\b|\bproject_context_restored\b/.test(text)) return '';
  if (/\[Recorder\].*\bexecute\s+\{/.test(text)) return '';
  if (/\baiRepair_call\b|\baiRepair_reply_received\b|\baiRepair_no_safe_repair\b/.test(text)) return '';

  if (/\bexecute_start\b/.test(text)) {
    const key = dubID || filePath || `${Date.now()}`;
    sidebarRunMeta.set(key, { filePath, task, action });
    if (dubID) sidebarRunMeta.set(filePath, { filePath, task, action });
    return '';
  }

  if (/\bexternal_drift_detected\b/.test(text)) {
    return `${at}DRIFT DETECTED${filePath ? ` — ${filePath}` : ''}`;
  }

  if (/\[Manifold\]/i.test(text)) {
    const via = logValue(text, 'via');
    if (/\broute_request\b/.test(text)) return `${at}MANIFOLD request${via ? ` — ${via}` : ''}`;
    if (/\broute_received_repaired\b/.test(text)) return `${at}MANIFOLD revised${via ? ` — ${via}` : ''}`;
    return `${at}MANIFOLD`;
  }

  if (/\[EQ\]/i.test(text)) {
    const via = logValue(text, 'via');
    const error = logTextAfter(text, 'error');
    if (/\bai_call_failed\b/.test(text)) return `${at}EQ CALL FAILED${via ? ` — ${via}` : ''}${error ? ` · ${error}` : ''}`;
    if (/\bai_call_/i.test(text)) return `${at}EQ CALL`;
  }

  if (/\binquiry_done\b/.test(text)) {
    const count = logValue(text, 'count');
    const ok = logValue(text, 'ok');
    const mark = ok === 'false' ? '✗' : '✓';
    const label = target || request || 'project';
    if (source === 'AUX' || /\bsource:aux\b/i.test(text)) {
      const noun = label === 'prj-file' || label === 'prj-map' || label === 'project' ? `${label}s` : label;
      return `${at}AUX Inquiry - ${noun}: ${count || (mark === '✓' ? '1' : '0')}`;
    }
    return `${at}${source} READ ${label} ${mark}${count ? ` · ${count}` : ''}`;
  }

  if (/\bsettings_saved\b/.test(text)) return '';

  if (/\bexecute_done\b/.test(text)) {
    const meta = sidebarRunMeta.get(dubID) || sidebarRunMeta.get(filePath) || {};
    const displayAction = action || meta.action || 'recorded';
    const displayFile = filePath || meta.filePath || dubID || '';
    const displayTask = task || meta.task || '';
    return `${at}RECORDED ${displayAction}${displayFile ? ` — ${displayFile}` : ''}${displayTask ? ` · ${displayTask}` : ''} ✓`;
  }

  if (/\bexecute_failure_detected\b|\bexecute_error_surfaced\b/.test(text)) {
    const meta = sidebarRunMeta.get(dubID) || sidebarRunMeta.get(filePath) || {};
    const error = logTextAfter(text, 'error') || logTextAfter(text, 'rawError') || 'recorder error';
    const displayAction = action || meta.action || 'record';
    const displayFile = filePath || meta.filePath || '';
    const displayTask = task || meta.task || '';
    return `${at}RECORDER ERROR ${displayAction}${displayFile ? ` — ${displayFile}` : ''}${displayTask ? ` · ${displayTask}` : ''} ✗ · ${error}`;
  }

  if (/\btypecheck_clear\b/.test(text)) return `${at}TYPECHECK clear`;

  if (/\btypecheck_issues_detected\b/.test(text)) {
    const count = logValue(text, 'issueCount') || '0';
    return `${at}TYPECHECK issues · ${count}`;
  }

  if (/\btypecheck_unparsed_failure\b/.test(text)) {
    const excerpt = logTextAfter(text, 'outputExcerpt') || 'no parsed diagnostics';
    return `${at}TYPECHECK failed · ${excerpt}`;
  }

  if (/\bauto_project_backup_created\b/.test(text)) {
    const slot = logValue(text, 'slot');
    const name = logValue(text, 'restoreName');
    return `${at}BACKUP CREATED${slot ? ` ${slot}` : ''}${name ? ` — ${name}` : ''}`;
  }

  if (/\bshutdown_requested\b/.test(text)) return `${at}SHUTDOWN requested`;
  if (/\bserver_started\b/.test(text)) return `${at}SERVER started`;
  if (/\bboot_auth_complete\b/.test(text)) return `${date && time ? `${date} ${time} ` : at}AUTH ready`;
  if (/\bstartup_mode_resolved\b/.test(text)) return `${at}STARTUP ready`;

  return `${at}${text.replace(/^\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\s+/, '').replace(/\s+/g, ' ')}`;
}
function renderSidebarSystemLines(lines) {
  const host = byId('log-window') || byId('system-log');
  if (!host) return;
  const rawList = Array.isArray(lines) ? lines.filter(Boolean).slice(0, 240).reverse() : [];
  const list = [];
  for (const raw of rawList) {
    const compact = compactSidebarSystemLine(raw);
    if (!compact) continue;
    if (compact === list[list.length - 1]) continue;
    list.push(compact);
  }
  const visible = list.slice(-90);
  host.innerHTML = '';
  if (!visible.length) {
    const empty = document.createElement('div');
    empty.id = 'log-placeholder';
    empty.textContent = 'Waiting for useful system activity…';
    host.appendChild(empty);
    return;
  }
  logLines = [];
  visible.forEach(line => appendLog(line, logTone(line)));
}
async function readSidebarSystemLog() {
  if (window.__visualizerSystemLogTakeover) return;
  const data = await api('/logs/system?limit=240');
  if (!data?.ok) return;
  const lines = Array.isArray(data.lines) ? data.lines : [];
  const newest = lines[0] || '';
  if (!systemLogSeeded) {
    systemLogSeeded = true;
    lastSidebarLine = newest;
    renderSidebarSystemLines(lines);
    return;
  }
  if (newest && newest !== lastSidebarLine) {
    lastSidebarLine = newest;
    renderSidebarSystemLines(lines);
  }
}

async function readStatus() {
  const data = await api('/status');
  if (!data?.ok) {
    deckOnline = false;
    appendLog(`status unavailable: ${data?.message || data?.error || 'unknown'}`, 'fail');
    return data;
  }
  deckOnline = true;
  recorderRunning = data.state === 'RECORD' || data.busy === true;
  const status = byId('monitor-status');
  if (status) status.textContent = recorderRunning ? '● RECORD' : data.paused ? '● PAUSE' : '● IDLE';
  if (typeof syncLeds === 'function') syncLeds();
  await readSidebarSystemLog();
  return data;
}

function startPolling() {
  if (pollTimer) return;
  pollTimer = setInterval(async () => {
    if (pollBusy) return;
    pollBusy = true;
    try {
      pollCycle += 1;
      await readStatus();
      if (pollCycle % 2 === 0) await readDubs();
      // History panels are refreshed by tab changes and refresh buttons, not polling; polling repaint caused log flashes.
    } finally {
      pollBusy = false;
    }
  }, 1800);
}

async function syncAll() {
  await readStatus();
  await readDubs();
  await readTape();
}

on('log-clear', 'click', () => {
  logLines = [];
  const host = byId('log-window') || byId('system-log');
  if (host) host.innerHTML = '<div id="log-placeholder">Waiting for system activity…</div>';
});

// ── EQ CANVAS ─────────────────────────────────────────────────────────────────

let canvas = null;
let ctx2d = null;
const BARS = 18;
const EQ_SEGMENTS = 13;
let eqH = Array.from({ length: BARS }, () => Math.random() * 0.22);
let eqT = Array.from({ length: BARS }, () => Math.random() * 0.26);
let eqSequence = null;
let eqSustain = null;
let lastCompletedDubKey = '';
let studioNeedleLeftAngle = -34;
let studioNeedleRightAngle = -32;
let studioNeedleLeftTarget = -34;
let studioNeedleRightTarget = -32;
let studioNeedleNextTargetAt = 0;

const EQ_SEQUENCE_LIBRARY = {
  run: [
    { energy: 'X', volume: 'max', ms: 800 },
    { energy: 'MH', volume: 'loud', ms: 4000 },
    { energy: 'M', volume: 'standard', ms: 4500 }
  ],
  record: [
    { energy: 'X', volume: 'max', ms: 800 },
    { energy: 'MH', volume: 'loud', ms: 4000 },
    { energy: 'M', volume: 'standard', ms: 4500 }
  ],
  chat: [
    { energy: 'M', volume: 'standard', ms: 4500 }
  ],
  readfile: [
    { energy: 'M', volume: 'standard', ms: 4500 }
  ],
  approve: [
    { energy: 'M', volume: 'standard', ms: 4500 }
  ],
  singleAction: [
    { energy: 'M', volume: 'standard', ms: 4500 }
  ],
  settleMedium: [
    { energy: 'M', volume: 'standard', ms: 4500 }
  ],
  settleLow: [
    { energy: 'LOW', volume: 'soft', ms: 1800 }
  ]
};
function startEQSequence(name, sustain = null) {
  const phases = EQ_SEQUENCE_LIBRARY[name];
  if (!Array.isArray(phases) || !phases.length) return;
  eqSequence = { name, phases, startedAt: Date.now(), sustain };
  eqSustain = sustain;
}

function clearEQSustain(reason = '') {
  if (!reason || eqSustain === reason) eqSustain = null;
}

function getEQSequencePhase() {
  if (!eqSequence) return null;
  const elapsed = Date.now() - eqSequence.startedAt;
  let cursor = 0;
  for (const phase of eqSequence.phases) {
    cursor += Math.max(0, Number(phase.ms) || 0);
    if (elapsed <= cursor) return phase;
  }
  eqSequence = null;
  return null;
}

function triggerEQActivity(level = 'medium') {
  const normalized = String(level || '').toLowerCase();
  if (normalized === 'run' || normalized === 'record') return startEQSequence('run', null);
  if (normalized === 'chat') return startEQSequence('chat', 'chat');
  if (normalized === 'readfile') return startEQSequence('readfile', null);
  if (normalized === 'approve') return startEQSequence('approve', null);
  if (normalized === 'low') return startEQSequence('settleLow', null);
  if (normalized === 'high') return startEQSequence('run', null);
  return startEQSequence('singleAction', null);
}
function getEQActivity() {
  const phase = getEQSequencePhase();
  if (phase) return phase;
  if (!deckOnline) return { energy: 'DEAD', volume: 'dead' };
  if (recorderRunning) return { energy: 'H', volume: 'max' };
  if (aiEngaged) return { energy: 'M', volume: 'standard' };
  if (eqSustain === 'record') return { energy: 'H', volume: 'max' };
  if (eqSustain === 'chat') return { energy: 'M', volume: 'standard' };
  if (eqSustain === 'approve') return { energy: 'M', volume: 'standard' };
  return { energy: 'L', volume: 'soft' };
}
function resolveStudioNeedleProfile(energy) {
  if (energy === 'DEAD') return { base: 0, swing: 0, speed: 0.18, interval: 1000, exponent: 4.0, rare: 0 };
  if (energy === 'X') return { base: 8, swing: 30, speed: 0.105, interval: 250, exponent: 1.45, rare: 0.018 };
  if (energy === 'H') return { base: 2, swing: 26, speed: 0.095, interval: 300, exponent: 1.55, rare: 0.014 };
  if (energy === 'MH') return { base: -8, swing: 22, speed: 0.084, interval: 400, exponent: 1.7, rare: 0.010 };
  if (energy === 'M') return { base: -16, swing: 18, speed: 0.076, interval: 470, exponent: 1.9, rare: 0.008 };
  if (energy === 'LOW') return { base: -28, swing: 12, speed: 0.052, interval: 840, exponent: 2.15, rare: 0.007 };
  return { base: -34, swing: 9, speed: 0.044, interval: 1040, exponent: 2.75, rare: 0.002 };
}
function nextStudioNeedleAngle(profile, sideOffset = 0) {
  const leftBias = Math.pow(Math.random(), profile.exponent);
  const rarePush = Math.random() < profile.rare ? Math.random() * profile.swing * 0.42 : 0;
  return profile.base + sideOffset + leftBias * profile.swing + rarePush;
}

function updateStudioNeedles(activity) {
  if (document.body?.dataset?.skin !== 'studio') return;
  const left = document.querySelector('.StudioNeedle-Eo.needle-left');
  const right = document.querySelector('.StudioNeedle-Eo.needle-right');
  if (!left || !right) return;

  const profile = resolveStudioNeedleProfile(String(activity?.energy || 'L'));
  const now = Date.now();
  if (now >= studioNeedleNextTargetAt) {
    studioNeedleLeftTarget = nextStudioNeedleAngle(profile, -1.5);
    studioNeedleRightTarget = nextStudioNeedleAngle(profile, 1.5);
    studioNeedleNextTargetAt = now + profile.interval + Math.random() * profile.interval;
  }

  studioNeedleLeftAngle += (studioNeedleLeftTarget - studioNeedleLeftAngle) * profile.speed;
  studioNeedleRightAngle += (studioNeedleRightTarget - studioNeedleRightAngle) * profile.speed;

  left.style.setProperty('--studio-needle-left', `${studioNeedleLeftAngle.toFixed(2)}deg`);
  right.style.setProperty('--studio-needle-right', `${studioNeedleRightAngle.toFixed(2)}deg`);
}

function eqBarColor(volume, ratio) {
  const pulse = Math.max(0, Math.min(1, Number(volume || 0)));
  const r = Math.max(0, Math.min(1, Number(ratio || 0)));

  if (r >= 0.85) return pulse > 0.5 ? '#ff4d00' : '#ff7a3d';
  if (r >= 0.65) return pulse > 0.5 ? '#ffb300' : '#d9ff1c';
  if (r >= 0.40) return pulse > 0.5 ? '#d9ff1c' : '#76ff1f';
  return pulse > 0.5 ? '#18ff3a' : '#57d95d';
}
function eqTick() {
  if (!canvas) canvas = byId('eq-canvas');
  if (!ctx2d && canvas) ctx2d = canvas.getContext('2d');
  if (!canvas || !ctx2d) {
    requestAnimationFrame(eqTick);
    return;
  }
  const nextWidth = Math.max(1, Math.floor(canvas.offsetWidth || canvas.clientWidth || 1));
  const nextHeight = Math.max(1, Math.floor(canvas.offsetHeight || canvas.clientHeight || 1));
  if (canvas.width !== nextWidth) canvas.width = nextWidth;
  if (canvas.height !== nextHeight) canvas.height = nextHeight;

  const activity = getEQActivity();
  updateStudioNeedles(activity);
  const { energy, volume } = activity;
  const range = energy === 'DEAD'
    ? { min: 0, max: 0 }
    : energy === 'X'
      ? { min: 0.82, max: 1.0 }
      : energy === 'H'
        ? { min: 0.62, max: 0.92 }
        : energy === 'MH'
          ? { min: 0.46, max: 0.76 }
          : energy === 'M'
            ? { min: 0.26, max: 0.44 }
            : energy === 'LOW'
              ? { min: 0.04, max: 0.14 }
              : { min: 0.035, max: 0.16 };

  const w = canvas.width;
  const h = canvas.height;
  const padX = 0;
  const padTop = 0;
  const padBottom = 0;
  const gap = 2;
  const segmentHeight = 4;
  const segmentGap = 2;
  const drawW = Math.max(1, w - padX * 2);
  const barW = Math.max(1, (drawW - gap * (BARS - 1)) / BARS);

  ctx2d.clearRect(0, 0, w, h);

  for (let i = 0; i < BARS; i++) {
    const jitter = energy === 'H' || energy === 'X' ? 0.18 : energy === 'M' ? 0.11 : 0.05;
    if (Math.random() < 0.08 + jitter) eqT[i] = range.min + Math.random() * (range.max - range.min);
    eqH[i] += (eqT[i] - eqH[i]) * (energy === 'H' || energy === 'X' ? 0.24 : energy === 'M' ? 0.18 : 0.1);

    const ratio = energy === 'DEAD' ? 0 : Math.max(0.03, Math.min(1, eqH[i]));
    const segments = energy === 'DEAD' ? 0 : Math.max(1, Math.min(EQ_SEGMENTS, Math.round(ratio * EQ_SEGMENTS)));
    const x = padX + i * (barW + gap);

    for (let s = 0; s < segments; s++) {
      const y = h - padBottom - ((s + 1) * (segmentHeight + segmentGap));
      if (y < padTop) continue;
      const visibleRows = Math.max(1, Math.min(segments, Math.floor((h - padTop - padBottom) / (segmentHeight + segmentGap))));
      const fullBlast = visibleRows >= Math.max(5, Math.round(EQ_SEGMENTS * 0.52));
      const capRows = fullBlast ? 1 : 0;
      const isCap = capRows > 0 && s >= visibleRows - capRows;
      const segRatio = isCap ? 0.92 : fullBlast ? (s + 1) / Math.max(visibleRows, 1) : s / Math.max(segments, 1);
      ctx2d.fillStyle = eqBarColor(isCap ? 'loud' : volume, segRatio);
      ctx2d.globalAlpha = volume === 'max' ? 0.96 : volume === 'loud' ? 0.9 : 0.78;
      ctx2d.fillRect(x, y, Math.max(1, barW - gap), segmentHeight);
    }
  }

  ctx2d.globalAlpha = 1;
  requestAnimationFrame(eqTick);
}

// ── BOOT INTERFACE RUNNERS ───────────────────────────────────────────────────

function bindStack() {
  const left = byId('left');
  const screw = byId('screw-adjustment');

  if (!left || !screw || screw.dataset.wired === 'true') return;
  screw.dataset.wired = 'true';

  screw.onmousedown = event => {
    event.preventDefault();

    const startMouseY = event.clientY;
    const startMiddleY = parseFloat(getComputedStyle(left).getPropertyValue('--middle-y')) || 215;

    document.onmousemove = event => {
      left.style.setProperty('--middle-y', `${startMiddleY + event.clientY - startMouseY}px`);
    };

    document.onmouseup = () => {
      document.onmousemove = null;
      document.onmouseup = null;
    };
  };
}
function bootStack() {
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', bindStack, { once: true });
    return;
  }
  bindStack();
}

bootStack();

// ── BROWSER CLOSE / POWERDOWN BRIDGE ────────────────────────────────────────

function browserClientId() {
  try {
    const key = 'nv-browser-client-id';
    const existing = sessionStorage.getItem(key);
    if (existing) return existing;
    const id = `browser-${Date.now()}-${Math.random().toString(36).slice(2)}`;
    sessionStorage.setItem(key, id);
    return id;
  } catch {
    return `browser-${Date.now()}-${Math.random().toString(36).slice(2)}`;
  }
}

function postShutdownSignal(path, payload, keepalive = false) {
  const body = JSON.stringify(payload || {});
  try {
    return fetch(DECK_URL + path, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body,
      keepalive
    }).catch(() => null);
  } catch {
    return null;
  }
}

function initBrowserCloseShutdownBridge() {
  if (window.__nvBrowserShutdownBridge) return;
  window.__nvBrowserShutdownBridge = true;

  const clientId = browserClientId();
  const heartbeat = () => postShutdownSignal('/shutdown/browser-heartbeat', {
    clientId,
    href: location.href,
    visibility: document.visibilityState || 'visible',
    ts: Date.now()
  });

  heartbeat();
  const heartbeatTimer = setInterval(heartbeat, 2500);

  document.addEventListener('visibilitychange', () => {
    if (document.visibilityState === 'visible') heartbeat();
  });

  window.addEventListener('pageshow', () => heartbeat());

  window.addEventListener('pagehide', event => {
    clearInterval(heartbeatTimer);
    postShutdownSignal('/shutdown/browser-gone', {
      clientId,
      reason: event.persisted ? 'pagehide_bfcache' : 'browser_pagehide',
      href: location.href,
      ts: Date.now()
    }, true);
  });
}

function renderSettingsProjectRow(project) {
  const name = esc(project?.name || 'Untitled Project');
  const serial = esc(project?.serialNo || 'no-serial');
  const location = esc(project?.location || project?.path || '');
  return `
    <div class="settings-project-row" data-project-serial="${serial}" data-project-name="${name}" data-project-location="${location}" style="display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;align-items:center;border:1px solid var(--border2);border-radius:8px;padding:8px;background:var(--bg2)">
      <div style="min-width:0">
        <div style="font-size:13px;color:var(--text1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis">${name}</div>
        <div style="font-size:11px;color:var(--text3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis">Serial: ${serial}</div>
        <div style="font-size:11px;color:var(--text2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis">Location: ${location}</div>
      </div>
      <button class="inp-btn settings-project-edit-btn" type="button">EDIT</button>
    </div>
  `;
}

async function refreshSettingsProjectsList() {
  const host = byId('settings-projects-list');
  if (!host) return;
  const data = await api('/projects');
  const projects = Array.isArray(data?.projects) ? data.projects.filter(project => {
    const name = String(project?.name || '').trim().toLowerCase();
    return name && !['system', 'backstage', 'universal'].includes(name);
  }) : [];

  host.innerHTML = projects.length
    ? projects.map(renderSettingsProjectRow).join('')
    : '<div style="font-size:12px;color:var(--text3)">No projects registered yet.</div>';

  host.querySelectorAll('.settings-project-edit-btn').forEach(button => {
    button.addEventListener('click', async () => {
      const row = button.closest('.settings-project-row');
      const currentName = String(row?.dataset?.projectName || '').trim();
      const currentLocation = String(row?.dataset?.projectLocation || '').trim();
      const nextName = String(prompt('Project name', currentName) || '').trim();
      if (!nextName) return;
      const nextLocation = String(prompt('Project location / folder', currentLocation) || '').trim();
      if (!nextLocation) return;

      let activeName = currentName;
      if (nextName !== currentName) {
        const rename = await api('/projects/rename', 'POST', { currentName, nextName });
        if (!rename?.ok) {
          toast(rename?.message || rename?.error || 'Project rename failed');
          return;
        }
        activeName = String(rename.project?.name || nextName).trim();
      }

      if (nextLocation !== currentLocation) {
        const moved = await api('/projects/repair-location', 'POST', { name: activeName, location: nextLocation });
        if (!moved?.ok || !moved.project) {
          toast(moved?.message || moved?.error || 'Project folder update failed');
          return;
        }
      }

      toast('Project identity updated');
      await refreshSettingsProjectsList();
      await window.MonitorProject?.loadProjectSelector?.();
      await window.reloadProjectOutlineFromFile?.();
    });
  });
}

async function initSettingsProjectIdentityUI() {
  await refreshSettingsProjectsList();
}

async function initRecorderSettingsUI() {
  const select = byId('set-recorder-shell-access');
  if (!select || select.dataset.wired === 'true') return;
  select.dataset.wired = 'true';

  const readMode = value => ['deny', 'standard', 'extended'].includes(String(value || '').trim()) ? String(value || '').trim() : 'deny';
  const settings = await SettingsStore.load();
  select.value = readMode(settings?.recorder?.shellAccess);

  select.addEventListener('change', async () => {
    const mode = readMode(select.value);
    const result = await SettingsStore.save({ recorder: { shellAccess: mode } });
    if (result?.ok) {
      toast(`Shell Commands: ${mode}`);
      appendLog(`⚙ recorder shell access → ${mode}`, 'neutral');
    } else {
      toast('Shell setting save failed');
    }
  });
}

function initStandaloneAccountControls() {
  on('account-open-window-btn', 'click', () => openAccountPortalWindow());
  on('account-refresh-btn', 'click', () => void refreshAuthFromPortal());
  on('agreement-open-account-btn', 'click', () => openAccountPortalWindow());
  on('agreement-refresh-auth-btn', 'click', () => void acceptAgreementFromStatus());
}

function initStandaloneAccountControls() {
  on('account-open-window-btn', 'click', () => openAccountPortalWindow());
  on('account-refresh-btn', 'click', () => void refreshAuthFromPortal());
  on('agreement-open-account-btn', 'click', () => openAccountPortalWindow());
  on('agreement-refresh-auth-btn', 'click', () => void acceptAgreementFromStatus());
}

function wireStandaloneAccountControls() {
  on('account-open-window-btn', 'click', () => {
    if (typeof openStandaloneAccountWindow === 'function') openStandaloneAccountWindow();
    else window.open(`${ACCOUNT_PORTAL_URL}?source=verbatim`, '_blank', 'noopener,noreferrer');
  });
  on('account-refresh-btn', 'click', async () => {
    const auth = await syncAccount();
    toast(auth?.status === 'signed_in' ? 'Account status refreshed' : 'Signed out');
  });
}

const VERBATIM_SKINS = {
  cruise: {
    frame: '/assets/cruiseframe.png',
    bgPanel: '/assets/cruisebgpanel.png',
    bgPanel2: '/assets/cruisebgpanel2.png',
    panel: '/assets/cruisepanel.png',
    buttons: '/assets/cruisebuttons.png',
    buttonFrame: '/assets/cruisebuttonframe.png',
    levels: '/assets/studiolevels.png'
  },
  studio: {
    frame: '/assets/studioframe.png',
    bgPanel: '/assets/studiobgpanel.png',
    bgPanel2: '/assets/studiobgpanel2.png',
    panel: '/assets/studiopanel.png',
    buttons: '/assets/studiobuttons.png',
    buttonFrame: '/assets/studiobuttonframe.png',
    levels: '/assets/studiolevels.png'
  }
};

function loadVerbatimSkin() {
  try {
    return localStorage.getItem('verbatim.skin') === 'cruise' ? 'cruise' : 'studio';
  } catch {
    return 'studio';
  }
}

function saveVerbatimSkin(skin) {
  try { localStorage.setItem('verbatim.skin', skin); } catch {}
}

function applyVerbatimSkin(skin) {
  const next = skin === 'cruise' ? 'cruise' : 'studio';
  const assets = VERBATIM_SKINS[next];
  document.body.dataset.skin = next;
  document.documentElement.style.setProperty('--verbatim-bg-panel', `url("${assets.bgPanel}")`);
  document.documentElement.style.setProperty('--verbatim-bg-panel-2', `url("${assets.bgPanel}")`);
  document.documentElement.style.setProperty('--verbatim-lcd-panel', `url("${assets.panel}")`);
  document.documentElement.style.setProperty('--verbatim-button-frame', `url("${assets.buttonFrame}")`);
  const frame = document.querySelector('#monitor-wrap .Frame-Eo');
  const levels = document.querySelector('#monitor-wrap .StudioLevels-Eo');
  const buttons = document.getElementById('deck-fullbar');
  if (frame) frame.src = assets.frame;
  if (levels) levels.src = assets.levels;
  if (buttons) buttons.src = assets.buttons;
}

function initVerbatimSkin() {
  applyVerbatimSkin(loadVerbatimSkin());
  const toggle = byId('verbatim-skin-toggle');
  if (!toggle || toggle.dataset.wired === 'true') return;
  toggle.dataset.wired = 'true';
  toggle.addEventListener('click', () => {
    const next = document.body.dataset.skin === 'studio' ? 'cruise' : 'studio';
    applyVerbatimSkin(next);
    saveVerbatimSkin(next);
  });
}

window.VerbatimPanels = {
  async refreshAfterProjectSwitch(projectState = null) {
    selectedDubIndex = -1;
    selectedDubManifest = null;
    expandedDubKey = null;
    selectedTapeIndex = -1;
    selectedSystemGroupIdx = -1;
    selectedProjectUnitIndex = -1;

    if (window.ProjectOutline?.loadProject) await window.ProjectOutline.loadProject();
    if (window.__reloadEditorProjectScope) await window.__reloadEditorProjectScope();
    await readStatus();
    await readDubs();
    await readTape();
    if (document.querySelector('#tabs [data-tab="history"].active')) await refreshActiveHistory();
    if (typeof refreshSettingsProjectsList === 'function') await refreshSettingsProjectsList();
  }
};

function bootStation() {
  if (window.__nvMonitorUIBooted) return;
  window.__nvMonitorUIBooted = true;

  try { initVerbatimSkin(); } catch {}
  try { hidePort(); } catch {}
  try { initBrowserCloseShutdownBridge(); } catch {}
  try { if (typeof wireLaunchGateControls === 'function') wireLaunchGateControls(); } catch {}
  try { bindStandaloneAccountControls(); } catch {}
  try { if (typeof bootLaunchGate === 'function') void bootLaunchGate(); } catch {}
  try { void readStatus(); } catch {}
  try { void readDubs(); } catch {}
  try { void readTape(); } catch {}
  try { void initRecorderSettingsUI(); } catch {}
  try { initAccountPortalUI(); } catch {}
  try { void initSettingsProjectIdentityUI(); } catch {}
  try { wireStandaloneAccountControls(); } catch {}
  try { initStandaloneAccountControls(); } catch {}
  try { initStandaloneAccountControls(); } catch {}
  try { void window.MonitorProject?.loadProjectSelector?.(); } catch {}
  try { startPolling(); } catch {}
  try { eqTick(); } catch {}
}

if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', bootStation, { once: true });
} else {
  bootStation();
}