import { renderDashboardNav } from "./web-dashboard-ui.js";
const faviconLinks = `
  <link rel="icon" href="/favicon.ico" sizes="any">
  <link rel="icon" type="image/png" href="/assets/favicon.png">
  <link rel="apple-touch-icon" href="/assets/logo.png">
  <link rel="manifest" href="/manifest.webmanifest">
  <meta name="theme-color" content="#205c43">`;
export function renderLoginPage(options) {
    const nonce = nonceAttr(options.cspNonce);
    return `<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>NordRelay Login</title>
${faviconLinks}
  <style${nonce}>
    body{margin:0;min-height:100vh;display:grid;place-items:center;background:#f4f5f2;color:#181c19;font-family:Inter,system-ui,-apple-system,Segoe UI,sans-serif}
    form{width:min(420px,calc(100vw - 32px));background:white;border:1px solid #dfe3dc;border-radius:8px;padding:24px;box-shadow:0 20px 60px rgba(20,30,24,.08)}
    h1{font-size:24px;margin:0 0 8px}
    p{color:#5d665d;margin:0 0 18px}
    label{display:block;font-size:13px;color:#4b544d;margin:14px 0 6px}
    input{box-sizing:border-box;width:100%;height:40px;border:1px solid #cfd6ce;border-radius:6px;padding:0 10px;font:inherit}
    button{margin-top:18px;width:100%;height:42px;border:0;border-radius:6px;background:#205c43;color:white;font-weight:650;cursor:pointer}
    button.secondary{background:#eef2ed;color:#205c43;border:1px solid #cfd6ce}
    .mfa{display:none;margin-top:18px;border-top:1px solid #e5e9e3;padding-top:18px}
    .mfa.active{display:block}
    .row{display:flex;gap:10px}
    .row button{flex:1}
    .error{color:#9b1c1c;min-height:22px;margin-top:12px}
  </style>
</head>
<body>
  <form id="login">
    <h1>NordRelay Dashboard</h1>
    <p>${options.adminConfigured ? "Sign in with your NordRelay user account." : "No admin user exists. Run nordrelay user create-admin on this host first."}</p>
    <label>Email</label><input id="email" name="email" type="email" autocomplete="username" ${options.adminConfigured ? "" : "disabled"}>
    <label>Password</label><input id="password" name="password" type="password" autocomplete="current-password" ${options.adminConfigured ? "" : "disabled"}>
    <button ${options.adminConfigured ? "" : "disabled"}>Sign in</button>
    <div id="mfaBox" class="mfa">
      <p>Enter an authenticator or recovery code to finish signing in.</p>
      <label>Authenticator or recovery code</label><input id="mfaCode" autocomplete="one-time-code">
      <div class="row"><button type="button" id="mfaSubmit">Verify code</button><button type="button" id="passkeySubmit" class="secondary">Use passkey</button></div>
    </div>
    <div class="error" id="error"></div>
  </form>
  <script${nonce}>
    let mfaChallengeId = '';
    let webAuthnOptions = null;
    document.getElementById('login').addEventListener('submit', async (event) => {
      event.preventDefault();
      document.getElementById('error').textContent = '';
      const payload = {
        email: document.getElementById('email')?.value || undefined,
        password: document.getElementById('password')?.value || undefined,
      };
      const res = await fetch('/api/auth', { method:'POST', headers:{'content-type':'application/json'}, body: JSON.stringify(payload) });
      const data = await readJson(res);
      if (!res.ok) {
        document.getElementById('error').textContent = data.error || 'Invalid credentials';
        return;
      }
      if (data.mfaRequired) {
        mfaChallengeId = data.challengeId || '';
        webAuthnOptions = data.webAuthnOptions || null;
        document.getElementById('mfaBox').classList.add('active');
        document.getElementById('passkeySubmit').hidden = !webAuthnOptions;
        document.getElementById('mfaCode').focus();
        if (webAuthnOptions && window.PublicKeyCredential) {
          try { await finishPasskeyLogin(); } catch {}
        }
        return;
      }
      location.href = '/';
    });
    document.getElementById('mfaSubmit').addEventListener('click', finishCodeLogin);
    document.getElementById('passkeySubmit').addEventListener('click', finishPasskeyLogin);
    async function finishCodeLogin() {
      const res = await fetch('/api/auth/mfa', { method:'POST', headers:{'content-type':'application/json'}, body: JSON.stringify({ challengeId:mfaChallengeId, code:document.getElementById('mfaCode').value }) });
      const data = await readJson(res);
      if (!res.ok) { document.getElementById('error').textContent = data.error || 'Verification failed'; return; }
      location.href = '/';
    }
    async function finishPasskeyLogin() {
      if (!webAuthnOptions || !navigator.credentials) return;
      const credential = await navigator.credentials.get({ publicKey: publicKeyRequest(webAuthnOptions) });
      const res = await fetch('/api/auth/webauthn/verify', { method:'POST', headers:{'content-type':'application/json'}, body: JSON.stringify({ challengeId:mfaChallengeId, response:credentialToJson(credential) }) });
      const data = await readJson(res);
      if (!res.ok) { document.getElementById('error').textContent = data.error || 'Passkey verification failed'; return; }
      location.href = '/';
    }
    async function readJson(res){ try{return await res.json()}catch{return {}} }
    function publicKeyRequest(options) {
      return { ...options, challenge:b64ToBuf(options.challenge), allowCredentials:(options.allowCredentials||[]).map(c=>({...c,id:b64ToBuf(c.id)})) };
    }
    function credentialToJson(credential) {
      return {
        id: credential.id,
        rawId: bufToB64(credential.rawId),
        type: credential.type,
        response: {
          authenticatorData: bufToB64(credential.response.authenticatorData),
          clientDataJSON: bufToB64(credential.response.clientDataJSON),
          signature: bufToB64(credential.response.signature),
          userHandle: credential.response.userHandle ? bufToB64(credential.response.userHandle) : undefined,
        },
      };
    }
    function b64ToBuf(value){const pad='='.repeat((4-value.length%4)%4);const b64=(value+pad).replace(/-/g,'+').replace(/_/g,'/');const bin=atob(b64);const bytes=new Uint8Array(bin.length);for(let i=0;i<bin.length;i++)bytes[i]=bin.charCodeAt(i);return bytes.buffer}
    function bufToB64(buffer){const bytes=new Uint8Array(buffer);let bin='';for(const b of bytes)bin+=String.fromCharCode(b);return btoa(bin).replace(/\\+/g,'-').replace(/\\//g,'_').replace(/=+$/,'')}
  </script>
</body>
</html>`;
}
export function renderFirstRunSetupPage(options) {
    const nonce = nonceAttr(options.cspNonce);
    return `<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>NordRelay First Run</title>
${faviconLinks}
  <style${nonce}>
    body{margin:0;min-height:100vh;display:grid;place-items:center;background:#f4f5f2;color:#181c19;font-family:Inter,system-ui,-apple-system,Segoe UI,sans-serif}
    form{width:min(460px,calc(100vw - 32px));background:white;border:1px solid #dfe3dc;border-radius:8px;padding:24px;box-shadow:0 20px 60px rgba(20,30,24,.08)}
    h1{font-size:24px;margin:0 0 8px}
    p{color:#5d665d;margin:0 0 18px;line-height:1.45}
    label{display:block;font-size:13px;color:#4b544d;margin:14px 0 6px}
    input{box-sizing:border-box;width:100%;height:40px;border:1px solid #cfd6ce;border-radius:6px;padding:0 10px;font:inherit}
    button{margin-top:18px;width:100%;height:42px;border:0;border-radius:6px;background:#205c43;color:white;font-weight:650;cursor:pointer}
    .error{color:#9b1c1c;min-height:22px;margin-top:12px}
    small{display:block;color:#667267;margin-top:8px;line-height:1.4}
  </style>
</head>
<body>
  <form id="setup">
    <h1>NordRelay Setup</h1>
    <p>Create the first admin account. After this, every dashboard page and API route requires login.</p>
    <label>Email</label><input id="email" name="email" type="email" autocomplete="username" required>
    <label>Name</label><input id="displayName" name="displayName" autocomplete="name" required>
    <label>Password</label><input id="password" name="password" type="password" autocomplete="new-password" minlength="12" required>
    <label>Setup token</label><input id="setupToken" name="setupToken" autocomplete="one-time-code" ${options.tokenRequired ? "required" : ""}>
    <small>${options.tokenRequired ? "Use the token printed in the NordRelay console." : "Local setup does not require the token, but the console token also works."}</small>
    <button>Create admin</button>
    <div class="error" id="error"></div>
  </form>
  <script${nonce}>
    document.getElementById('setup').addEventListener('submit', async (event) => {
      event.preventDefault();
      const payload = {
        email: document.getElementById('email')?.value || undefined,
        displayName: document.getElementById('displayName')?.value || undefined,
        password: document.getElementById('password')?.value || undefined,
        setupToken: document.getElementById('setupToken')?.value || undefined,
      };
      const res = await fetch('/api/setup/admin', { method:'POST', headers:{'content-type':'application/json'}, body: JSON.stringify(payload) });
      if (!res.ok) {
        const data = await res.json().catch(() => ({}));
        document.getElementById('error').textContent = data.error || 'Setup failed';
        return;
      }
      location.href = '/';
    });
  </script>
</body>
</html>`;
}
export function renderDashboardApp(options = {}) {
    const nonce = nonceAttr(options.cspNonce);
    const assetVersion = encodeURIComponent(options.assetVersion ?? "dev");
    const dashboardAssetPrefix = `/assets/${assetVersion}`;
    return `<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>NordRelay Dashboard</title>
${faviconLinks}
  <script${nonce}>
    (() => {
      const preference = localStorage.getItem('nordrelayThemePreference') || localStorage.getItem('nordrelayTheme') || 'light';
      const resolved = preference === 'system' && matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : preference === 'dark' ? 'dark' : 'light';
      document.documentElement.dataset.theme = resolved;
    })();
  </script>
  <link rel="stylesheet" href="${dashboardAssetPrefix}/dashboard.css">
</head>
<body>
  <div class="app">
    <aside class="sidebar" id="sidebar">
      <button id="brandHomeBtn" class="brand brand-home" type="button" aria-label="Open overview"><img class="brand-mark" src="/assets/logo.png" alt="" width="44" height="44" aria-hidden="true"><span class="brand-copy"><strong>NordRelay</strong><small>Remote control</small></span></button>
      <div class="brand-separator" aria-hidden="true"></div>
      <nav>
        ${renderDashboardNav()}
      </nav>
    </aside>
    <main>
      <header>
        <div class="header-title">
          <h1 id="pageTitle" class="page-title-heading">Overview</h1>
          <div id="sessionLine" class="header-target-line">Loading session...</div>
        </div>
        <div class="header-actions">
          <div class="account-menu" id="accountMenu">
            <button id="userMenuBtn" class="secondary account-menu-button" type="button" aria-haspopup="menu" aria-expanded="false" title="Account">
              <span id="userMenuInitials" class="account-avatar">?</span>
              <span id="userMenuName">Account</span>
            </button>
            <div id="userMenuPanel" class="account-menu-panel" role="menu" hidden>
              <button id="profileBtn" class="secondary" type="button" role="menuitem">Profile</button>
              <div class="account-menu-group" role="group" aria-label="Theme">
                <button class="secondary" type="button" role="menuitemradio" data-theme-choice="light" aria-checked="false">Theme: Light</button>
                <button class="secondary" type="button" role="menuitemradio" data-theme-choice="dark" aria-checked="false">Theme: Dark</button>
                <button class="secondary" type="button" role="menuitemradio" data-theme-choice="system" aria-checked="false">Theme: System</button>
              </div>
              <button id="logoutBtn" class="secondary" type="button" role="menuitem">Logout</button>
            </div>
          </div>
          <button class="menu" id="menuBtn" type="button" aria-label="Open navigation" aria-expanded="false">
            <span class="menu-icon" aria-hidden="true"></span>
          </button>
        </div>
      </header>
      <div id="apiStateBanner" class="api-state-banner" hidden></div>

      <section class="page active" id="page-overview">
        <div class="metrics" id="metrics"></div>
        <div class="stack">
          <div class="panel">
            <div class="active-sessions-header">
              <h2>Active Sessions <span id="activeSessionsCount" class="active-sessions-count">(0)</span></h2>
              <div id="activeSessionsTarget" class="active-sessions-target"></div>
            </div>
            <div id="activeSessions" class="list"></div>
          </div>
          <div class="overview-adapter-grid">
            <div class="panel"><h2>Agent Adapters</h2><div id="agentAdapters"></div></div>
            <div class="panel"><h2>Chat Adapters</h2><div id="chatAdapters"></div></div>
          </div>
        </div>
      </section>

      <section class="page" id="page-chat">
        <div class="chat-layout tools-hidden" id="chatLayout">
          <div class="panel chat-panel">
            <div id="chatTabs" class="chat-tabs" hidden></div>
            <div class="chat-toolbar">
              <button id="newSessionBtn">New session</button>
              <div class="template-picker-menu" data-template-picker-menu>
                <button id="templatePickerBtn" class="secondary" type="button" aria-haspopup="menu" aria-expanded="false">Templates</button>
                <div id="templatePickerMenu" class="control-menu-list header-target-list template-picker-list" role="menu" hidden>
                  <div class="header-target-session-state">Loading templates...</div>
                </div>
              </div>
              <button id="notifyBtn" class="secondary icon-button notify-toggle" type="button" aria-label="Enable notifications" aria-pressed="false" title="Enable notifications">
                <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
                  <path class="notify-outline" d="M18 8a6 6 0 0 0-12 0c0 7-3 8-3 8h18s-3-1-3-8M13.7 21a2 2 0 0 1-3.4 0" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                  <path class="notify-filled" d="M12 3a6 6 0 0 0-6 6c0 4.7-1.5 6.2-2.6 6.9A1 1 0 0 0 4 18h16a1 1 0 0 0 .6-2.1C19.5 15.2 18 13.7 18 9a6 6 0 0 0-6-6Zm2 17h-4a2 2 0 0 0 4 0Z" fill="currentColor"/>
                </svg>
              </button>
              <button id="soundBtn" class="secondary icon-button sound-toggle" type="button" aria-label="Enable completion sound" aria-pressed="false" title="Enable completion sound">
                <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
                  <path class="sound-outline" d="M11 5 6.5 9H3v6h3.5L11 19V5Zm4.5 4.5a4 4 0 0 1 0 5M18 7a7 7 0 0 1 0 10" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
                  <path class="sound-filled" d="M11.6 4.2a1 1 0 0 0-1.1.2L6.1 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h3.1l4.4 3.6A1 1 0 0 0 12 19V5a1 1 0 0 0-.4-.8Zm4.4 4.1a1 1 0 0 0-1.4 1.4 3.2 3.2 0 0 1 0 4.6 1 1 0 1 0 1.4 1.4 5.2 5.2 0 0 0 0-7.4Zm3-2.8a1 1 0 0 0-1.4 1.4 7.2 7.2 0 0 1 0 10.2 1 1 0 1 0 1.4 1.4 9.2 9.2 0 0 0 0-13Z" fill="currentColor"/>
                </svg>
              </button>
              <div class="chat-more-menu">
                <button id="chatMoreBtn" class="secondary chat-more-toggle" type="button" aria-haspopup="menu" aria-expanded="false">More</button>
                <div id="chatMoreMenu" class="control-menu-list chat-more-list" role="menu" hidden>
                  <button id="clearChatBtn" class="secondary" type="button" role="menuitem" title="Clears only the WebUI chat history shown for this session. Agent context and session history stay intact.">Clear</button>
                  <button id="syncBtn" class="secondary" type="button" role="menuitem" title="Sync the current WebUI session controls from the active agent session.">Sync</button>
                  <button id="toggleToolsBtn" class="secondary" type="button" role="menuitem" aria-controls="toolPanel" aria-expanded="false" title="Show or hide the Tools / Plan sidebar for the current chat.">Show Tools</button>
                  <button id="toggleHistoryBtn" class="secondary" type="button" role="menuitem" aria-controls="toolPanel" aria-expanded="false" title="Show or hide the prompt history sidebar for the current chat.">Show History</button>
                </div>
              </div>
            </div>
            <div class="control-grid" id="sessionControls"></div>
            <div class="chat-messages-wrap">
              <div id="messages" class="messages"></div>
              <button id="chatJumpLatestBtn" class="chat-jump-latest" type="button" title="Jump to latest message" aria-label="Jump to latest message" hidden><span aria-hidden="true"></span></button>
            </div>
            <form id="promptForm" class="composer">
              <div class="composer-fields">
                <textarea id="promptInput" placeholder="Send a message to the active coding agent..." rows="3"></textarea>
                <div class="attachment-row">
                  <label class="file-button" for="fileInput">Attach files</label>
                  <input id="fileInput" type="file" multiple>
                  <button type="button" id="recordBtn" class="secondary" title="Requires browser microphone permission. On LAN URLs, browsers require HTTPS; localhost is allowed.">Record voice</button>
                  <span id="fileSummary">No files selected</span>
                  <button type="button" id="clearFilesBtn" class="secondary">Clear</button>
                  <div id="chatWorkspaceLine" class="chat-workspace-line" hidden></div>
                </div>
              </div>
              <div class="composer-actions">
                <button id="sendPromptBtn" type="submit">Send</button>
                <button id="abortBtn" class="secondary composer-abort" type="button" hidden>Abort</button>
              </div>
            </form>
          </div>
          <div class="panel side-panel" id="toolPanel" hidden>
            <h2 id="toolPanelTitle">Tools / Plan</h2>
            <div id="toolStream" class="tool-stream"></div>
            <div id="promptHistoryStream" class="prompt-history-stream" hidden></div>
          </div>
        </div>
      </section>

      <section class="page" id="page-workflows">
        <div class="panel">
          <div class="section-header workflow-section-header">
            <div id="workflowTabs" class="section-tabs workflow-tabs" role="tablist" aria-label="Workflow sections">
              <button type="button" role="tab" aria-selected="true" tabindex="0" data-workflow-tab="templates" class="active">Templates</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-workflow-tab="workflows">Workflows</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-workflow-tab="runs">Runs</button>
            </div>
          </div>
          <div class="workflow-tab active" data-workflow-tab-panel="templates">
            <div class="workflow-tab-heading">
              <div class="row workflow-heading-actions"><button id="reloadWorkflowsBtn" class="secondary">Reload</button><button id="importTemplateBtn" class="secondary">Import template</button><button id="createTemplateBtn">Create template</button></div>
              <div class="workflow-filter-row"><input id="templateSearch" placeholder="Search templates"></div>
            </div>
            <div id="templateList" class="list"></div>
          </div>
          <div class="workflow-tab" data-workflow-tab-panel="workflows">
            <div class="workflow-tab-heading">
              <div class="row workflow-heading-actions"><button id="importWorkflowBtn" class="secondary">Import workflow</button><button id="createWorkflowBtn">Create workflow</button></div>
              <div class="workflow-filter-row"><input id="workflowSearch" placeholder="Search workflows"></div>
            </div>
            <div id="workflowList" class="list"></div>
          </div>
          <div class="workflow-tab" data-workflow-tab-panel="runs">
            <div class="workflow-tab-heading">
              <div class="row workflow-heading-actions"><button id="reloadWorkflowRunsBtn" class="secondary">Reload runs</button></div>
            </div>
            <div id="workflowRunList" class="list"></div>
          </div>
        </div>
      </section>

      <section class="page" id="page-metrics">
        <div class="panel">
          <div class="section-header metrics-section-header">
            <div id="metricsTabs" class="section-tabs metrics-tabs" role="tablist" aria-label="Metrics sections">
              <button type="button" role="tab" aria-selected="true" tabindex="0" data-metrics-tab="overview" class="active">Overview</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-metrics-tab="process">Process</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-metrics-tab="web">Web API</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-metrics-tab="rate">Rate Limits</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-metrics-tab="observability">Observability</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-metrics-tab="history">History</button>
            </div>
          </div>
          <div class="metrics-tab-heading">
            <div class="row metrics-heading-actions">
              <button id="reloadMetricsBtn">Reload metrics</button>
              <label class="metrics-auto-refresh"><input id="metricsAutoRefresh" type="checkbox"> Auto refresh</label>
              <small id="metricsLastUpdated">Last updated -</small>
            </div>
          </div>
          <div id="metricsPanel"></div>
        </div>
      </section>

      <section class="page" id="page-sessions">
        <div class="panel">
          <div class="section-header sessions-section-header">
            <div id="sessionTabs" class="section-tabs session-tabs" role="tablist" aria-label="Session sections">
              <button type="button" role="tab" aria-selected="true" tabindex="0" data-session-tab="sessions" class="active">Sessions</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-session-tab="worktrees">Worktrees</button>
            </div>
          </div>
          <div class="session-tab active" data-session-tab-panel="sessions">
            <div class="sessions-toolbar">
              <div class="row search-row"><input id="sessionSearch" placeholder="Search sessions"><button id="sessionSearchBtn">Search</button></div>
              <div class="row attach-row"><input id="attachInput" placeholder="Thread ID to attach/switch"><button id="attachBtn">Attach</button></div>
            </div>
            <div id="sessionsList" class="sessions-table-host"></div>
            <div id="sessionsPager" class="pager"></div>
          </div>
          <div class="session-tab" data-session-tab-panel="worktrees">
            <div class="sessions-toolbar">
              <div class="row search-row"><button id="reloadWorktreesBtn">Reload worktrees</button><button id="forkWorktreeBtn" class="secondary">Fork current</button><label class="checkbox"><input id="forkIncludeUncommitted" type="checkbox"> Include uncommitted diff</label></div>
              <div class="row attach-row"><button id="integrateWorktreesBtn">Integrate selected</button><button id="previewWorktreeIntegrationBtn" class="secondary">Preview integration</button><button id="compareWorktreesBtn" class="secondary">Compare diffs</button><button id="exportWorktreePatchBtn" class="secondary">Export patches</button><button id="cleanupWorktreesBtn" class="secondary">Cleanup stale</button></div>
            </div>
            <div id="worktreeReviewCenter" class="worktree-review-center"></div>
            <div id="worktreeWarnings" class="list"></div>
            <div id="worktreesList" class="sessions-table-host"></div>
            <div id="worktreeIntegrations" class="list"></div>
          </div>
        </div>
      </section>

      <section class="page" id="page-queue">
        <div class="panel">
          <div class="section-header queue-section-header">
            <div id="queueTabs" class="section-tabs queue-tabs" role="tablist" aria-label="Queue sections">
              <button type="button" role="tab" aria-selected="true" tabindex="0" data-queue-tab="queue" class="active">Queue</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-queue-tab="planner">Planner</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-queue-tab="progress">In Progress</button>
            </div>
          </div>
          <div class="queue-tab active" data-queue-tab-panel="queue">
            <div class="queue-tab-heading">
              <div class="row"><button data-queue="pause">Pause</button><button data-queue="resume">Resume</button><button data-queue="clear" class="danger">Clear</button><span id="queueStatus"></span></div>
            </div>
            <div id="queueList" class="list"></div>
          </div>
          <div class="queue-tab" data-queue-tab-panel="planner">
            <div class="queue-tab-heading">
              <div class="row"><button id="createQueuePlanBtn">Create planned prompt</button><button id="reloadQueuePlansBtn" class="secondary">Reload</button></div>
              <div class="row queue-filter-row"><input id="queuePlanSearch" placeholder="Search planned prompts"></div>
            </div>
            <div id="queuePlannerBoard" class="queue-kanban"></div>
          </div>
          <div class="queue-tab" data-queue-tab-panel="progress">
            <div class="queue-tab-heading">
              <div class="row"><button id="reloadQueueProgressBtn" class="secondary">Reload</button></div>
            </div>
            <div id="queueProgressBoard" class="queue-kanban queue-progress-board"></div>
          </div>
        </div>
      </section>

      <section class="page" id="page-monitor">
        <div class="panel">
          <div class="section-header monitor-section-header">
            <div id="monitorTabs" class="section-tabs monitor-tabs" role="tablist" aria-label="Monitor sections">
              <button type="button" role="tab" aria-selected="true" tabindex="0" data-monitor-tab="activity" data-permission="sessions.read" class="active">Activity</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-monitor-tab="tasks" data-permission="inspect">Tasks</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-monitor-tab="trace" data-permission="sessions.read">Trace</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-monitor-tab="artifacts" data-permission="files.read">Artifacts</button>
            </div>
          </div>
          <div class="monitor-tab active" data-monitor-tab-panel="activity">
            <div class="monitor-tab-heading">
              <button type="button" class="secondary monitor-filter-toggle" data-monitor-filter-toggle="activity" aria-expanded="false"><span class="monitor-filter-arrow" aria-hidden="true">▸</span><span>Filters</span></button>
              <div class="row monitor-filter-content" data-monitor-filter-panel="activity" hidden><select id="activitySource"><option value="all">All sources</option><option value="web">Web</option><option value="telegram">Telegram</option><option value="discord">Discord</option><option value="slack">Slack</option><option value="matrix">Matrix</option><option value="cli">CLI</option></select><select id="activityCategory"><option value="all">All categories</option><option value="prompt">Prompt</option><option value="session">Session</option><option value="queue">Queue</option><option value="agent-update">Agent update</option><option value="artifact">Artifact</option><option value="system">System</option><option value="auth">Auth</option><option value="security">Security</option><option value="tool">Tool</option></select><select id="activityStatus"><option value="all">All statuses</option><option value="queued">Queued</option><option value="running">Running</option><option value="completed">Completed</option><option value="failed">Failed</option><option value="aborted">Aborted</option><option value="info">Info</option></select><input id="activityActor" placeholder="Actor"><input id="activityAgent" placeholder="Agent"><input id="activityThread" placeholder="Thread ID"><input id="activityWorkspace" placeholder="Workspace"><input id="activityType" placeholder="Type"><input id="activitySince" type="datetime-local"><input id="activityLimit" type="number" value="100" min="1" max="500"><button id="loadActivityBtn">Load activity</button><button id="exportActivityBtn" class="secondary">Export</button></div>
            </div>
            <div id="activityList" class="list"></div>
            <div id="activityPager" class="pager"></div>
          </div>
          <div class="monitor-tab" data-monitor-tab-panel="tasks">
            <div class="monitor-tab-heading">
              <button type="button" class="secondary monitor-filter-toggle" data-monitor-filter-toggle="tasks" aria-expanded="false"><span class="monitor-filter-arrow" aria-hidden="true">▸</span><span>Filters</span></button>
              <div class="row monitor-filter-content" data-monitor-filter-panel="tasks" hidden><button id="reloadTasksBtn">Reload tasks</button></div>
            </div>
            <div id="tasksList" class="list"></div>
            <div id="jobsPager" class="pager"></div>
          </div>
          <div class="monitor-tab" data-monitor-tab-panel="trace">
            <div class="monitor-tab-heading">
              <button type="button" class="secondary monitor-filter-toggle" data-monitor-filter-toggle="trace" aria-expanded="false"><span class="monitor-filter-arrow" aria-hidden="true">▸</span><span>Filters</span></button>
              <div class="row monitor-filter-content" data-monitor-filter-panel="trace" hidden><input id="traceCorrelationId" placeholder="Correlation ID"><button id="loadTraceBtn">Load trace</button></div>
            </div>
            <div id="traceDetail" class="list"></div>
          </div>
          <div class="monitor-tab" data-monitor-tab-panel="artifacts">
            <div class="monitor-tab-heading">
              <button type="button" class="secondary monitor-filter-toggle" data-monitor-filter-toggle="artifacts" aria-expanded="false"><span class="monitor-filter-arrow" aria-hidden="true">▸</span><span>Filters</span></button>
              <div class="row monitor-filter-content" data-monitor-filter-panel="artifacts" hidden><button id="reloadArtifactsBtn">Reload artifacts</button><input id="artifactSearch" placeholder="Search artifacts"><select id="artifactKind"><option value="all">All files</option><option value="images">Images</option><option value="docs">Docs/code</option></select><button id="previewArtifactCleanupBtn" class="secondary">Preview cleanup</button><button id="runArtifactCleanupBtn" class="danger">Run cleanup</button><button id="zipSelectedArtifactsBtn" class="secondary">ZIP selected</button><button id="deleteSelectedArtifactsBtn" class="danger">Delete selected</button></div>
            </div>
            <div id="artifactUsage" class="artifact-usage"></div>
            <div id="artifactCleanupPlan" class="artifact-cleanup-plan"></div>
            <div id="artifactPreview" class="preview"></div>
            <div id="artifactList" class="list"></div>
            <div id="artifactPager" class="pager"></div>
          </div>
        </div>
      </section>

      <section class="page" id="page-adapters">
        <div class="panel">
          <div class="section-header adapter-section-header">
            <div id="adapterTabs" class="section-tabs adapter-tabs" role="tablist" aria-label="Adapter sections">
              <button type="button" role="tab" aria-selected="true" tabindex="0" data-adapter-tab="adapters" class="active">Adapters</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-adapter-tab="conformance">Adapter Conformance</button>
            </div>
          </div>
          <div id="adapterPanel" class="adapter-panel">
            <div class="adapter-tab active" data-adapter-tab-panel="adapters">
              <div class="adapter-heading-actions"><button id="reloadAdaptersBtn">Reload adapters</button></div>
              <div id="adapterHealth" class="list"></div>
            </div>
            <div class="adapter-tab" data-adapter-tab-panel="conformance">
              <div class="adapter-heading-actions"><button id="reloadAdapterConformanceBtn" class="secondary">Reload conformance</button></div>
              <div id="adapterConformance" class="list"></div>
            </div>
          </div>
        </div>
      </section>

      <section class="page" id="page-peers">
        <div class="panel">
          <div class="section-header peer-section-header">
            <div id="peerTabs" class="section-tabs peer-tabs" role="tablist" aria-label="Peer sections">
              <button type="button" role="tab" aria-selected="true" tabindex="0" data-peer-tab="status" class="active">Status</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-peer-tab="topology">Topology</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-peer-tab="relay">Relay</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-peer-tab="peers">Peers</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-peer-tab="invitations">Invitations</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-peer-tab="discovery">Discovery</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-peer-tab="global">Global Sessions</button>
            </div>
          </div>
          <div class="peer-tab active" data-peer-tab-panel="status">
            <div class="peer-tab-heading">
              <div class="row peer-heading-actions"><button id="loadPeersBtn">Reload status</button><button id="exportPeerIdentityBtn" class="secondary">Export identity</button><button id="restorePeerIdentityBtn" class="secondary">Restore identity</button></div>
            </div>
            <div id="peerStatus" class="list"></div>
          </div>
          <div class="peer-tab" data-peer-tab-panel="topology">
            <div class="peer-tab-heading">
              <div class="row peer-heading-actions"><button id="reloadPeerTopologyBtn" class="secondary">Reload topology</button></div>
            </div>
            <div id="peerTopology" class="list"></div>
          </div>
          <div class="peer-tab" data-peer-tab-panel="relay">
            <div class="peer-tab-heading">
              <div class="row peer-heading-actions"><button id="reloadPeerRelayBtn" class="secondary">Reload relay</button><button id="retryPeerRelayBtn" class="secondary">Retry stale</button><button id="drainPeerRelayBtn" class="secondary">Drain expired</button></div>
            </div>
            <div id="peerRelay" class="list"></div>
          </div>
          <div class="peer-tab" data-peer-tab-panel="peers">
            <div class="peer-tab-heading">
              <div class="row peer-heading-actions"><button id="addPeerBtn" class="secondary">Add peer</button><button id="syncPeersBtn" class="secondary">Sync peers</button><button id="reloadPeersListBtn" class="secondary">Reload peers</button></div>
            </div>
            <div id="peersList" class="list"></div>
          </div>
          <div class="peer-tab" data-peer-tab-panel="invitations">
            <div class="peer-tab-heading">
              <div class="row peer-heading-actions"><button id="createPeerInviteBtn">Create invite</button><button id="reloadPeerInvitesBtn" class="secondary">Reload invitations</button></div>
            </div>
            <div id="peerInvites" class="list"></div>
          </div>
          <div class="peer-tab" data-peer-tab-panel="discovery">
            <div class="peer-tab-heading">
              <div class="row peer-heading-actions"><button id="discoverPeersBtn" class="secondary">Discover LAN peers</button><button id="cancelPeerDiscoveryBtn" class="secondary">Cancel discovery</button></div>
            </div>
            <div class="row peer-discovery-controls"><input id="peerDiscoveryTargets" placeholder="Optional targets: 192.168.178.0/24, 192.168.178.10-50, host.local, https://host:31979"><input id="peerDiscoveryMaxHosts" type="number" min="1" max="65536" value="512" title="Max hosts"><input id="peerDiscoveryConcurrency" type="number" min="1" max="128" value="32" title="Concurrency"></div>
            <div id="peerDiscovery" class="list"></div>
          </div>
          <div class="peer-tab" data-peer-tab-panel="global">
            <div class="peer-tab-heading">
              <div class="row peer-heading-actions"><input id="globalPeerSessionSearch" placeholder="Search sessions across peers"><button id="loadGlobalPeerSessionsBtn">Load global sessions</button></div>
            </div>
            <div id="globalPeerSessionsPanel" class="list"><div class="item"><div id="globalPeerSessionsList">Load global sessions to inspect sessions across connected peers.</div></div></div>
          </div>
        </div>
      </section>

      <section class="page" id="page-plugins">
        <div class="panel">
          <div class="section-header plugin-section-header">
            <div id="pluginTabs" class="section-tabs plugin-tabs" role="tablist" aria-label="Plugin sections">
              <button type="button" role="tab" aria-selected="true" tabindex="0" data-plugin-tab="installed" class="active">Installed</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-plugin-tab="marketplace">Marketplace</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-plugin-tab="catalog">Extension Catalog</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-plugin-tab="developer">Developer</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-plugin-tab="logs">Logs</button>
            </div>
          </div>
          <div class="plugin-tab active" data-plugin-tab-panel="installed">
            <div class="plugin-tab-heading">
              <div class="row plugin-heading-actions"><button id="reloadPluginsBtn" class="secondary">Reload plugins</button></div>
            </div>
            <div id="pluginStatus" class="callout muted plugin-tab-intro"></div>
            <div id="pluginList" class="sessions-table-host"></div>
          </div>
          <div class="plugin-tab" data-plugin-tab-panel="marketplace">
            <div class="plugin-tab-heading">
              <div class="row plugin-heading-actions"><button id="reloadPluginMarketplaceBtn" class="secondary">Refresh marketplace</button><button id="openInstallPluginDialogBtn">Install plugin</button></div>
            </div>
            <div class="callout muted plugin-tab-intro">Install official or approved plugins on the selected node. Marketplace installs use the same permission checks and audit log as manual plugin installs.</div>
            <div id="pluginMarketplace" class="sessions-table-host"></div>
            <div id="pluginMarketplaceResult" class="list"></div>
          </div>
          <div class="plugin-tab" data-plugin-tab-panel="catalog">
            <div class="plugin-tab-heading">
              <div class="row plugin-heading-actions"><button id="reloadPluginCatalogBtn" class="secondary">Reload catalog</button></div>
            </div>
            <div id="pluginCatalog" class="list"></div>
            <div id="pluginCapabilityResult" class="list"></div>
          </div>
          <div class="plugin-tab" data-plugin-tab-panel="developer">
            <div class="plugin-tab-heading">
              <div class="row plugin-heading-actions"><button id="createPluginScaffoldBtn">Create plugin scaffold</button></div>
            </div>
            <div class="settings-grid compact-settings-grid">
              <label><span>Target directory</span><input id="pluginScaffoldDir" placeholder="/path/to/my-plugin"></label>
              <label><span>Plugin ID</span><input id="pluginScaffoldId" placeholder="my-plugin"></label>
              <label><span>Name</span><input id="pluginScaffoldName" placeholder="My Plugin"></label>
              <label class="full-span"><span>Description</span><input id="pluginScaffoldDescription" placeholder="What this plugin adds"></label>
            </div>
            <div id="pluginDeveloperResult" class="list"></div>
          </div>
          <div class="plugin-tab" data-plugin-tab-panel="logs">
            <div class="plugin-tab-heading">
              <div class="row plugin-heading-actions"><select id="pluginLogSelect"></select><button id="loadPluginLogBtn" class="secondary">Load log</button></div>
            </div>
            <pre id="pluginLog" class="log-view"></pre>
          </div>
        </div>
      </section>

      <section class="page" id="page-plugin-panel">
        <div class="plugin-panel-page">
          <div id="pluginPanelPageInput" class="callout muted" hidden></div>
          <div id="pluginPanelPageResult"></div>
        </div>
      </section>

      <section class="page" id="page-access">
        <div class="panel">
          <div class="section-header access-section-header">
            <div id="accessTabs" class="section-tabs access-tabs" role="tablist" aria-label="Users sections">
              <button type="button" role="tab" aria-selected="true" tabindex="0" data-access-tab="users" class="active">Users</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-access-tab="groups">Groups</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-access-tab="telegram">Telegram</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-access-tab="discord">Discord</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-access-tab="slack">Slack</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-access-tab="matrix">Matrix</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-access-tab="locks">Locks</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-access-tab="audit">Audit</button>
            </div>
          </div>
          <div class="access-tab active" data-access-tab-panel="users">
            <div class="access-tab-heading">
              <div class="row access-heading-actions"><button id="loadAccessBtn" class="secondary">Reload</button><button id="createUserBtn">Create user</button></div>
              <div class="access-filter-row">
                <input id="userSearch" placeholder="Search users">
                <select id="userStatusFilter"><option value="all">All statuses</option><option value="active">Active</option><option value="disabled">Disabled</option></select>
                <select id="userGroupFilter"><option value="all">All groups</option></select>
                <select id="userIdentityFilter"><option value="all">All identities</option><option value="telegram">Telegram linked</option><option value="discord">Discord linked</option><option value="slack">Slack linked</option><option value="matrix">Matrix linked</option><option value="web">Web sessions</option><option value="unlinked">No chat identity</option></select>
              </div>
            </div>
            <div id="accessPanel" class="list user-list"></div>
            <div id="usersPager" class="pager"></div>
          </div>
          <div class="access-tab" data-access-tab-panel="groups">
            <div class="access-tab-heading">
              <div class="row access-heading-actions"><button id="createGroupBtn" class="secondary">Create group</button></div>
              <div class="access-filter-row"><input id="groupSearch" placeholder="Search groups"></div>
            </div>
            <div id="groupsList" class="list"></div>
          </div>
          <div class="access-tab" data-access-tab-panel="telegram">
            <div class="access-tab-heading">
              <div class="row access-heading-actions"><button id="createChatBtn" class="secondary">Add Telegram chat</button></div>
              <input id="telegramChatSearch" placeholder="Search Telegram chats">
            </div>
            <div id="telegramChatsList" class="list"></div>
          </div>
          <div class="access-tab" data-access-tab-panel="discord">
            <div class="access-tab-heading">
              <div class="row access-heading-actions"><button id="createDiscordChannelBtn" class="secondary">Add Discord channel</button></div>
              <input id="discordChannelSearch" placeholder="Search Discord channels">
            </div>
            <div id="discordChannelsList" class="list"></div>
          </div>
          <div class="access-tab" data-access-tab-panel="slack">
            <div class="access-tab-heading">
              <div class="row access-heading-actions"><button id="createSlackChannelBtn" class="secondary">Add Slack channel</button></div>
              <input id="slackChannelSearch" placeholder="Search Slack channels">
            </div>
            <div id="slackChannelsList" class="list"></div>
          </div>
          <div class="access-tab" data-access-tab-panel="matrix">
            <div class="access-tab-heading">
              <div class="row access-heading-actions"><button id="createMatrixRoomBtn" class="secondary">Add Matrix room</button></div>
              <input id="matrixRoomSearch" placeholder="Search Matrix rooms">
            </div>
            <div id="matrixRoomsList" class="list"></div>
          </div>
          <div class="access-tab" data-access-tab-panel="locks">
            <div class="access-tab-heading">
              <div class="row access-heading-actions"><button id="lockSessionBtn" class="secondary">Lock web session</button><button id="unlockSessionBtn" class="secondary">Unlock web session</button></div>
            </div>
            <div id="locksList" class="list"></div>
          </div>
          <div class="access-tab" data-access-tab-panel="audit">
            <div class="access-tab-heading">
              <div class="row access-heading-actions"><button id="loadAuditBtn">Load audit</button><button id="exportAuditBtn" class="secondary">Export</button></div>
            </div>
            <div class="row audit-filter-row"><select id="auditChannel"><option value="all">All channels</option><option value="web">Web</option><option value="telegram">Telegram</option><option value="discord">Discord</option><option value="slack">Slack</option><option value="matrix">Matrix</option></select><select id="auditCategory"><option value="all">All categories</option><option value="prompt">Prompt</option><option value="session">Session</option><option value="queue">Queue</option><option value="agent-update">Agent update</option><option value="artifact">Artifact</option><option value="system">System</option><option value="auth">Auth</option><option value="security">Security</option><option value="tool">Tool</option></select><select id="auditStatus"><option value="all">All statuses</option><option value="ok">OK</option><option value="failed">Failed</option><option value="denied">Denied</option></select><input id="auditActor" placeholder="Actor"><input id="auditAgent" placeholder="Agent"><input id="auditThread" placeholder="Thread ID"><input id="auditWorkspace" placeholder="Workspace"><input id="auditSince" type="datetime-local"><input id="auditLimit" type="number" value="50" min="1" max="500"></div>
            <div id="auditList" class="list"></div>
            <div id="auditPager" class="pager"></div>
          </div>
        </div>
      </section>

      <section class="page" id="page-version">
        <div class="panel">
          <div class="row version-actions"><button id="loadVersionBtn">Check versions</button><button id="updateBtn" class="secondary">Update NordRelay</button></div>
          <div id="versionPanel" class="list"></div>
          <h2 class="version-update-title">Agent update jobs</h2>
          <div id="agentUpdateJobs" class="list"></div>
        </div>
      </section>

      <section class="page" id="page-settings">
        <div class="panel">
          <div id="settingsTabHeader" class="settings-topbar">
            <label class="settings-search-label"><span>Search settings</span><input id="settingsSearchInput" type="search" placeholder="Search by key, label, description, or help text"></label>
          </div>
          <div id="settingsLayout" class="settings-layout">
            <aside id="settingsSubnav" class="settings-navigator"></aside>
            <div class="settings-content">
              <div id="settingsActions" class="row settings-actions"><button id="saveSettingsBtn">Save settings</button><button id="settingsWizardBtn" class="secondary">Setup wizard</button><button id="restartBtn" class="secondary">Restart NordRelay</button><span id="settingsStatus"></span></div>
              <div id="settingsForm" class="settings-grid"></div>
            </div>
          </div>
        </div>
      </section>

      <section class="page" id="page-logs">
        <div class="panel">
          <div class="row"><select id="logTarget"><option value="connector">Connector</option><option value="update">NordRelay Update</option><option value="agent-updates">Agent Updates</option></select><select id="logLevel"><option value="all">All levels</option><option value="ERROR">Error</option><option value="WARN">Warn</option><option value="INFO">Info</option></select><input id="logSearch" placeholder="Search logs"><input id="logSince" type="datetime-local" title="Show entries after this time"><input id="logLines" type="number" value="120" min="1" max="300" title="Rows per page"><label class="checkbox"><input id="logAutoRefresh" type="checkbox"> Auto</label><label class="checkbox"><input id="logFollow" type="checkbox"> Follow</label><button id="loadLogsBtn">Load logs</button><button id="downloadLogsBtn" class="secondary">Download</button><button id="clearLogsBtn" class="danger">Clear</button></div>
          <pre id="logs" class="log-view"></pre>
          <div id="logPager" class="pager"></div>
        </div>
      </section>

      <section class="page" id="page-diagnostics">
        <div class="panel">
          <div class="section-header diagnostics-section-header">
            <div id="diagnosticsTabs" class="section-tabs diagnostics-tabs" role="tablist" aria-label="Diagnostics sections">
              <button type="button" role="tab" aria-selected="true" tabindex="0" data-diagnostics-tab="overview" class="active">Overview</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-diagnostics-tab="runtime">Runtime</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-diagnostics-tab="agent">Agent</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-diagnostics-tab="state">Agent State</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-diagnostics-tab="versions">Versions</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-diagnostics-tab="channels">Channels</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-diagnostics-tab="voice">Voice</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-diagnostics-tab="mirror">Mirror</button>
              <button type="button" role="tab" aria-selected="false" tabindex="-1" data-diagnostics-tab="doctor">Doctor</button>
            </div>
          </div>
          <div class="diagnostics-tab-heading">
            <div class="row diagnostics-heading-actions"><button id="exportDiagnosticsBundleBtn" class="secondary">Export diagnostics bundle</button></div>
          </div>
          <div id="diagnostics"></div>
        </div>
      </section>

      <footer>
        <span id="footerVersion">NordRelay</span>
        <span id="footerHealth">Health: loading</span>
        <span id="connectionStatus" class="footer-connection"><span class="footer-label">Connection:</span> <span class="footer-connection-value connection-warn">Connecting</span></span>
        <span id="footerUser">User: loading</span>
      </footer>
    </main>
  </div>
  <dialog id="newSessionDialog">
    <form method="dialog" id="newSessionForm">
      <h2>New Session</h2>
      <div class="form-grid">
        <div id="newSessionNodeWrap" class="new-session-node full-span" hidden>
          <span>Node</span>
          <strong id="newSessionNodeName">Local node</strong>
          <small id="newSessionNodeHint">New session will start on the currently selected node.</small>
        </div>
        <label>Agent<select id="newAgent"></select></label>
        <label>Workspace<input id="newWorkspace" list="workspaceOptions" placeholder="Current workspace"></label>
        <label>Model<select id="newModel"></select></label>
        <label id="newReasoningWrap">Reasoning<select id="newReasoning"></select></label>
        <label id="newLaunchWrap">Launch profile<select id="newLaunch"></select></label>
        <label><span class="form-label-title">Workspace mode <span class="setting-info session-workspace-mode-help" tabindex="0" role="img" aria-label="Default uses the configured workspace mode. Shared uses the selected workspace directly. Isolated worktree creates a separate Git worktree and branch for the new session. Attached/manual keeps externally started sessions untouched." title="Default uses the configured workspace mode. Shared uses the selected workspace directly. Isolated worktree creates a separate Git worktree and branch for the new session. Attached/manual keeps externally started sessions untouched.">i</span></span><select id="newWorkspaceMode"><option value="">Default</option><option value="shared">Shared workspace</option><option value="worktree">Isolated worktree</option><option value="attached">Attached/manual</option></select></label>
        <label id="newFastWrap" class="checkbox"><input id="newFast" type="checkbox"> Fast mode</label>
      </div>
      <datalist id="workspaceOptions"></datalist>
      <div class="row dialog-actions"><button type="button" id="cancelSessionBtn" class="secondary">Cancel</button><button id="createSessionBtn" value="default">Create session</button></div>
    </form>
  </dialog>
  <dialog id="sessionDetailDialog">
    <div id="sessionDetail"></div>
    <div class="row dialog-actions"><button id="closeSessionDetailBtn" class="secondary">Close</button></div>
  </dialog>
  <dialog id="userDetailDialog">
    <div id="userDetail"></div>
    <div class="row dialog-actions"><button id="closeUserDetailBtn" class="secondary">Close</button></div>
  </dialog>
  <dialog id="adminDialog">
    <form method="dialog" id="adminDialogForm">
      <h2 id="adminDialogTitle">Edit</h2>
      <div id="adminDialogBody" class="form-grid"></div>
      <div class="row dialog-actions"><button type="button" id="adminDialogCancel" class="secondary">Cancel</button><button id="adminDialogSubmit" value="default">Save</button></div>
    </form>
  </dialog>
  <dialog id="profileDialog">
    <form method="dialog" id="profileForm">
      <h2>Profile</h2>
      <div class="profile-grid">
        <section class="profile-section">
          <h3>Account</h3>
          <div class="form-grid">
            <label>Email<input id="profileEmail" type="email" disabled></label>
            <label>Name<input id="profileNameInput" autocomplete="name"></label>
            <label>Theme<select id="profileThemeSelect"><option value="light">Light</option><option value="dark">Dark</option><option value="system">System</option></select></label>
          </div>
          <div id="profileStatus" class="profile-status"></div>
          <div class="row dialog-actions"><button type="button" id="saveProfileBtn">Save profile</button></div>
        </section>
        <section class="profile-section">
          <h3>Change password</h3>
          <div class="form-grid">
            <label>Current password<input id="profileCurrentPassword" type="password" autocomplete="current-password"></label>
            <label>New password<input id="profileNewPassword" type="password" autocomplete="new-password"></label>
            <label>Confirm password<input id="profileConfirmPassword" type="password" autocomplete="new-password"></label>
          </div>
          <div id="profilePasswordStatus" class="profile-status"></div>
          <div class="row dialog-actions"><button type="button" id="changeProfilePasswordBtn" class="secondary">Change password</button></div>
        </section>
        <section class="profile-section full-span">
          <div class="profile-section-title"><h3>Security</h3><button type="button" id="setupTotpBtn" class="secondary">Setup authenticator</button></div>
          <div id="profileSecurity" class="profile-list"></div>
          <div id="profileSecurityStatus" class="profile-status"></div>
        </section>
        <section class="profile-section full-span">
          <div class="profile-section-title"><h3>API tokens</h3><button type="button" id="createApiTokenBtn" class="secondary">Create token</button></div>
          <div id="profileApiTokens" class="profile-list"></div>
          <div id="profileApiTokenResult" class="profile-status"></div>
        </section>
        <section class="profile-section full-span">
          <h3>Linked accounts</h3>
          <div id="profileLinkedAccounts" class="profile-list"></div>
        </section>
        <section class="profile-section full-span">
          <div class="profile-section-title"><h3>Web sessions</h3><button type="button" id="logoutOtherSessionsBtn" class="danger">Logout other sessions</button></div>
          <div id="profileWebSessions" class="profile-list"></div>
        </section>
      </div>
      <div class="row dialog-actions"><button type="button" id="closeProfileBtn" class="secondary">Close</button></div>
    </form>
  </dialog>
  <div id="toolTooltip" class="tool-tooltip"></div>
  <div id="toast"></div>
  <script src="${dashboardAssetPrefix}/dashboard.js"></script>
</body>
</html>`;
}
function nonceAttr(cspNonce) {
    return cspNonce ? ` nonce="${cspNonce.replace(/"/g, "")}"` : "";
}
