<template>
  <transition name="personal-page-fade" appear>
    <div
      class="personal-page-overlay"
      v-if="visible"
      @click="closeDropdown"
      @mousedown.self="personalization.handleOverlayPressStart($event)"
      @mouseup.self="personalization.handleOverlayPressEnd"
      @mouseleave.self="personalization.handleOverlayPressCancel"
      @touchstart.self.prevent="personalization.handleOverlayPressStart($event)"
      @touchend.self.prevent="personalization.handleOverlayPressEnd"
      @touchcancel.self="personalization.handleOverlayPressCancel"
    >
      <div class="personal-page-card settings-redesign-card" data-tutorial="personal-card">
        <button
          type="button"
          class="settings-close-button"
          data-tutorial="personal-close"
          aria-label="关闭个人空间"
          @click="personalization.closeDrawer()"
        >
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-linecap="round">
            <path d="M6 6l12 12M18 6 6 18" />
          </svg>
        </button>

        <div class="personalization-body settings-redesign-body" v-if="!loading">
          <form
            class="personal-form settings-redesign-form"
            @submit.prevent="personalization.save()"
          >
            <div class="settings-redesign-layout">
              <nav class="settings-redesign-tabs" aria-label="个人空间分组切换">
                <button
                  v-for="tab in personalTabs"
                  :key="tab.id"
                  type="button"
                  class="settings-redesign-tab"
                  :data-tutorial="`personal-tab-${tab.id}`"
                  :class="{ active: activeTab === tab.id }"
                  :aria-pressed="activeTab === tab.id"
                  @click.prevent="setActiveTab(tab.id)"
                >
                  <span
                    v-if="tab.id === 'context'"
                    class="settings-tab-icon settings-tab-icon--chat"
                    aria-hidden="true"
                  >
                    <svg viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
                      <path
                        d="M5 6.5c0-1.38 1.12-2.5 2.5-2.5h13c1.38 0 2.5 1.12 2.5 2.5v8.5c0 1.38-1.12 2.5-2.5 2.5h-5.6l-3.4 3.2.6-3.2H7.5c-1.38 0-2.5-1.12-2.5-2.5V6.5z"
                        stroke="currentColor"
                        stroke-width="1.7"
                        stroke-linejoin="round"
                      />
                      <path
                        d="M9 9.5h10"
                        stroke="currentColor"
                        stroke-width="1.7"
                        stroke-linecap="round"
                      />
                      <path
                        d="M9 13h6"
                        stroke="currentColor"
                        stroke-width="1.7"
                        stroke-linecap="round"
                      />
                    </svg>
                  </span>
                  <span
                    v-else
                    class="icon settings-tab-icon"
                    :style="settingsTabIconStyle(tab.icon)"
                    aria-hidden="true"
                  ></span>
                  <span>{{ tab.label }}</span>
                </button>
              </nav>

              <section class="settings-redesign-content" data-tutorial="personal-content-shell">
                <header class="settings-redesign-content-header">
                  <h2>{{ activeTabLabel }}</h2>
                </header>
                <div class="settings-redesign-title-line" aria-hidden="true"></div>

                <div class="settings-redesign-scroll">
                  <transition name="personal-page-vertical" mode="out-in">
                    <section v-if="activeTab === 'general'" key="general" class="settings-page">
                      <label class="settings-toggle-row">
                        <span class="settings-row-copy">
                          <span class="settings-row-title">自动生成对话标题</span>
                          <span class="settings-row-desc"
                            >默认开启；关闭后标题将沿用首条消息</span
                          >
                        </span>
                        <input
                          type="checkbox"
                          :checked="form.auto_generate_title"
                          @change="
                            personalization.updateField({
                              key: 'auto_generate_title',
                              value: $event.target.checked
                            })
                          "
                        />
                        <span class="fancy-check" aria-hidden="true"
                          ><svg viewBox="0 0 64 64">
                            <path
                              d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                              pathLength="575.0541381835938"
                              class="fancy-path"
                            ></path></svg
                        ></span>
                      </label>
                      <div class="settings-action-row">
                        <span class="settings-row-copy">
                          <span class="settings-row-title">新手教程</span>
                          <span class="settings-row-desc"
                            >通过高亮与说明窗了解主要功能入口和常用设置</span
                          >
                        </span>
                        <button
                          type="button"
                          class="settings-secondary-button"
                          @click="startTutorial"
                        >
                          开始教程
                        </button>
                      </div>
                      <div class="settings-action-row" v-if="isAppShell">
                        <span class="settings-row-copy">
                          <span class="settings-row-title">软件更新</span>
                          <span class="settings-row-desc"
                            >当前版本：{{ appCurrentVersionText }} ·
                            {{ appUpdateCheckedText }}</span
                          >
                        </span>
                        <div class="settings-inline-actions">
                          <span class="settings-mini-status" :class="{ warning: appHasUpdate }">{{
                            appUpdateStateText
                          }}</span>
                          <button
                            type="button"
                            class="settings-secondary-button"
                            :disabled="appUpdateChecking"
                            @click="checkAppUpdate"
                          >
                            {{ appUpdateChecking ? '检查中...' : '检查更新' }}
                          </button>
                          <button
                            v-if="appHasUpdate"
                            type="button"
                            class="settings-primary-button"
                            @click="downloadLatestApp"
                          >
                            下载
                          </button>
                        </div>
                      </div>
                      <div class="settings-action-row danger-zone">
                        <span class="settings-row-copy">
                          <span class="settings-row-title">退出登录</span>
                          <span class="settings-row-desc">结束当前账号会话</span>
                        </span>
                        <button
                          type="button"
                          class="settings-secondary-button danger"
                          @click="personalization.logout()"
                        >
                          退出登录
                        </button>
                      </div>
                    </section>

                    <section
                      v-else-if="activeTab === 'preferences'"
                      key="preferences"
                      class="settings-page"
                      data-tutorial="personal-page-preferences"
                    >
                      <label class="settings-toggle-row">
                        <span class="settings-row-copy">
                          <span class="settings-row-title">启用个性化提示</span>
                          <span class="settings-row-desc">开启后才会注入您的偏好</span>
                        </span>
                        <input
                          type="checkbox"
                          :checked="form.enabled"
                          :disabled="toggleUpdating"
                          @change="personalization.toggleEnabled()"
                        />
                        <span class="fancy-check" aria-hidden="true"
                          ><svg viewBox="0 0 64 64">
                            <path
                              d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                              pathLength="575.0541381835938"
                              class="fancy-path"
                            ></path></svg
                        ></span>
                      </label>
                      <label class="settings-input-row">
                        <span class="settings-row-title">AI 智能体自称</span>
                        <input
                          type="text"
                          :value="form.self_identify"
                          maxlength="20"
                          placeholder="如：小秘、助理小A"
                          @input="
                            personalization.updateField({
                              key: 'self_identify',
                              value: $event.target.value
                            })
                          "
                          @focus="personalization.clearFeedback()"
                        />
                      </label>
                      <label class="settings-input-row">
                        <span class="settings-row-title">用户称呼</span>
                        <input
                          type="text"
                          :value="form.user_name"
                          maxlength="20"
                          placeholder="如：Jojo、老师"
                          @input="
                            personalization.updateField({
                              key: 'user_name',
                              value: $event.target.value
                            })
                          "
                          @focus="personalization.clearFeedback()"
                        />
                      </label>
                      <label class="settings-input-row">
                        <span class="settings-row-title">职业</span>
                        <input
                          type="text"
                          :value="form.profession"
                          maxlength="20"
                          placeholder="如：产品经理、设计师"
                          @input="
                            personalization.updateField({
                              key: 'profession',
                              value: $event.target.value
                            })
                          "
                          @focus="personalization.clearFeedback()"
                        />
                      </label>
                      <div class="settings-input-row stackable">
                        <span class="settings-row-title">交流语气</span>
                        <div class="settings-input-stack">
                          <input
                            type="text"
                            :value="form.tone"
                            maxlength="20"
                            placeholder="请选择或输入语气"
                            @input="
                              personalization.updateField({
                                key: 'tone',
                                value: $event.target.value
                              })
                            "
                            @focus="personalization.clearFeedback()"
                          />
                          <div class="settings-chip-row">
                            <button
                              v-for="preset in tonePresets"
                              :key="preset"
                              type="button"
                              @click.prevent="personalization.applyTonePreset(preset)"
                            >
                              {{ preset }}
                            </button>
                          </div>
                        </div>
                      </div>
                      <div class="settings-list-row tall">
                        <span class="settings-row-copy">
                          <span class="settings-row-title">回答时必须考虑的信息</span>
                          <span class="settings-row-desc"
                            >最多 {{ maxConsiderations }} 条，可拖动排序</span
                          >
                        </span>
                        <div class="settings-input-stack wide">
                          <div class="settings-add-row">
                            <input
                              type="text"
                              :value="newConsideration"
                              maxlength="50"
                              placeholder="输入后点击 + 添加"
                              @input="personalization.updateNewConsideration($event.target.value)"
                              @focus="personalization.clearFeedback()"
                            />
                            <button
                              type="button"
                              :disabled="
                                !newConsideration || form.considerations.length >= maxConsiderations
                              "
                              @click="personalization.addConsideration()"
                            >
                              +
                            </button>
                          </div>
                          <ul class="settings-consideration-list" v-if="form.considerations.length">
                            <li
                              v-for="(item, idx) in form.considerations"
                              :key="`consideration-${idx}`"
                              draggable="true"
                              @dragstart="personalization.considerationDragStart(idx, $event)"
                              @dragover.prevent="personalization.considerationDragOver(idx, $event)"
                              @drop.prevent="personalization.considerationDrop(idx, $event)"
                              @dragend="personalization.considerationDragEnd()"
                            >
                              <span class="drag-handle" aria-hidden="true">≡</span>
                              <span>{{ item }}</span>
                              <button
                                type="button"
                                @click="personalization.removeConsideration(idx)"
                              >
                                −
                              </button>
                            </li>
                          </ul>
                        </div>
                      </div>
                      <div class="settings-select-row">
                        <span class="settings-row-copy">
                          <span class="settings-row-title">智能体交流风格</span>
                          <span class="settings-row-desc">智能体和您交流时使用何种形式</span>
                        </span>
                        <div
                          class="settings-select-wrap"
                          :class="{ open: activeDropdown === 'communication' }"
                          @click.stop
                        >
                          <button
                            type="button"
                            class="settings-select-button"
                            @click="toggleDropdown('communication')"
                          >
                            {{ communicationStyleLabel }}
                            <span class="select-chevron" aria-hidden="true"></span>
                          </button>
                          <div
                            :class="['settings-floating-menu', { dark: activeTheme === 'dark' }]"
                            :style="activeDropdown ? floatingMenuStyle : undefined"
                          >
                            <button
                              type="button"
                              class="settings-menu-option"
                              :class="{ selected: form.communication_style === 'default' }"
                              @click="selectCommunicationStyle('default')"
                            >
                              <strong>默认</strong><span>标准 AI 风格</span
                              ><svg viewBox="0 0 24 24"><path d="M5 12.5 9.5 17 19 7" /></svg>
                            </button>
                            <button
                              type="button"
                              class="settings-menu-option"
                              :class="{ selected: form.communication_style === 'human_like' }"
                              @click="selectCommunicationStyle('human_like')"
                            >
                              <strong>拟人</strong><span>像聊天一样模仿人类语言风格</span
                              ><svg viewBox="0 0 24 24"><path d="M5 12.5 9.5 17 19 7" /></svg>
                            </button>
                          </div>
                        </div>
                      </div>
                    </section>

                    <section
                      v-else-if="activeTab === 'model'"
                      key="model"
                      class="settings-page"
                      data-tutorial="personal-page-model"
                    >
                      <div class="settings-select-row">
                        <span class="settings-row-copy"
                          ><span class="settings-row-title">默认模型</span
                          ><span class="settings-row-desc"
                            >为新对话/登录后首次请求选择首选模型</span
                          ></span
                        >
                        <div
                          class="settings-select-wrap"
                          :class="{ open: activeDropdown === 'model' }"
                          @click.stop
                        >
                          <button
                            type="button"
                            class="settings-select-button"
                            @click="toggleDropdown('model')"
                          >
                            {{ defaultModelLabel }}
                            <span class="select-chevron" aria-hidden="true"></span>
                          </button>
                          <div
                            :class="['settings-floating-menu', { dark: activeTheme === 'dark' }]"
                            :style="activeDropdown ? floatingMenuStyle : undefined"
                          >
                            <button
                              v-for="option in filteredModelOptions"
                              :key="option.id"
                              type="button"
                              class="settings-menu-option"
                              :class="{
                                selected: form.default_model === option.value,
                                disabled: option.disabled
                              }"
                              :disabled="option.disabled"
                              @click="selectDefaultModel(option.value)"
                            >
                              <strong>{{ option.label }}</strong
                              ><span>{{ option.disabled ? '已被管理员禁用' : option.desc }}</span
                              ><svg viewBox="0 0 24 24"><path d="M5 12.5 9.5 17 19 7" /></svg>
                            </button>
                          </div>
                        </div>
                      </div>
                      <div class="settings-select-row">
                        <span class="settings-row-copy"
                          ><span class="settings-row-title">默认运行模式</span
                          ><span class="settings-row-desc"
                            >登录或新建任务时的初始运行模式</span
                          ></span
                        >
                        <div
                          class="settings-select-wrap"
                          :class="{ open: activeDropdown === 'run-mode' }"
                          @click.stop
                        >
                          <button
                            type="button"
                            class="settings-select-button"
                            @click="toggleDropdown('run-mode')"
                          >
                            {{ runModeLabel }}
                            <span class="select-chevron" aria-hidden="true"></span>
                          </button>
                          <div
                            :class="['settings-floating-menu', { dark: activeTheme === 'dark' }]"
                            :style="activeDropdown ? floatingMenuStyle : undefined"
                          >
                            <button
                              v-for="option in runModeOptions"
                              :key="option.id"
                              type="button"
                              class="settings-menu-option"
                              :class="{ selected: isRunModeActive(option.value) }"
                              @click="selectDefaultRunMode(option.value)"
                            >
                              <strong>{{ option.label }}</strong
                              ><span>{{ option.desc }}</span
                              ><svg viewBox="0 0 24 24"><path d="M5 12.5 9.5 17 19 7" /></svg>
                            </button>
                          </div>
                        </div>
                      </div>
                      <div class="settings-list-row tall">
                        <span class="settings-row-copy"
                          ><span class="settings-row-title">思考频率</span
                          ><span class="settings-row-desc"
                            >连续快速模式运行多少轮后，系统强制切换到思考模型</span
                          ></span
                        >
                        <div class="settings-input-stack wide">
                          <div class="settings-chip-row right">
                            <button
                              v-for="preset in thinkingPresets"
                              :key="preset.id"
                              type="button"
                              :class="{ active: isPresetActive(preset.value) }"
                              @click.prevent="applyThinkingPreset(preset.value)"
                            >
                              {{ preset.label }} · {{ preset.value }}轮
                            </button>
                          </div>
                          <div class="settings-number-row">
                            <input
                              type="number"
                              :min="thinkingIntervalRange.min"
                              :max="thinkingIntervalRange.max"
                              :placeholder="`默认 ${thinkingIntervalDefault} 轮`"
                              :value="form.thinking_interval ?? ''"
                              @input="handleThinkingInput"
                              @focus="personalization.clearFeedback()"
                            />
                            <button type="button" @click.prevent="restoreThinkingInterval">
                              恢复默认
                            </button>
                          </div>
                        </div>
                      </div>
                    </section>

                    <section
                      v-else-if="activeTab === 'appearance'"
                      key="appearance"
                      class="settings-page"
                    >
                      <div class="settings-select-row">
                        <span class="settings-row-copy"
                          ><span class="settings-row-title">主题切换</span
                          ><span class="settings-row-desc">在经典、明亮和夜间之间切换</span></span
                        >
                        <div
                          class="settings-select-wrap"
                          :class="{ open: activeDropdown === 'theme' }"
                          @click.stop
                        >
                          <button
                            type="button"
                            class="settings-select-button"
                            @click="toggleDropdown('theme')"
                          >
                            {{ themeLabel }} <span class="select-chevron" aria-hidden="true"></span>
                          </button>
                          <div
                            :class="['settings-floating-menu', { dark: activeTheme === 'dark' }]"
                            :style="activeDropdown ? floatingMenuStyle : undefined"
                          >
                            <button
                              v-for="option in themeOptions"
                              :key="option.id"
                              type="button"
                              class="settings-menu-option"
                              :class="{ selected: activeTheme === option.id }"
                              @click="selectThemeOption(option.id)"
                            >
                              <strong>{{ option.label }}</strong
                              ><span>{{ option.desc }}</span
                              ><svg viewBox="0 0 24 24"><path d="M5 12.5 9.5 17 19 7" /></svg>
                            </button>
                          </div>
                        </div>
                      </div>
                      <label class="settings-toggle-row"
                        ><span class="settings-row-copy"
                          ><span class="settings-row-title">默认隐藏工作区</span
                          ><span class="settings-row-desc"
                            >打开页面时默认收起左侧工作区，仍可随时手动展开</span
                          ></span
                        ><input
                          type="checkbox"
                          :checked="form.default_hide_workspace"
                          @change="applyDefaultHideWorkspaceOption($event.target.checked)"
                        /><span class="fancy-check" aria-hidden="true"
                          ><svg viewBox="0 0 64 64">
                            <path
                              d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                              pathLength="575.0541381835938"
                              class="fancy-path"
                            ></path></svg></span
                      ></label>
                      <label class="settings-toggle-row"
                        ><span class="settings-row-copy"
                          ><span class="settings-row-title">使用自定义称呼</span
                          ><span class="settings-row-desc"
                            >对话区域使用个性化设置中的自称和称呼</span
                          ></span
                        ><input
                          type="checkbox"
                          :checked="form.use_custom_names"
                          @change="
                            personalization.updateField({
                              key: 'use_custom_names',
                              value: $event.target.checked
                            })
                          " /><span class="fancy-check" aria-hidden="true"
                          ><svg viewBox="0 0 64 64">
                            <path
                              d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                              pathLength="575.0541381835938"
                              class="fancy-path"
                            ></path></svg></span
                      ></label>
                      <label class="settings-toggle-row"
                        ><span class="settings-row-copy"
                          ><span class="settings-row-title">增强工具显示</span
                          ><span class="settings-row-desc"
                            >工具块显示格式化内容，关闭则显示原始 JSON</span
                          ></span
                        ><input
                          type="checkbox"
                          :checked="form.enhanced_tool_display"
                          @change="
                            personalization.updateField({
                              key: 'enhanced_tool_display',
                              value: $event.target.checked
                            })
                          " /><span class="fancy-check" aria-hidden="true"
                          ><svg viewBox="0 0 64 64">
                            <path
                              d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                              pathLength="575.0541381835938"
                              class="fancy-path"
                            ></path></svg></span
                      ></label>
                      <label class="settings-toggle-row"
                        ><span class="settings-row-copy"
                          ><span class="settings-row-title">显示 Git 状态栏</span
                          ><span class="settings-row-desc"
                            >工作区存在 Git 仓库时，在输入栏上方显示分支和变更统计</span
                          ></span
                        ><input
                          type="checkbox"
                          :checked="form.show_git_status_bar"
                          @change="
                            personalization.updateField({
                              key: 'show_git_status_bar',
                              value: $event.target.checked
                            })
                          " /><span class="fancy-check" aria-hidden="true"
                          ><svg viewBox="0 0 64 64">
                            <path
                              d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                              pathLength="575.0541381835938"
                              class="fancy-path"
                            ></path></svg></span
                      ></label>
                      <div class="settings-select-row">
                        <span class="settings-row-copy"
                          ><span class="settings-row-title">堆叠块显示模式</span
                          ><span class="settings-row-desc">选择思考/工具块的显示方式</span></span
                        >
                        <div
                          class="settings-select-wrap"
                          :class="{ open: activeDropdown === 'block-display' }"
                          @click.stop
                        >
                          <button
                            type="button"
                            class="settings-select-button"
                            @click="toggleDropdown('block-display')"
                          >
                            {{ blockDisplayLabel }}
                            <span class="select-chevron" aria-hidden="true"></span>
                          </button>
                          <div
                            :class="['settings-floating-menu', { dark: activeTheme === 'dark' }]"
                            :style="activeDropdown ? floatingMenuStyle : undefined"
                          >
                            <button
                              v-for="option in blockDisplayOptions"
                              :key="option.id"
                              type="button"
                              class="settings-menu-option"
                              :class="{ selected: currentBlockDisplayMode === option.value }"
                              @click="selectBlockDisplayMode(option.value)"
                            >
                              <strong>{{ option.label }}</strong
                              ><span>{{ option.desc }}</span
                              ><svg viewBox="0 0 24 24"><path d="M5 12.5 9.5 17 19 7" /></svg>
                            </button>
                          </div>
                        </div>
                      </div>
                      <div class="settings-select-row">
                        <span class="settings-row-copy"
                          ><span class="settings-row-title">简略消息显示</span
                          ><span class="settings-row-desc"
                            >审核、子智能体等紧凑系统消息的显示形式</span
                          ></span
                        >
                        <div
                          class="settings-select-wrap"
                          :class="{ open: activeDropdown === 'compact-message' }"
                          @click.stop
                        >
                          <button
                            type="button"
                            class="settings-select-button"
                            @click="toggleDropdown('compact-message')"
                          >
                            {{ compactMessageDisplayLabel }}
                            <span class="select-chevron" aria-hidden="true"></span>
                          </button>
                          <div
                            :class="['settings-floating-menu', { dark: activeTheme === 'dark' }]"
                            :style="activeDropdown ? floatingMenuStyle : undefined"
                          >
                            <button
                              v-for="option in compactMessageDisplayOptions"
                              :key="option.id"
                              type="button"
                              class="settings-menu-option"
                              :class="{ selected: currentCompactMessageDisplay === option.value }"
                              @click="selectCompactMessageDisplay(option.value)"
                            >
                              <strong>{{ option.label }}</strong
                              ><span>{{ option.desc }}</span
                              ><svg viewBox="0 0 24 24"><path d="M5 12.5 9.5 17 19 7" /></svg>
                            </button>
                          </div>
                        </div>
                      </div>
                    </section>

                    <section
                      v-else-if="activeTab === 'workspace'"
                      key="workspace"
                      class="settings-page"
                      data-tutorial="personal-page-workspace"
                    >
                      <div class="settings-select-row">
                        <span class="settings-row-copy"
                          ><span class="settings-row-title">默认权限</span
                          ><span class="settings-row-desc">新建对话时的默认权限模式</span></span
                        >
                        <div
                          class="settings-select-wrap"
                          :class="{ open: activeDropdown === 'permission' }"
                          @click.stop
                        >
                          <button
                            type="button"
                            class="settings-select-button"
                            @click="toggleDropdown('permission')"
                          >
                            {{ permissionModeLabel }}
                            <span class="select-chevron" aria-hidden="true"></span>
                          </button>
                          <div
                            :class="['settings-floating-menu', { dark: activeTheme === 'dark' }]"
                            :style="activeDropdown ? floatingMenuStyle : undefined"
                          >
                            <button
                              v-for="option in permissionModeOptions"
                              :key="option.id"
                              type="button"
                              class="settings-menu-option"
                              :class="{ selected: form.default_permission_mode === option.id }"
                              @click="selectDefaultPermissionMode(option.id)"
                            >
                              <strong>{{ option.label }}</strong
                              ><span>{{ option.desc }}</span
                              ><svg viewBox="0 0 24 24"><path d="M5 12.5 9.5 17 19 7" /></svg>
                            </button>
                          </div>
                        </div>
                      </div>
                      <label class="settings-toggle-row"
                        ><span class="settings-row-copy"
                          ><span class="settings-row-title">允许根目录创建文件</span
                          ><span class="settings-row-desc"
                            >关闭则禁止在工作区根目录创建文件</span
                          ></span
                        ><input
                          type="checkbox"
                          :checked="form.allow_root_file_creation"
                          @change="
                            personalization.updateField({
                              key: 'allow_root_file_creation',
                              value: $event.target.checked
                            })
                          " /><span class="fancy-check" aria-hidden="true"
                          ><svg viewBox="0 0 64 64">
                            <path
                              d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                              pathLength="575.0541381835938"
                              class="fancy-path"
                            ></path></svg></span
                      ></label>
                      <label class="settings-toggle-row"
                        ><span class="settings-row-copy"
                          ><span class="settings-row-title">AGENTS.md 自动注入</span
                          ><span class="settings-row-desc"
                            >工作区根目录存在 AGENTS.md 时自动注入系统提示词</span
                          ></span
                        ><input
                          type="checkbox"
                          :checked="form.agents_md_auto_inject"
                          @change="
                            personalization.updateField({
                              key: 'agents_md_auto_inject',
                              value: $event.target.checked
                            })
                          " /><span class="fancy-check" aria-hidden="true"
                          ><svg viewBox="0 0 64 64">
                            <path
                              d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                              pathLength="575.0541381835938"
                              class="fancy-path"
                            ></path></svg></span
                      ></label>

                      <div class="settings-section-divider">
                        <span class="settings-section-divider__label">目标模式</span>
                      </div>

                      <label class="settings-toggle-row"
                        ><span class="settings-row-copy"
                          ><span class="settings-row-title">审核智能体主动取证</span
                          ><span class="settings-row-desc"
                            >开启后可运行只读命令核实目标，关闭则仅依据对话判断</span
                          ></span
                        ><input
                          type="checkbox"
                          :checked="form.goal_review_mode === 'active'"
                          @change="
                            personalization.updateField({
                              key: 'goal_review_mode',
                              value: $event.target.checked ? 'active' : 'readonly'
                            })
                          " /><span class="fancy-check" aria-hidden="true"
                          ><svg viewBox="0 0 64 64">
                            <path
                              d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                              pathLength="575.0541381835938"
                              class="fancy-path"
                            ></path></svg></span
                      ></label>

                      <div class="settings-select-row">
                        <span class="settings-row-copy"
                          ><span class="settings-row-title">最大自动续命轮数</span
                          ><span class="settings-row-desc"
                            >主模型停下后最多自动继续 1-100 轮</span
                          ></span
                        >
                        <input
                          type="number"
                          class="settings-number-input"
                          min="1"
                          max="100"
                          :value="form.goal_max_turns"
                          @change="
                            personalization.updateField({
                              key: 'goal_max_turns',
                              value: clampGoalMaxTurns($event.target.value)
                            })
                          "
                        />
                      </div>

                      <label class="settings-toggle-row"
                        ><span class="settings-row-copy"
                          ><span class="settings-row-title">启用累计 token 上限</span
                          ><span class="settings-row-desc"
                            >累计输入输出超过上限时停止目标模式</span
                          ></span
                        ><input
                          type="checkbox"
                          :checked="goalTokenLimitEnabled"
                          @change="toggleGoalTokenLimit($event.target.checked)" /><span
                          class="fancy-check"
                          aria-hidden="true"
                          ><svg viewBox="0 0 64 64">
                            <path
                              d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                              pathLength="575.0541381835938"
                              class="fancy-path"
                            ></path></svg></span
                      ></label>

                      <div v-if="goalTokenLimitEnabled" class="settings-select-row">
                        <span class="settings-row-copy"
                          ><span class="settings-row-title">累计 token 上限</span
                          ><span class="settings-row-desc">达到该累计消耗即停止目标模式</span></span
                        >
                        <input
                          type="number"
                          class="settings-number-input"
                          min="1000"
                          step="1000"
                          :value="form.goal_max_tokens || 100000"
                          @change="
                            personalization.updateField({
                              key: 'goal_max_tokens',
                              value: clampGoalMaxTokens($event.target.value)
                            })
                          "
                        />
                      </div>
                    </section>

                    <section
                      v-else-if="activeTab === 'context'"
                      key="context"
                      class="settings-page"
                    >
                      <label class="settings-toggle-row"
                        ><span class="settings-row-copy"
                          ><span class="settings-row-title">最近对话提示</span
                          ><span class="settings-row-desc"
                            >把当前工作区最近若干个非空对话注入系统提示词</span
                          ></span
                        ><input
                          type="checkbox"
                          :checked="form.recent_conversations_prompt_enabled"
                          @change="
                            personalization.updateField({
                              key: 'recent_conversations_prompt_enabled',
                              value: $event.target.checked
                            })
                          " /><span class="fancy-check" aria-hidden="true"
                          ><svg viewBox="0 0 64 64">
                            <path
                              d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                              pathLength="575.0541381835938"
                              class="fancy-path"
                            ></path></svg></span
                      ></label>
                      <div
                        class="settings-input-row"
                        v-if="form.recent_conversations_prompt_enabled"
                      >
                        <span class="settings-row-title">最近对话注入数量</span>
                        <div class="settings-number-row">
                          <input
                            type="number"
                            :min="recentConversationsPromptLimitRange.min"
                            :max="recentConversationsPromptLimitRange.max"
                            :value="form.recent_conversations_prompt_limit"
                            @input="handleRecentConversationsPromptLimitInput"
                            @blur="commitRecentConversationsPromptLimitInput"
                          /><button type="button" @click="restoreRecentConversationsPromptLimit">
                            恢复默认
                          </button>
                        </div>
                      </div>
                      <div class="settings-group-block">
                        <div class="settings-group-title">
                          <span class="settings-row-title">上下文压缩策略</span
                          ><span class="settings-row-desc"
                            >可分别控制自动浅层压缩与自动深层压缩</span
                          >
                        </div>
                        <label class="settings-toggle-row inner"
                          ><span class="settings-row-copy"
                            ><span class="settings-row-title">自动浅层压缩</span></span
                          ><input
                            type="checkbox"
                            :checked="form.auto_shallow_compress_enabled"
                            @change="
                              personalization.updateField({
                                key: 'auto_shallow_compress_enabled',
                                value: $event.target.checked
                              })
                            " /><span class="fancy-check" aria-hidden="true"
                            ><svg viewBox="0 0 64 64">
                              <path
                                d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                                pathLength="575.0541381835938"
                                class="fancy-path"
                              ></path></svg></span
                        ></label>
                        <label class="settings-toggle-row inner"
                          ><span class="settings-row-copy"
                            ><span class="settings-row-title">自动深层压缩</span></span
                          ><input
                            type="checkbox"
                            :checked="form.auto_deep_compress_enabled"
                            @change="
                              personalization.updateField({
                                key: 'auto_deep_compress_enabled',
                                value: $event.target.checked
                              })
                            " /><span class="fancy-check" aria-hidden="true"
                            ><svg viewBox="0 0 64 64">
                              <path
                                d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                                pathLength="575.0541381835938"
                                class="fancy-path"
                              ></path></svg></span
                        ></label>
                        <div class="settings-compression-grid">
                          <label
                            ><span>浅压缩触发上下文</span
                            ><input
                              type="number"
                              :value="form.shallow_compress_trigger_tokens ?? ''"
                              @input="
                                handleCompressionNumberInput(
                                  'shallow_compress_trigger_tokens',
                                  $event
                                )
                              "
                          /></label>
                          <label
                            ><span>浅压缩保留最近工具数</span
                            ><input
                              type="number"
                              :value="form.shallow_compress_keep_recent_tools ?? ''"
                              @input="
                                handleCompressionNumberInput(
                                  'shallow_compress_keep_recent_tools',
                                  $event
                                )
                              "
                          /></label>
                          <label
                            ><span>浅压缩保留当前轮工具数</span
                            ><input
                              type="number"
                              :value="form.shallow_compress_keep_user_turn_tools ?? ''"
                              @input="
                                handleCompressionNumberInput(
                                  'shallow_compress_keep_user_turn_tools',
                                  $event
                                )
                              "
                          /></label>
                          <label
                            ><span>每轮最大替换数量</span
                            ><input
                              type="number"
                              :value="form.shallow_compress_max_replace_per_round ?? ''"
                              @input="
                                handleCompressionNumberInput(
                                  'shallow_compress_max_replace_per_round',
                                  $event
                                )
                              "
                          /></label>
                          <label
                            ><span>工具调用间隔触发</span
                            ><input
                              type="number"
                              :value="form.shallow_compress_trigger_tool_calls_interval ?? ''"
                              @input="
                                handleCompressionNumberInput(
                                  'shallow_compress_trigger_tool_calls_interval',
                                  $event
                                )
                              "
                          /></label>
                          <label
                            ><span>深压缩触发上下文</span
                            ><input
                              type="number"
                              :value="form.deep_compress_trigger_tokens ?? ''"
                              @input="
                                handleCompressionNumberInput('deep_compress_trigger_tokens', $event)
                              "
                          /></label>
                        </div>
                        <label class="settings-toggle-row inner"
                          ><span class="settings-row-copy"
                            ><span class="settings-row-title">深压缩直接注入</span
                            ><span class="settings-row-desc"
                              >开启后直接注入历次压缩全文，关闭则只提示文件位置</span
                            ></span
                          ><input
                            type="checkbox"
                            :checked="form.deep_compress_form === 'inject'"
                            @change="
                              personalization.updateField({
                                key: 'deep_compress_form',
                                value: $event.target.checked ? 'inject' : 'file'
                              })
                            " /><span class="fancy-check" aria-hidden="true"
                            ><svg viewBox="0 0 64 64">
                              <path
                                d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                                pathLength="575.0541381835938"
                                class="fancy-path"
                              ></path></svg></span
                        ></label>
                        <label class="settings-toggle-row inner"
                          ><span class="settings-row-copy"
                            ><span class="settings-row-title">手动压缩后等待用户</span
                            ><span class="settings-row-desc"
                              >开启后手动压缩只插入引导语并等待输入，关闭则自动继续工作</span
                            ></span
                          ><input
                            type="checkbox"
                            :checked="form.deep_compress_behavior === 'wait'"
                            @change="
                              personalization.updateField({
                                key: 'deep_compress_behavior',
                                value: $event.target.checked ? 'wait' : 'continue'
                              })
                            " /><span class="fancy-check" aria-hidden="true"
                            ><svg viewBox="0 0 64 64">
                              <path
                                d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                                pathLength="575.0541381835938"
                                class="fancy-path"
                              ></path></svg></span
                        ></label>
                        <div class="settings-inline-actions right">
                          <button
                            type="button"
                            class="settings-secondary-button"
                            @click="restoreCompressionDefaults"
                          >
                            恢复压缩默认值
                          </button>
                        </div>
                      </div>
                    </section>

                    <section v-else-if="activeTab === 'tools'" key="tools" class="settings-page">
                      <label class="settings-toggle-row"
                        ><span class="settings-row-copy"
                          ><span class="settings-row-title">静默禁用工具</span
                          ><span class="settings-row-desc"
                            >禁用工具时不再注入提示消息，模型不会感知被禁用项</span
                          ></span
                        ><input
                          type="checkbox"
                          :checked="form.silent_tool_disable"
                          @change="
                            personalization.updateField({
                              key: 'silent_tool_disable',
                              value: $event.target.checked
                            })
                          " /><span class="fancy-check" aria-hidden="true"
                          ><svg viewBox="0 0 64 64">
                            <path
                              d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                              pathLength="575.0541381835938"
                              class="fancy-path"
                            ></path></svg></span
                      ></label>
                      <label class="settings-toggle-row"
                        ><span class="settings-row-copy"
                          ><span class="settings-row-title">工具意图提示</span
                          ><span class="settings-row-desc"
                            >调用工具时先用简短文字告诉你要做什么</span
                          ></span
                        ><input
                          type="checkbox"
                          :checked="form.tool_intent_enabled"
                          @change="
                            personalization.updateField({
                              key: 'tool_intent_enabled',
                              value: $event.target.checked
                            })
                          " /><span class="fancy-check" aria-hidden="true"
                          ><svg viewBox="0 0 64 64">
                            <path
                              d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                              pathLength="575.0541381835938"
                              class="fancy-path"
                            ></path></svg></span
                      ></label>
                      <label class="settings-toggle-row"
                        ><span class="settings-row-copy"
                          ><span class="settings-row-title">Skill 提示系统</span
                          ><span class="settings-row-desc"
                            >检测到特定关键词时自动提示模型阅读相关 skill</span
                          ></span
                        ><input
                          type="checkbox"
                          :checked="form.skill_hints_enabled"
                          @change="
                            personalization.updateField({
                              key: 'skill_hints_enabled',
                              value: $event.target.checked
                            })
                          " /><span class="fancy-check" aria-hidden="true"
                          ><svg viewBox="0 0 64 64">
                            <path
                              d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                              pathLength="575.0541381835938"
                              class="fancy-path"
                            ></path></svg></span
                      ></label>
                      <div class="settings-group-block">
                        <div class="settings-group-title">
                          <span class="settings-row-title">强约束系统</span
                          ><span class="settings-row-desc"
                            >仅对个人空间中已启用的 skill 生效</span
                          >
                        </div>
                        <label class="settings-toggle-row inner"
                          ><span class="settings-row-title">Terminal 系列工具</span
                          ><input
                            type="checkbox"
                            :checked="form.skill_strict_terminal_enabled"
                            @change="
                              personalization.updateField({
                                key: 'skill_strict_terminal_enabled',
                                value: $event.target.checked
                              })
                            " /><span class="fancy-check" aria-hidden="true"
                            ><svg viewBox="0 0 64 64">
                              <path
                                d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                                pathLength="575.0541381835938"
                                class="fancy-path"
                              ></path></svg></span
                        ></label>
                        <label class="settings-toggle-row inner"
                          ><span class="settings-row-title">子智能体系列工具</span
                          ><input
                            type="checkbox"
                            :checked="form.skill_strict_sub_agent_enabled"
                            @change="
                              personalization.updateField({
                                key: 'skill_strict_sub_agent_enabled',
                                value: $event.target.checked
                              })
                            " /><span class="fancy-check" aria-hidden="true"
                            ><svg viewBox="0 0 64 64">
                              <path
                                d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                                pathLength="575.0541381835938"
                                class="fancy-path"
                              ></path></svg></span
                        ></label>
                        <label class="settings-toggle-row inner"
                          ><span class="settings-row-title">run_command 前台模式</span
                          ><input
                            type="checkbox"
                            :checked="form.skill_strict_run_command_foreground_enabled"
                            @change="
                              personalization.updateField({
                                key: 'skill_strict_run_command_foreground_enabled',
                                value: $event.target.checked
                              })
                            " /><span class="fancy-check" aria-hidden="true"
                            ><svg viewBox="0 0 64 64">
                              <path
                                d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                                pathLength="575.0541381835938"
                                class="fancy-path"
                              ></path></svg></span
                        ></label>
                        <label class="settings-toggle-row inner"
                          ><span class="settings-row-title">run_command 后台模式</span
                          ><input
                            type="checkbox"
                            :checked="form.skill_strict_run_command_background_enabled"
                            @change="
                              personalization.updateField({
                                key: 'skill_strict_run_command_background_enabled',
                                value: $event.target.checked
                              })
                            " /><span class="fancy-check" aria-hidden="true"
                            ><svg viewBox="0 0 64 64">
                              <path
                                d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                                pathLength="575.0541381835938"
                                class="fancy-path"
                              ></path></svg></span
                        ></label>
                      </div>
                      <div class="settings-group-block" v-if="skillsCatalog.length">
                        <div class="settings-group-title">
                          <span class="settings-row-title">可用 Skills</span
                          ><span class="settings-row-desc"
                            >勾选后会注入 system prompt，并同步到工作区的 skills/ 目录</span
                          >
                        </div>
                        <div class="settings-check-grid">
                          <label
                            v-for="skill in skillsCatalog"
                            :key="skill.id"
                            class="settings-toggle-row inner"
                            ><span class="settings-row-title">{{ skill.label }}</span
                            ><input
                              type="checkbox"
                              :checked="form.enabled_skills.includes(skill.id)"
                              @change="personalization.toggleSkill(skill.id)" /><span
                              class="fancy-check"
                              aria-hidden="true"
                              ><svg viewBox="0 0 64 64">
                                <path
                                  d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                                  pathLength="575.0541381835938"
                                  class="fancy-path"
                                ></path></svg></span
                          ></label>
                        </div>
                      </div>
                      <div class="settings-group-block" v-if="toolCategories.length">
                        <div class="settings-group-title">
                          <span class="settings-row-title">默认禁用工具类别</span
                          ><span class="settings-row-desc"
                            >选择后，这些类别在新任务中保持关闭</span
                          >
                        </div>
                        <div class="settings-check-grid">
                          <label
                            v-for="category in toolCategories"
                            :key="category.id"
                            class="settings-toggle-row inner"
                            ><span class="settings-row-title">{{ category.label }}</span
                            ><input
                              type="checkbox"
                              :checked="form.disabled_tool_categories.includes(category.id)"
                              @change="toggleCategory(category.id)" /><span
                              class="fancy-check"
                              aria-hidden="true"
                              ><svg viewBox="0 0 64 64">
                                <path
                                  d="M 0 16 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 16 L 32 48 L 64 16 V 8 A 8 8 90 0 0 56 0 H 8 A 8 8 90 0 0 0 8 V 56 A 8 8 90 0 0 8 64 H 56 A 8 8 90 0 0 64 56 V 16"
                                  pathLength="575.0541381835938"
                                  class="fancy-path"
                                ></path></svg></span
                          ></label>
                        </div>
                      </div>
                    </section>

                    <section
                      v-else-if="activeTab === 'files'"
                      key="files"
                      class="settings-page"
                      data-tutorial="personal-page-image"
                    >
                      <div class="settings-select-row">
                        <span class="settings-row-copy"
                          ><span class="settings-row-title">图片压缩</span
                          ><span class="settings-row-desc"
                            >发送图片或调用 view_image 时自动等比缩放</span
                          ></span
                        >
                        <div
                          class="settings-select-wrap"
                          :class="{ open: activeDropdown === 'image' }"
                          @click.stop
                        >
                          <button
                            type="button"
                            class="settings-select-button"
                            @click="toggleDropdown('image')"
                          >
                            {{ imageCompressionLabel }}
                            <span class="select-chevron" aria-hidden="true"></span>
                          </button>
                          <div
                            :class="['settings-floating-menu', { dark: activeTheme === 'dark' }]"
                            :style="activeDropdown ? floatingMenuStyle : undefined"
                          >
                            <button
                              v-for="option in imageCompressionOptions"
                              :key="option.id"
                              type="button"
                              class="settings-menu-option"
                              :class="{ selected: form.image_compression === option.id }"
                              @click="selectImageCompression(option.id)"
                            >
                              <strong>{{ option.label }}</strong
                              ><span>{{ option.desc }}</span
                              ><svg viewBox="0 0 24 24"><path d="M5 12.5 9.5 17 19 7" /></svg>
                            </button>
                          </div>
                        </div>
                      </div>
                    </section>

                    <section
                      v-else-if="activeTab === 'data'"
                      key="data"
                      class="settings-page usage-summary-page"
                      data-tutorial="personal-page-usage"
                    >
                      <div class="usage-summary-card settings-stats-card">
                        <div class="usage-summary-header">
                          <div>
                            <p class="usage-summary-eyebrow">对话用量</p>
                            <h3>用量统计</h3>
                            <p class="usage-summary-desc">
                              累计统计所有对话的输入/输出 Token、对话数量、用户消息与工具调用
                            </p>
                          </div>
                        </div>
                        <div class="usage-summary-grid usage-summary-grid--tokens">
                          <div class="usage-summary-item">
                            <div class="label">累计输入</div>
                            <div class="value value--success">
                              {{ formatTokenCount(usageSummary.total_input_tokens) }}
                            </div>
                          </div>
                          <div class="usage-summary-item">
                            <div class="label">累计输出</div>
                            <div class="value value--warning">
                              {{ formatTokenCount(usageSummary.total_output_tokens) }}
                            </div>
                          </div>
                        </div>
                        <div class="usage-summary-grid usage-summary-grid--counts">
                          <div class="usage-summary-item">
                            <div class="label">总对话数</div>
                            <div class="value">
                              {{ formatTokenCount(usageSummary.total_conversations) }}
                            </div>
                          </div>
                          <div class="usage-summary-item">
                            <div class="label">用户消息数</div>
                            <div class="value">
                              {{ formatTokenCount(usageSummary.total_user_messages) }}
                            </div>
                          </div>
                          <div class="usage-summary-item">
                            <div class="label">工具调用次数</div>
                            <div class="value">
                              {{ formatTokenCount(usageSummary.total_tools) }}
                            </div>
                          </div>
                        </div>
                        <div class="usage-summary-meta">
                          <span v-if="usageError" class="usage-summary-error">{{ usageError }}</span
                          ><span v-else-if="usageLoading">正在同步最新统计...</span
                          ><span v-else>最近更新：{{ usageUpdatedText }}</span
                          ><button
                            type="button"
                            class="usage-summary-refresh"
                            @click="fetchUsageSummary"
                            :disabled="usageLoading"
                          >
                            {{ usageLoading ? '刷新中...' : '刷新数据' }}
                          </button>
                        </div>
                      </div>
                    </section>

                    <section
                      v-else-if="activeTab === 'admin'"
                      key="admin"
                      class="settings-page admin-monitor-page"
                    >
                      <div class="settings-action-row" v-if="showMcpConfigEntry">
                        <span class="settings-row-copy"
                          ><span class="settings-row-title">MCP 服务器管理</span
                          ><span class="settings-row-desc"
                            >统一配置 MCP Server，集中管理工具扩展能力</span
                          ></span
                        ><button
                          type="button"
                          class="settings-secondary-button"
                          @click="openMcpConfig"
                        >
                          打开
                        </button>
                      </div>
                      <div class="settings-action-row">
                        <span class="settings-row-copy"
                          ><span class="settings-row-title">管理员监控入口</span
                          ><span class="settings-row-desc"
                            >展示配额趋势、容器运行、项目存储与上传安全</span
                          ></span
                        ><button
                          type="button"
                          class="settings-secondary-button"
                          @click="openAdminPanel"
                        >
                          打开
                        </button>
                      </div>
                      <div class="settings-action-row">
                        <span class="settings-row-copy"
                          ><span class="settings-row-title">API 管理</span
                          ><span class="settings-row-desc">管理 API 调用与账户</span></span
                        ><button
                          type="button"
                          class="settings-secondary-button"
                          @click="openApiAdmin"
                        >
                          打开
                        </button>
                      </div>
                      <div class="settings-action-row">
                        <span class="settings-row-copy"
                          ><span class="settings-row-title">自定义工具管理</span
                          ><span class="settings-row-desc"
                            >在线创建/编辑自定义工具文件</span
                          ></span
                        ><button
                          type="button"
                          class="settings-secondary-button"
                          @click="openCustomTools"
                        >
                          打开
                        </button>
                      </div>
                    </section>
                  </transition>
                </div>

                <div class="settings-save-bar">
                  <div class="personal-status-group">
                    <transition name="personal-status-fade"
                      ><span class="status success" v-if="status">{{ status }}</span></transition
                    ><transition name="personal-status-fade"
                      ><span class="status error" v-if="error">{{ error }}</span></transition
                    >
                  </div>
                  <button type="submit" class="settings-primary-button" :disabled="saving">
                    {{ saving ? '保存中...' : '保存设置' }}
                  </button>
                </div>
              </section>
            </div>
          </form>
        </div>
        <div class="personalization-loading" v-else>正在加载个性化配置...</div>
      </div>
    </div>
  </transition>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, nextTick, onBeforeUnmount } from 'vue';
import { storeToRefs } from 'pinia';
import { usePersonalizationStore } from '@/stores/personalization';
import { useResourceStore } from '@/stores/resource';
import { useUiStore, persistDefaultHideWorkspace } from '@/stores/ui';
import { usePolicyStore } from '@/stores/policy';
import { useTutorialStore } from '@/stores/tutorial';
import { useModelStore } from '@/stores/model';
import { formatTokenCount } from '@/utils/formatters';
import { ICONS } from '@/utils/icons';
import { useTheme } from '@/utils/theme';
import type { ThemeKey } from '@/utils/theme';

defineOptions({ name: 'PersonalizationDrawer' });

const personalization = usePersonalizationStore();
const resourceStore = useResourceStore();
const uiStore = useUiStore();
const tutorialStore = useTutorialStore();
const {
  visible,
  loading,
  form,
  tonePresets,
  newConsideration,
  maxConsiderations,
  status,
  error,
  saving,
  toggleUpdating,
  toolCategories,
  skillsCatalog,
  thinkingIntervalDefault,
  thinkingIntervalRange,
  recentConversationsPromptLimitRange,
  experiments
} = storeToRefs(personalization);

// ---- 目标模式设置辅助 ----
const goalTokenLimitEnabled = computed(
  () => typeof form.value.goal_max_tokens === 'number' && form.value.goal_max_tokens > 0
);

const clampGoalMaxTurns = (raw: any): number => {
  const n = Math.round(Number(raw));
  if (!Number.isFinite(n)) return 5;
  return Math.min(100, Math.max(1, n));
};

const clampGoalMaxTokens = (raw: any): number => {
  const n = Math.round(Number(raw));
  if (!Number.isFinite(n)) return 100000;
  return Math.min(100000000, Math.max(1000, n));
};

const toggleGoalTokenLimit = (enabled: boolean) => {
  personalization.updateField({
    key: 'goal_max_tokens',
    value: enabled ? form.value.goal_max_tokens || 100000 : null
  });
};

type IconKey = keyof typeof ICONS;

type PersonalTab =
  | 'general'
  | 'preferences'
  | 'model'
  | 'appearance'
  | 'workspace'
  | 'context'
  | 'tools'
  | 'files'
  | 'data'
  | 'admin';

const baseTabs = [
  { id: 'general', label: '常规', icon: 'settings' },
  { id: 'preferences', label: '个性化', icon: 'userPen' },
  { id: 'model', label: '模型与思考', icon: 'brainCog' },
  { id: 'appearance', label: '外观与显示', icon: 'monitor' },
  { id: 'workspace', label: '工作区与权限', icon: 'folder' },
  { id: 'context', label: '上下文', icon: 'chatBubble' },
  { id: 'tools', label: '工具与 Skills', icon: 'wrench' },
  { id: 'files', label: '文件与图片', icon: 'file' },
  { id: 'data', label: '数据管理', icon: 'layers' }
] as const satisfies ReadonlyArray<{ id: PersonalTab; label: string; icon: IconKey }>;

const sessionRole = ref('');
const sessionHostMode = ref(false);

const isAdmin = computed(() => {
  const quotaRole = (resourceStore.usageQuota.role || '').toLowerCase();
  const loginRole = (sessionRole.value || '').toLowerCase();
  return quotaRole === 'admin' || loginRole === 'admin';
});
const isHostMode = computed(() => {
  const mode = (resourceStore.containerStatus?.mode || '').toLowerCase();
  if (mode) {
    return mode === 'host';
  }
  return sessionHostMode.value;
});
const showMcpConfigEntry = computed(() => isAdmin.value && isHostMode.value);
const isAppShell = computed(() => {
  if (typeof window === 'undefined') return false;
  const params = new URLSearchParams(window.location.search);
  if (params.has('app_shell')) return true;
  return Boolean((window as any)?.AndroidThemeBridge);
});

const personalTabs = computed(() => {
  const tabs: Array<{ id: PersonalTab; label: string; icon: IconKey }> = [...baseTabs];
  if (isAdmin.value) {
    tabs.push({ id: 'admin', label: '管理员', icon: 'wrench' });
  }
  return tabs;
});

const activeTab = ref<PersonalTab>('general');
const activeDropdown = ref<string | null>(null);
const floatingMenuStyle = ref<Record<string, string>>({});

const activeTabLabel = computed(() => {
  return personalTabs.value.find((tab) => tab.id === activeTab.value)?.label || '常规';
});

const updateFloatingMenuPosition = async () => {
  if (!activeDropdown.value || typeof window === 'undefined') {
    floatingMenuStyle.value = {};
    return;
  }
  await nextTick();
  const button = document.querySelector<HTMLElement>(
    '.settings-select-wrap.open .settings-select-button'
  );
  if (!button) {
    return;
  }
  const rect = button.getBoundingClientRect();
  const menuWidth = Math.min(300, Math.max(240, window.innerWidth - 32));
  const left = Math.max(16, Math.min(rect.right - menuWidth, window.innerWidth - menuWidth - 16));
  const top = Math.max(16, Math.min(rect.bottom + 10, window.innerHeight - 80));
  floatingMenuStyle.value = {
    position: 'fixed',
    top: `${Math.round(top)}px`,
    left: `${Math.round(left)}px`,
    right: 'auto',
    width: `${Math.round(menuWidth)}px`,
    zIndex: '2147483647'
  };
};

const toggleDropdown = async (key: string) => {
  activeDropdown.value = activeDropdown.value === key ? null : key;
  await updateFloatingMenuPosition();
};

const closeDropdown = () => {
  activeDropdown.value = null;
  floatingMenuStyle.value = {};
};

const settingsTabIconStyle = (icon: IconKey) => ({
  '--icon-src': `url(${ICONS[icon]})`
});

onMounted(() => {
  window.addEventListener('resize', updateFloatingMenuPosition);
  window.addEventListener('scroll', updateFloatingMenuPosition, true);
});

onBeforeUnmount(() => {
  window.removeEventListener('resize', updateFloatingMenuPosition);
  window.removeEventListener('scroll', updateFloatingMenuPosition, true);
});

type RunModeValue = 'fast' | 'thinking' | 'deep' | null;
type PermissionModeValue = 'readonly' | 'approval' | 'auto_approval' | 'unrestricted';
type CompressionField =
  | 'shallow_compress_trigger_tokens'
  | 'shallow_compress_keep_recent_tools'
  | 'shallow_compress_keep_user_turn_tools'
  | 'shallow_compress_max_replace_per_round'
  | 'shallow_compress_trigger_tool_calls_interval'
  | 'deep_compress_trigger_tokens';

const runModeOptions: Array<{
  id: string;
  label: string;
  desc: string;
  value: RunModeValue;
  badge?: string;
}> = [
  { id: 'fast', label: '快速模式', desc: '追求响应速度，跳过思考模型', value: 'fast' },
  { id: 'thinking', label: '思考模式', desc: '首轮回复会先输出思考过程', value: 'thinking' },
  { id: 'deep', label: '深度思考', desc: '整轮对话都使用思考模型', value: 'deep' }
];

const permissionModeOptions: Array<{
  id: PermissionModeValue;
  label: string;
  desc: string;
}> = [
  { id: 'readonly', label: '只读', desc: '仅允许读取/检索类工具，修改操作将被拒绝' },
  { id: 'approval', label: '批准', desc: '对工作区文件进行修改的工具需人工批准后执行' },
  {
    id: 'auto_approval',
    label: '自动审核',
    desc: '工作区内写入直通；高风险操作由后台审核智能体自动审批'
  },
  { id: 'unrestricted', label: '无限制', desc: '工具按常规流程直接执行' }
];

const policyStore = usePolicyStore();
const modelStore = useModelStore();

const filteredModelOptions = computed(() =>
  (modelStore.models || []).map((opt: any) => {
    const multimodal = String(opt.multimodal || 'none');
    return {
      id: opt.key,
      value: opt.key,
      label: opt.label,
      desc: opt.description || '',
      badge: multimodal === 'image,video' ? '图文' : opt.deepOnly ? '深度思考' : undefined,
      deepOnly: !!opt.deepOnly,
      fastOnly: !!opt.fastOnly,
      disabled: policyStore.disabledModelSet.has(opt.key)
    };
  })
);

const thinkingPresets = [
  { id: 'low', label: '低', value: 10 },
  { id: 'medium', label: '中', value: 5 },
  { id: 'high', label: '高', value: 3 }
];

const imageCompressionOptions = [
  { id: 'original', label: '原图', desc: '不压缩' },
  { id: '1080p', label: '1080p', desc: '最长边不超过 1080p 等比缩放' },
  { id: '720p', label: '720p', desc: '最长边不超过 720p 等比缩放' },
  { id: '540p', label: '540p', desc: '最长边不超过 540p 等比缩放' }
] as const;

const defaultModelLabel = computed(() => {
  return (
    filteredModelOptions.value.find((option: any) => option.value === form.value.default_model)
      ?.label || '未设置'
  );
});

const runModeLabel = computed(() => {
  return runModeOptions.find((option) => isRunModeActive(option.value))?.label || '未设置';
});

const permissionModeLabel = computed(() => {
  return (
    permissionModeOptions.find((option) => option.id === form.value.default_permission_mode)
      ?.label || '未设置'
  );
});

const imageCompressionLabel = computed(() => {
  return (
    imageCompressionOptions.find((option) => option.id === form.value.image_compression)?.label ||
    '未设置'
  );
});

const communicationStyleLabel = computed(() => {
  return form.value.communication_style === 'human_like' ? '拟人' : '默认';
});

const currentBlockDisplayMode = computed(() => experiments.value.blockDisplayMode);

const blockDisplayLabel = computed(() => {
  return (
    blockDisplayOptions.find((option) => option.value === currentBlockDisplayMode.value)?.label ||
    '堆叠动画'
  );
});

const currentCompactMessageDisplay = computed(() => experiments.value.compactMessageDisplay);

const compactMessageDisplayLabel = computed(() => {
  return (
    compactMessageDisplayOptions.find(
      (option) => option.value === currentCompactMessageDisplay.value
    )?.label || '完整信息'
  );
});

const usageSummary = ref({
  total_input_tokens: 0,
  total_output_tokens: 0,
  total_conversations: 0,
  total_user_messages: 0,
  total_tools: 0
});
const usageLoading = ref(false);
const usageError = ref('');
const usageUpdatedAt = ref<string | null>(null);

const usageUpdatedText = computed(() => {
  if (!usageUpdatedAt.value) {
    return '尚未刷新';
  }
  const date = new Date(usageUpdatedAt.value);
  if (Number.isNaN(date.getTime())) {
    return '时间未知';
  }
  return date.toLocaleString('zh-CN', {
    month: '2-digit',
    day: '2-digit',
    hour: '2-digit',
    minute: '2-digit'
  });
});

const appCurrentVersionCode = ref<number | null>(null);
const appCurrentVersionName = ref<string>('');
const appUpdateChecking = ref(false);
const appUpdateError = ref('');
const appUpdateCheckedAt = ref<string | null>(null);
const appUpdateInfo = ref<{
  latestVersionCode: number;
  latestVersionName: string;
  apkUrl: string;
  fileSizeBytes: number;
  changelog?: string;
  publishedAt?: string | null;
  hasUpdate?: boolean | null;
} | null>(null);

if (typeof window !== 'undefined') {
  const params = new URLSearchParams(window.location.search);
  const vcRaw = params.get('app_vc') || '';
  const vnRaw = params.get('app_vn') || '';
  const bridge = (window as any)?.AndroidThemeBridge;
  const bridgeVcRaw =
    bridge && typeof bridge.getAppVersionCode === 'function'
      ? String(bridge.getAppVersionCode() || '')
      : '';
  const bridgeVnRaw =
    bridge && typeof bridge.getAppVersionName === 'function'
      ? String(bridge.getAppVersionName() || '')
      : '';
  // App 端优先使用 Bridge 实时版本，避免 WebView 恢复旧 URL 参数导致显示过期版本号
  const finalVcRaw = bridgeVcRaw || vcRaw;
  const finalVnRaw = bridgeVnRaw || vnRaw;
  appCurrentVersionCode.value = /^\d+$/.test(finalVcRaw) ? Number(finalVcRaw) : null;
  appCurrentVersionName.value = finalVnRaw || '';
}

const hydrateAppVersionFromBridge = () => {
  if (typeof window === 'undefined') return;
  const bridge = (window as any)?.AndroidThemeBridge;
  if (!bridge) return;
  try {
    const vcRaw =
      typeof bridge.getAppVersionCode === 'function'
        ? String(bridge.getAppVersionCode() || '')
        : '';
    const vnRaw =
      typeof bridge.getAppVersionName === 'function'
        ? String(bridge.getAppVersionName() || '')
        : '';
    if (vcRaw && /^\d+$/.test(vcRaw)) {
      appCurrentVersionCode.value = Number(vcRaw);
    }
    if (vnRaw) {
      appCurrentVersionName.value = vnRaw;
    }
  } catch {
    // ignore bridge read failures
  }
};

const appCurrentVersionText = computed(() => {
  return appCurrentVersionName.value || '未知';
});

const appHasUpdate = computed(() => {
  if (!appUpdateInfo.value) return false;
  if (typeof appUpdateInfo.value.hasUpdate === 'boolean') return appUpdateInfo.value.hasUpdate;
  if (appCurrentVersionCode.value == null) return false;
  return Number(appUpdateInfo.value.latestVersionCode || 0) > appCurrentVersionCode.value;
});

const appDownloadUrl = computed(() => appUpdateInfo.value?.apkUrl || '');

const appUpdateStateText = computed(() => {
  if (!appUpdateInfo.value) return '未检查';
  return appHasUpdate.value ? '发现新版本' : '已是最新';
});

const appUpdateCheckedText = computed(() => {
  if (!appUpdateCheckedAt.value) return '尚未检查更新';
  const d = new Date(appUpdateCheckedAt.value);
  if (Number.isNaN(d.getTime())) return '刚刚检查过';
  return `最近检查：${d.toLocaleString('zh-CN', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' })}`;
});

const fetchUsageSummary = async () => {
  if (usageLoading.value) {
    return;
  }
  usageLoading.value = true;
  usageError.value = '';
  try {
    const response = await fetch('/api/conversations/statistics');
    const payload = await response.json();
    if (!response.ok || !payload.success) {
      throw new Error(payload.error || payload.message || '获取用量统计失败');
    }
    const data = payload.data || {};
    const tokenStats = data.token_statistics || {};
    usageSummary.value = {
      total_input_tokens: Number(tokenStats.total_input_tokens || 0),
      total_output_tokens: Number(tokenStats.total_output_tokens || 0),
      total_conversations: Number(data.total_conversations || 0),
      total_user_messages: Number(data.total_user_messages || 0),
      total_tools: Number(data.total_tools || 0)
    };
    usageUpdatedAt.value = new Date().toISOString();
  } catch (error: any) {
    usageError.value = error?.message || '获取用量统计失败';
  } finally {
    usageLoading.value = false;
  }
};

const checkAppUpdate = async () => {
  if (appUpdateChecking.value) return;
  hydrateAppVersionFromBridge();
  appUpdateChecking.value = true;
  appUpdateError.value = '';
  try {
    const params = new URLSearchParams();
    if (appCurrentVersionCode.value != null) {
      params.set('currentVersionCode', String(appCurrentVersionCode.value));
    }
    const suffix = params.toString() ? `?${params.toString()}` : '';
    const resp = await fetch(`/api/app/version${suffix}`);
    const payload = await resp.json();
    if (!resp.ok || !payload?.success) {
      throw new Error(payload?.error || '检查更新失败');
    }
    const data = payload?.data || {};
    appUpdateInfo.value = {
      latestVersionCode: Number(data.latestVersionCode || 0),
      latestVersionName: String(data.latestVersionName || ''),
      apkUrl: String(data.apkUrl || ''),
      fileSizeBytes: Number(data.fileSizeBytes || 0),
      changelog: String(data.changelog || ''),
      publishedAt: data.publishedAt || null,
      hasUpdate: typeof data.hasUpdate === 'boolean' ? data.hasUpdate : null
    };
    appUpdateCheckedAt.value = new Date().toISOString();
  } catch (error: any) {
    appUpdateError.value = error?.message || '检查更新失败';
  } finally {
    appUpdateChecking.value = false;
  }
};

const downloadLatestApp = () => {
  const url = appDownloadUrl.value;
  if (!url) {
    appUpdateError.value = '未拿到下载地址';
    return;
  }
  window.location.href = url;
};

onMounted(async () => {
  hydrateAppVersionFromBridge();
  try {
    const resp = await fetch('/api/session-status', { credentials: 'same-origin' });
    if (!resp.ok) return;
    const payload = await resp.json();
    const snapshot = payload?.session || {};
    sessionRole.value = String(snapshot.role || '');
    sessionHostMode.value = !!snapshot.host_mode;
  } catch (_err) {
    sessionRole.value = '';
  }
});

watch(
  () => [activeTab.value, visible.value],
  ([tab, isVisible]) => {
    if (isVisible && tab === 'data') {
      fetchUsageSummary();
    }
    if (
      isVisible &&
      tab === 'general' &&
      isAppShell.value &&
      !appUpdateInfo.value &&
      !appUpdateChecking.value
    ) {
      checkAppUpdate();
    }
  }
);

const setActiveTab = (tab: PersonalTab) => {
  activeTab.value = tab;
  closeDropdown();
};

const startTutorial = () => {
  fetch('/api/tutorial-status', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'same-origin',
    body: JSON.stringify({ tutorial_completed: true })
  }).catch(() => {});
  tutorialStore.markCompleted();
  personalization.closeDrawer();
  window.setTimeout(() => {
    tutorialStore.startTutorial();
  }, 320);
};

const applyThinkingPreset = (value: number) => {
  personalization.setThinkingInterval(value);
};

const isRunModeActive = (value: RunModeValue) => {
  if (value === null) {
    return !form.value.default_run_mode;
  }
  return form.value.default_run_mode === value;
};

const setDefaultRunMode = (value: RunModeValue) => {
  if (checkModeModelConflict(value, form.value.default_model)) {
    return;
  }
  personalization.setDefaultRunMode(value);
};

const setDefaultModel = (value: string) => {
  if (policyStore.disabledModelSet.has(value)) {
    uiStore.pushToast({
      title: '模型被禁用',
      message: '已被管理员禁用，无法选择',
      type: 'warning'
    });
    return;
  }
  if (checkModeModelConflict(form.value.default_run_mode, value)) {
    return;
  }
  personalization.setDefaultModel(value);
};

const setDefaultPermissionMode = (value: PermissionModeValue) => {
  personalization.setDefaultPermissionMode(value);
};

const setCommunicationStyle = (value: 'default' | 'human_like') => {
  personalization.setCommunicationStyle(value);
};

const selectDefaultModel = (value: string) => {
  setDefaultModel(value);
  closeDropdown();
};

const selectDefaultRunMode = (value: RunModeValue) => {
  setDefaultRunMode(value);
  closeDropdown();
};

const selectDefaultPermissionMode = (value: PermissionModeValue) => {
  setDefaultPermissionMode(value);
  closeDropdown();
};

const selectCommunicationStyle = (value: 'default' | 'human_like') => {
  setCommunicationStyle(value);
  closeDropdown();
};

const selectImageCompression = (value: (typeof imageCompressionOptions)[number]['id']) => {
  personalization.setImageCompression(value);
  closeDropdown();
};

const selectBlockDisplayMode = (mode: 'traditional' | 'stacked' | 'minimal') => {
  handleBlockDisplayModeChange(mode);
  closeDropdown();
};

const checkModeModelConflict = (mode: RunModeValue, model: string | null): boolean => {
  const found = (filteredModelOptions.value || []).find((item: any) => item.value === model);
  const warnings: string[] = [];
  if (found?.deepOnly && mode && mode !== 'deep') {
    warnings.push(`${found.label} 仅支持深度思考模式，已保持原设置。`);
  }
  if (found?.fastOnly && mode && mode !== 'fast') {
    warnings.push(`${found.label} 仅支持快速模式，已保持原设置。`);
  }
  if (warnings.length) {
    uiStore.pushToast({
      title: '模型/思考模式不兼容',
      message: warnings.join(' '),
      type: 'warning',
      duration: 6000
    });
    return true;
  }
  return false;
};

const handleThinkingInput = (event: Event) => {
  const target = event.target as HTMLInputElement;
  if (!target.value) {
    personalization.setThinkingInterval(null);
    return;
  }
  const parsed = Number(target.value);
  personalization.setThinkingInterval(Number.isNaN(parsed) ? null : parsed);
};

const restoreThinkingInterval = () => {
  personalization.setThinkingInterval(null);
};

const handleRecentConversationsPromptLimitInput = (event: Event) => {
  const target = event.target as HTMLInputElement | null;
  if (!target) {
    return;
  }
  personalization.updateField({
    key: 'recent_conversations_prompt_limit',
    value: target.value
  });
};

const commitRecentConversationsPromptLimitInput = (event: Event) => {
  const target = event.target as HTMLInputElement | null;
  if (!target || !target.value) {
    personalization.setRecentConversationsPromptLimit(null);
    return;
  }
  const parsed = Number(target.value);
  personalization.setRecentConversationsPromptLimit(Number.isNaN(parsed) ? null : parsed);
};

const restoreRecentConversationsPromptLimit = () => {
  personalization.setRecentConversationsPromptLimit(null);
};

const handleCompressionNumberInput = (key: CompressionField, event: Event) => {
  const target = event.target as HTMLInputElement | null;
  if (!target || !target.value) {
    personalization.updateField({ key, value: null });
    return;
  }
  const parsed = Number(target.value);
  if (!Number.isFinite(parsed)) {
    personalization.updateField({ key, value: null });
    return;
  }
  personalization.updateField({ key, value: Math.round(parsed) });
};

const restoreCompressionDefaults = () => {
  personalization.updateField({ key: 'shallow_compress_trigger_tokens', value: null });
  personalization.updateField({ key: 'shallow_compress_keep_recent_tools', value: null });
  personalization.updateField({ key: 'shallow_compress_max_replace_per_round', value: null });
  personalization.updateField({ key: 'shallow_compress_trigger_tool_calls_interval', value: null });
  personalization.updateField({ key: 'deep_compress_trigger_tokens', value: null });
};

const isPresetActive = (value: number) => {
  if (
    form.value.thinking_interval === null ||
    typeof form.value.thinking_interval === 'undefined'
  ) {
    return value === thinkingIntervalDefault.value;
  }
  return form.value.thinking_interval === value;
};

const toggleCategory = (categoryId: string) => {
  personalization.toggleDefaultToolCategory(categoryId);
};

const blockDisplayOptions = [
  {
    id: 'traditional',
    label: '传统列表',
    desc: '按时间顺序垂直排列，经典样式',
    value: 'traditional' as const
  },
  {
    id: 'stacked',
    label: '堆叠动画',
    desc: '超过 6 条自动收纳为"更多"，动态展示',
    value: 'stacked' as const,
    badge: '推荐'
  },
  {
    id: 'minimal',
    label: '极简模式',
    desc: '摘要行 + 无缝展开，流式输出效果',
    value: 'minimal' as const,
    badge: '新'
  }
];

const handleBlockDisplayModeChange = (mode: 'traditional' | 'stacked' | 'minimal') => {
  personalization.setBlockDisplayMode(mode);
};

const compactMessageDisplayOptions = [
  {
    id: 'full',
    label: '完整信息',
    desc: '审核、子智能体等系统消息显示完整原始内容',
    value: 'full' as const
  },
  {
    id: 'brief',
    label: '简略信息',
    desc: '用一行横线概要替代系统消息',
    value: 'brief' as const
  }
];

const selectCompactMessageDisplay = (mode: 'full' | 'brief') => {
  personalization.setCompactMessageDisplay(mode);
  closeDropdown();
};

const openAdminPanel = () => {
  window.open('/admin/monitor', '_blank', 'noopener');
  personalization.closeDrawer();
};

const openCustomTools = () => {
  window.open('/admin/custom-tools', '_blank', 'noopener');
  personalization.closeDrawer();
};

const openApiAdmin = () => {
  window.open('/admin/api', '_blank', 'noopener');
  personalization.closeDrawer();
};

const openMcpConfig = () => {
  window.open('/admin/policy', '_blank', 'noopener');
  personalization.closeDrawer();
};

// ===== 主题切换 =====
const { setTheme, loadTheme } = useTheme();
const themeOptions: Array<{ id: ThemeKey; label: string; desc: string; swatches: string[] }> = [
  {
    id: 'classic',
    label: '经典',
    desc: '米色质感，柔和高对比',
    swatches: ['#eeece2', '#f7f3ea', '#da7756']
  },
  {
    id: 'light',
    label: '明亮',
    desc: '纯白底色 + 优雅灰，简洁清爽',
    swatches: ['#ffffff', '#f7f7f8', '#6b7280']
  },
  {
    id: 'dark',
    label: '夜间',
    desc: '深灰 + 黑，低亮度并保持彩色点缀',
    swatches: ['#1a1a1a', '#2a2a2a', '#3a3a3a']
  }
];

const activeTheme = ref<ThemeKey>(loadTheme());

const themeLabel = computed(() => {
  return themeOptions.find((option) => option.id === activeTheme.value)?.label || '经典';
});

// 监听store中的theme变化，同步到activeTheme（用于从后端加载主题后更新UI）
watch(
  () => personalization.form.theme,
  (newTheme) => {
    if (newTheme && newTheme !== activeTheme.value) {
      activeTheme.value = newTheme as ThemeKey;
      setTheme(newTheme as ThemeKey);
    }
  },
  { immediate: true }
);

const selectThemeOption = (theme: ThemeKey) => {
  applyThemeOption(theme);
  closeDropdown();
};

const applyThemeOption = async (theme: ThemeKey) => {
  activeTheme.value = theme;
  setTheme(theme);

  // 同步更新到store并保存到后端配置文件
  personalization.updateField({ key: 'theme', value: theme });

  try {
    const resp = await fetch('/api/personalization', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ theme })
    });
    const result = await resp.json();
    if (!resp.ok || !result.success) {
      console.warn('保存主题到后端失败:', result.error);
    }
  } catch (error) {
    console.warn('保存主题到后端失败:', error);
  }
};

const applyDefaultHideWorkspaceOption = async (hidden: boolean) => {
  const next = !!hidden;
  persistDefaultHideWorkspace(next);
  personalization.updateField({ key: 'default_hide_workspace', value: next });
  if (next) {
    uiStore.setWorkspaceCollapsed(true);
  }

  try {
    const resp = await fetch('/api/personalization', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ default_hide_workspace: next })
    });
    const result = await resp.json();
    if (!resp.ok || !result.success) {
      console.warn('保存默认隐藏工作区失败:', result.error);
    }
  } catch (error) {
    console.warn('保存默认隐藏工作区失败:', error);
  }
};
</script>

<style scoped>
.settings-redesign-card {
  --settings-floating-menu-bg: #ffffff;
  --settings-floating-menu-hover: rgba(0, 0, 0, 0.055);
  --settings-floating-menu-shadow: none;
  --settings-tab-hover-bg: var(--theme-tab-active, rgba(0, 0, 0, 0.055));
  --settings-tab-active-bg: var(--theme-tab-active, rgba(0, 0, 0, 0.078));
  position: relative;
  width: min(70vw, calc(100vw - 24px));
  height: min(80vh, calc(100vh - 24px));
  padding: 30px 42px 24px;
  border-radius: 32px;
  overflow: visible;
  background: var(--theme-surface-soft, var(--claude-panel));
  border: 1px solid var(--theme-control-border, var(--claude-border));
  box-shadow: none;
}

:global(html[data-theme='dark']) .settings-redesign-card,
:global(body[data-theme='dark']) .settings-redesign-card {
  --settings-floating-menu-bg: #1a1a1a;
  --settings-floating-menu-hover: rgba(255, 255, 255, 0.08);
  --settings-floating-menu-shadow: none;
  --settings-tab-hover-bg: rgba(255, 255, 255, 0.078);
  --settings-tab-active-bg: rgba(255, 255, 255, 0.078);
}

.settings-close-button {
  position: absolute;
  top: 27px;
  left: 45px;
  width: 42px;
  height: 42px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--claude-text);
  display: grid;
  place-items: center;
  cursor: pointer;
  z-index: 3;
}

.settings-close-button:hover {
  background: var(--theme-hover-bg, rgba(0, 0, 0, 0.06));
}

.settings-close-button svg {
  width: 25px;
  height: 25px;
  stroke-width: 2.15;
}

.settings-redesign-body,
.settings-redesign-form {
  height: 100%;
  min-height: 0;
}

.settings-redesign-layout {
  height: 100%;
  display: grid;
  grid-template-columns: minmax(190px, 2fr) minmax(0, 8fr);
  column-gap: 34px;
  min-height: 0;
}

.settings-redesign-tabs {
  margin-top: 68px;
  height: calc(100% - 68px);
  padding-right: 28px;
  border-right: 1px solid var(--theme-control-border, var(--claude-border));
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.settings-redesign-tab {
  width: 100%;
  height: 47px;
  flex: 0 0 auto;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--claude-text);
  padding: 0 13px;
  display: flex;
  align-items: center;
  gap: 14px;
  cursor: pointer;
  text-align: left;
  font-size: 16px;
  letter-spacing: -0.01em;
}

.settings-redesign-tab:hover {
  background: var(--settings-tab-hover-bg);
}

.settings-redesign-tab.active {
  background: var(--settings-tab-active-bg);
  font-weight: 640;
}

.settings-tab-icon {
  --icon-size: 20px;
  flex: 0 0 auto;
}

.settings-tab-icon--chat {
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: -5px;
  margin-right: -5px;
}

.settings-tab-icon--chat svg {
  width: 30px;
  height: 30px;
}

.settings-redesign-content {
  min-width: 0;
  min-height: 0;
  height: 100%;
  overflow: visible;
  display: flex;
  flex-direction: column;
  position: relative;
}

.settings-redesign-content-header {
  height: 46px;
  flex: 0 0 46px;
  display: flex;
  align-items: center;
}

.settings-redesign-content-header h2 {
  margin: 0;
  color: var(--claude-text);
  font-size: 28px;
  line-height: 1;
  letter-spacing: -0.045em;
  font-weight: 730;
}

.settings-redesign-title-line {
  height: 1px;
  background: var(--theme-control-border, var(--claude-border));
  margin: 22px 0 8px;
  flex: 0 0 1px;
}

.settings-redesign-scroll {
  min-height: 0;
  flex: 1 1 auto;
  overflow-y: auto;
  overflow-x: visible;
  padding-right: 18px;
  padding-bottom: 86px;
  scroll-padding-bottom: 86px;
  scrollbar-width: none;
  -ms-overflow-style: none;
}


.settings-redesign-tabs::-webkit-scrollbar,
.settings-redesign-scroll::-webkit-scrollbar,
.settings-floating-menu::-webkit-scrollbar,
.app-update-changelog-content::-webkit-scrollbar {
  display: none;
}

.settings-floating-menu,
.app-update-changelog-content {
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.settings-page {
  max-width: 900px;
  min-height: 0;
}

.settings-select-row,
.settings-input-row,
.settings-list-row,
.settings-action-row,
.settings-toggle-row {
  min-height: 64px;
  border-bottom: 1px solid var(--theme-control-border, var(--claude-border));
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 18px;
  padding: 11px 0;
  color: var(--claude-text);
}

.settings-list-row.tall,
.settings-input-row.stackable {
  align-items: flex-start;
}

.settings-list-row.tall {
  grid-template-columns: minmax(180px, 1fr) minmax(0, 360px);
}

.settings-row-copy {
  min-width: 0;
  display: block;
}

.settings-row-title {
  display: block;
  color: var(--claude-text);
  font-size: 14px;
  font-weight: 550;
  letter-spacing: -0.01em;
  line-height: 1.32;
}

.settings-row-desc {
  display: block;
  margin-top: 3px;
  color: var(--claude-text-secondary);
  font-size: 12.5px;
  line-height: 1.38;
}

.settings-select-wrap {
  position: relative;
  display: inline-flex;
  justify-self: end;
}

.settings-select-button {
  width: max-content;
  min-width: 0;
  height: 36px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--claude-text);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 8px 0 10px;
  cursor: pointer;
  font-size: 15px;
  white-space: nowrap;
}

.settings-select-button:hover {
  background: var(--theme-hover-bg, rgba(0, 0, 0, 0.055));
}

.settings-select-button .select-chevron {
  width: 12px;
  height: 12px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.15s ease;
}

.settings-select-button .select-chevron::before {
  content: '';
  width: 7px;
  height: 7px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-1.5px) rotate(45deg);
}

.settings-select-wrap.open .settings-select-button .select-chevron {
  transform: rotate(180deg);
}

.settings-floating-menu {
  position: fixed;
  right: auto;
  top: auto;
  width: 300px;
  max-height: min(420px, 60vh);
  overflow: auto;
  padding: 6px;
  border-radius: 20px;
  background: var(--settings-floating-menu-bg);
  border: 1px solid var(--theme-control-border, var(--claude-border));
  box-shadow: var(--settings-floating-menu-shadow);
  opacity: 1;
  backdrop-filter: none;
  z-index: 2147483647;
  display: none;
}

.settings-select-wrap.open .settings-floating-menu {
  display: block;
}

.settings-floating-menu.dark {
  background: #1a1a1a !important;
  box-shadow: none !important;
}

.settings-floating-menu.dark .settings-menu-option:hover {
  background: rgba(255, 255, 255, 0.08) !important;
}

:global(html[data-theme='dark']) :global(.settings-floating-menu),
:global(body[data-theme='dark']) :global(.settings-floating-menu) {
  background: #1a1a1a !important;
  box-shadow: none !important;
}

:global(html[data-theme='dark']) :global(.settings-menu-option:hover),
:global(body[data-theme='dark']) :global(.settings-menu-option:hover) {
  background: rgba(255, 255, 255, 0.08) !important;
}

.settings-menu-option {
  width: 100%;
  min-height: 38px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--claude-text);
  display: grid;
  grid-template-columns: minmax(0, 1fr) 22px;
  row-gap: 0;
  column-gap: 8px;
  align-items: center;
  padding: 7px 10px;
  text-align: left;
  cursor: pointer;
}

.settings-menu-option:hover {
  background: var(--settings-floating-menu-hover);
}

.settings-menu-option:disabled {
  opacity: 0.48;
  cursor: not-allowed;
}

.settings-menu-option strong {
  grid-column: 1;
  grid-row: 1;
  display: block;
  color: var(--claude-text);
  font-size: 15px;
  font-weight: 550;
  letter-spacing: -0.01em;
  min-width: 0;
}

.settings-menu-option span {
  grid-column: 1;
  grid-row: 2;
  display: block;
  margin-top: 0;
  color: var(--claude-text-secondary);
  font-size: 11px;
  line-height: 1.15;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.settings-menu-option svg {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  width: 21px;
  height: 21px;
  fill: none;
  stroke: var(--claude-text);
  stroke-width: 2.25;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
}

.settings-menu-option.selected svg {
  opacity: 1;
}

.settings-input-row input,
.settings-add-row input,
.settings-number-row input,
.settings-number-input,
.settings-compression-grid input {
  height: 38px;
  border: 1px solid var(--theme-control-border, var(--claude-border));
  border-radius: 12px;
  background: transparent;
  color: var(--claude-text);
  padding: 0 12px;
  outline: none;
  font-size: 13px;
}

.settings-number-input {
  width: 120px;
  text-align: right;
}

.settings-section-divider {
  display: flex;
  align-items: center;
  margin: 18px 0 6px;
}
.settings-section-divider__label {
  font-size: 12px;
  font-weight: 600;
  color: var(--claude-text-secondary, #7f7766);
  letter-spacing: 0.04em;
}
.settings-section-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  margin-left: 10px;
  background: var(--theme-control-border, var(--claude-border));
}

.settings-input-row > input {
  width: min(360px, 40vw);
  text-align: right;
}

.settings-input-row input:focus,
.settings-add-row input:focus,
.settings-number-row input:focus,
.settings-number-input:focus,
.settings-compression-grid input:focus {
  border-color: var(--claude-text-secondary);
  box-shadow: none;
}

.settings-input-stack {
  width: min(430px, 46vw);
  display: grid;
  gap: 8px;
  justify-self: end;
}

.settings-input-stack.wide {
  width: min(360px, 42vw);
}

.settings-input-stack input {
  width: 100%;
}

.settings-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.settings-chip-row.right {
  justify-content: flex-end;
}

.settings-chip-row button,
.settings-number-row button,
.settings-add-row button,
.settings-secondary-button,
.settings-primary-button {
  border: 1px solid var(--theme-control-border, var(--claude-border));
  border-radius: 999px;
  background: transparent;
  color: var(--claude-text);
  min-height: 32px;
  padding: 0 12px;
  font-size: 12px;
  cursor: pointer;
}

.settings-chip-row button:hover,
.settings-number-row button:hover,
.settings-add-row button:hover,
.settings-secondary-button:hover {
  background: var(--theme-hover-bg, rgba(0, 0, 0, 0.055));
}

.settings-chip-row button.active,
.settings-primary-button {
  border-color: var(--claude-accent);
  background: var(--claude-accent);
  color: #fff;
}

.settings-secondary-button.danger {
  color: var(--claude-warning, #c85f45);
}

.settings-inline-actions {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  flex-wrap: wrap;
}

.settings-inline-actions.right {
  margin-top: 10px;
}

.settings-mini-status {
  color: var(--claude-text-secondary);
  font-size: 12px;
}

.settings-mini-status.warning {
  color: var(--claude-warning, #c85f45);
}

.settings-add-row,
.settings-number-row {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
}

.settings-add-row input,
.settings-number-row input {
  min-width: 0;
  flex: 1 1 auto;
}

.settings-consideration-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 6px;
}

.settings-consideration-list li {
  min-height: 34px;
  border: 1px solid var(--theme-control-border, var(--claude-border));
  border-radius: 12px;
  padding: 0 8px;
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) 28px;
  gap: 8px;
  align-items: center;
  color: var(--claude-text);
  font-size: 13px;
}

.settings-consideration-list button {
  border: 0;
  background: transparent;
  color: var(--claude-text-secondary);
  cursor: pointer;
}

.drag-handle {
  color: var(--claude-text-secondary);
  cursor: grab;
}

.settings-toggle-row {
  cursor: pointer;
  position: relative;
}

.settings-toggle-row input[type='checkbox'] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.settings-toggle-row .fancy-check {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  background: transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: none;
  transition: opacity 0.2s ease;
}

.settings-toggle-row .fancy-check svg {
  width: 22px;
  height: 22px;
  overflow: visible;
}

.fancy-path {
  fill: none;
  stroke: var(--claude-text-secondary);
  stroke-width: 5;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition:
    stroke-dasharray 0.5s ease,
    stroke-dashoffset 0.5s ease,
    stroke 0.2s ease;
  stroke-dasharray: 241 9999999;
  stroke-dashoffset: 0;
}

.settings-toggle-row input:checked + .fancy-check .fancy-path {
  stroke: var(--claude-text-secondary);
  stroke-dasharray: 70.5096664428711 9999999;
  stroke-dashoffset: -262.2723388671875;
}

.settings-group-block {
  border-bottom: 1px solid var(--theme-control-border, var(--claude-border));
  padding: 14px 0 16px;
}

.settings-group-title {
  margin-bottom: 6px;
}

.settings-toggle-row.inner {
  min-height: 48px;
  padding: 7px 0 7px 18px;
  border-bottom: 0;
}

.settings-check-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 26px;
}

.settings-compression-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px 14px;
  margin-top: 10px;
}

.settings-compression-grid label {
  display: grid;
  gap: 5px;
  color: var(--claude-text-secondary);
  font-size: 12px;
}

.settings-save-bar {
  position: absolute;
  right: 18px;
  bottom: 0;
  left: 0;
  min-height: 54px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  background: transparent;
  pointer-events: none;
}

.settings-save-bar > * {
  pointer-events: auto;
}

.personal-status-group {
  min-height: 20px;
  font-size: 12px;
}

.status.success {
  color: var(--claude-success);
}

.status.error,
.usage-summary-error {
  color: var(--claude-warning);
}

.usage-summary-page {
  display: block;
  padding: 0;
}

.settings-stats-card,
.usage-summary-card {
  width: 100%;
  max-width: 720px;
  padding: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.usage-summary-header h3 {
  margin: 4px 0 6px;
  font-size: 20px;
}

.usage-summary-eyebrow {
  margin: 0;
  font-size: 11px;
  color: var(--claude-accent-strong);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.usage-summary-desc,
.usage-summary-note,
.usage-summary-meta {
  margin: 0;
  color: var(--claude-text-secondary);
  font-size: 12px;
}

.usage-summary-grid {
  display: grid;
  gap: 10px;
}

.usage-summary-grid--tokens {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.usage-summary-grid--counts {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.usage-summary-item {
  padding: 12px 14px;
  border-radius: 14px;
  border: 1px solid var(--theme-control-border, var(--claude-border));
  background: transparent;
}

.usage-summary-item .label {
  font-size: 12px;
  color: var(--claude-text-secondary);
}

.usage-summary-item .value {
  margin-top: 4px;
  font-size: 20px;
  font-weight: 600;
  color: var(--claude-text);
}

.usage-summary-item .value--success {
  color: var(--claude-success);
}

.usage-summary-item .value--warning {
  color: var(--claude-warning);
}

.usage-summary-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.usage-summary-refresh {
  border: 1px solid var(--theme-control-border, var(--claude-border));
  border-radius: 999px;
  padding: 7px 14px;
  background: transparent;
  color: var(--claude-text);
  font-size: 12px;
  cursor: pointer;
}

.admin-monitor-page {
  display: block;
  padding: 0;
}

@media (max-width: 900px) {
  .settings-redesign-card {
    width: 100vw;
    height: 100vh;
    border-radius: 0;
    padding: 30px 24px;
  }

  .settings-close-button {
    left: 27px;
    top: 20px;
  }

  .settings-redesign-layout {
    grid-template-columns: 1fr;
    gap: 0;
  }

  .settings-redesign-tabs {
    margin-top: 68px;
    height: auto;
    padding-right: 0;
    padding-bottom: 12px;
    border-right: 0;
    border-bottom: 1px solid var(--theme-control-border, var(--claude-border));
    flex-direction: row;
    overflow: auto;
    scrollbar-width: none;
  }

  .settings-redesign-tabs::-webkit-scrollbar {
    display: none;
  }

  .settings-redesign-tab {
    width: auto;
    white-space: nowrap;
  }

  .settings-redesign-content {
    padding-top: 18px;
  }

  .settings-select-row,
  .settings-input-row,
  .settings-list-row,
  .settings-action-row,
  .settings-toggle-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }

  .settings-select-wrap,
  .settings-input-stack,
  .settings-input-row > input {
    justify-self: stretch;
    width: 100%;
  }

  .settings-select-button {
    margin-left: auto;
  }

  .settings-floating-menu {
    width: min(340px, calc(100vw - 48px));
  }

  .settings-check-grid,
  .settings-compression-grid,
  .usage-summary-grid--tokens,
  .usage-summary-grid--counts {
    grid-template-columns: 1fr;
  }
}
</style>
