﻿/* Chat Shell — styling */
* { box-sizing: border-box; }
/* 修改记录：[Wed 2026-06-10 11:32 GMT+8] 调整 (便于回溯/恢复)
     - 背景：客户要求 chat-shell 输出内容统一微软雅黑显示
     - 修正前：font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
              (Segoe UI 排在微软雅黑前面，英文字母会优先用 Segoe UI)
     - 修正后：font-family: "Microsoft YaHei", "PingFang SC", "PingFang TC", "Hiragino Sans GB", sans-serif;
              (微软雅黑排第一，去掉 Segoe UI 避免英文字母用不同字体)
     - 原因：统一字体，中英文都优先用微软雅黑 */
body, html { margin: 0; padding: 0; height: 100%; font-family: "Microsoft YaHei", "PingFang SC", "PingFang TC", "Hiragino Sans GB", sans-serif; }
#app { height: 100vh; }

.view { display: none; height: 100%; }
.view.active { display: flex; }

/* ===== Login ===== */
#login-view, #change-password-view {
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.login-card {
  background: #fff;
  padding: 2.5rem;
  border-radius: 16px;
  box-shadow: 0 10px 40px rgba(0,0,0,0.2);
  width: 100%;
  max-width: 400px;
}
.login-card h1 { margin: 0 0 0.25rem; font-size: 1.75rem; }
/* [Fri 2026-06-12 08:10 GMT+8] Login title: Logo + WASU Agent */
.login-title-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin-bottom: 0.25rem;
}
.login-logo {
  width: 52px;
  height: 52px;
  border-radius: 12px;
  flex-shrink: 0;
}
.login-title-text {
  margin: 0;
  font-size: 1.6rem;
  font-weight: 700;
  color: #003366;
  letter-spacing: -0.5px;
}
.subtitle { color: #666; margin: 0 0 1.5rem; font-size: 0.8rem; text-align: center; }
.login-hint { color: #999; font-size: 0.82rem; margin-top: 1.2rem; text-align: center; }
.login-hint a { color: #667eea; text-decoration: none; }
.login-hint a:hover { text-decoration: underline; }
.login-card label { display: block; font-size: 0.85rem; color: #555; margin: 0.75rem 0 0.25rem; }
.login-card input {
  width: 100%;
  padding: 0.6rem 0.8rem;
  border: 1px solid #ddd;
  border-radius: 6px;
  font-size: 0.95rem;
}
.login-card input:focus { outline: none; border-color: #667eea; }
.login-card button {
  width: 100%;
  margin-top: 1.25rem;
  padding: 0.7rem;
  background: #667eea;
  color: #fff;
  border: none;
  border-radius: 6px;
  font-size: 1rem;
  cursor: pointer;
}
.login-card button:hover { background: #5568d3; }
.login-error { color: #d32f2f; font-size: 0.85rem; margin: 0.5rem 0 0; min-height: 1.2em; }
.hint { color: #999; font-size: 0.8rem; margin-top: 1rem; text-align: center; }

/* ===== Chat layout ===== */
#chat-view { display: none; }
#chat-view.active { display: flex; }

.sidebar {
  width: 260px;
  background: #f7f8fa;
  border-right: 1px solid #e5e7eb;
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
}
.sidebar-header { padding: 1rem; border-bottom: 1px solid #e5e7eb; }
.primary-btn {
  width: 100%;
  padding: 0.6rem;
  background: #667eea;
  color: #fff;
  border: none;
  border-radius: 6px;
  font-size: 0.9rem;
  cursor: pointer;
}
.primary-btn:hover { background: #5568d3; }
.primary-btn:disabled { background: #aaa; cursor: not-allowed; }

.session-list { flex: 1; overflow-y: auto; padding: 0.5rem; }
.session-item {
  padding: 0.7rem 0.85rem;
  border-radius: 6px;
  cursor: pointer;
  margin-bottom: 0.25rem;
  font-size: 0.9rem;
  color: #333;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  border: 1px solid transparent;
}
.session-item:hover { background: #eceef3; }
.session-item.active { background: #e0e7ff; border-color: #c7d2fe; color: #4338ca; font-weight: 500; }

.sidebar-footer { padding: 1rem; border-top: 1px solid #e5e7eb; }
.user-info {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 0.85rem;
  color: #666;
}

/* Logout text button */
.logout-text-btn {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 0.85rem;
  color: #999;
  font-family: inherit;
  padding: 4px 8px;
  border-radius: 4px;
  transition: color 0.15s, background 0.15s;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.logout-text-btn:hover {
  color: #d32f2f;
  background: #fee;
}

/* 修改记录：[Thu 2026-06-11 20:36 GMT+8] 新增 (便于回溯/恢复)
   - 背景：用户要求在退出左侧增加配置小图标（修改当前用户密码）
   - 实现：复用 .logout-text-btn 样式，调整 hover 为金黄色（区别于退出的红色）*/
#change-pw-icon-btn {
  color: #999;
  padding: 4px 6px;
}
#change-pw-icon-btn:hover {
  color: #b8860b;
  background: #fff8dc;
}

.main-area { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.main-header {
  padding: 1rem 1.5rem;
  border-bottom: 1px solid #e5e7eb;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: #fff;
}
.main-header h2 { margin: 0; font-size: 1.1rem; font-weight: 500; }

/* Right side of header: brand + delete dropdown */
.header-right {
  display: flex;
  align-items: center;
  gap: 1rem;
}

/* 修改记录：[Thu 2026-06-11 20:36 GMT+8] 新增 (便于回溯/恢复)
   - 背景：用户要求在删除按钮右侧增加太阳/月亮主题切换图标
   - 实现：.theme-toggle 行内 flex 布局，两个小图标水平排列 */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.theme-btn {
  background: none;
  border: 1px solid transparent;
  border-radius: 4px;
  padding: 4px 6px;
  cursor: pointer;
  color: #999;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s, background 0.15s, border-color 0.15s;
}
.theme-btn:hover {
  color: #555;
  background: #f0f0f0;
}
.theme-btn.active {
  color: #0078D4;
  background: #e0f0ff;
  border-color: #c7d2fe;
}
.theme-btn svg {
  display: block;
}

/* Gateway status dot + Azure Operation Agent label */
.gw-status {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
  font-size: 12px;
  font-weight: bold;
  color: #4169E1;
  opacity: 1;
}
/* Logo: 高度与 main-header 匹配（header padding 1rem+1.5rem ≈ 40px，font 1.1rem ≈ 17.6px → 总高约 57px），设 logo 高度约 48px */
.gw-logo {
  width: auto;
  height: 48px;
  border-radius: 10px;
  flex-shrink: 0;
}
.gw-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
  background: #f99;
  box-shadow: 0 0 0 2px rgba(255,255,255,0.3);
}
.gw-dot.on { background: #5f5; box-shadow: 0 0 0 2px rgba(95,255,95,0.3); }
.gw-dot.off { background: #f99; }

/* ===== Delete dropdown ===== */
.delete-dropdown {
  position: relative;
  display: inline-block;
}
.delete-dropdown .icon-btn.danger {
  background: none;
  border: 1px solid #f3c2c2;
  border-radius: 6px;
  padding: 4px 10px;
  cursor: pointer;
  font-size: 0.85rem;
  color: #d32f2f;
  font-family: inherit;
  transition: background 0.15s;
}
.delete-dropdown .icon-btn.danger:hover {
  background: #fee;
}

.delete-menu {
  display: none;
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  min-width: 180px;
  z-index: 100;
  overflow: hidden;
  font-size: 0.85rem;
  font-family: inherit;
}
.delete-menu.open {
  display: block;
}
.delete-menu-item {
  padding: 10px 16px;
  cursor: pointer;
  color: #333;
  transition: background 0.12s;
  white-space: nowrap;
}
.delete-menu-item:hover {
  background: #f0f4ff;
  color: #4338ca;
}
.delete-menu-separator {
  height: 1px;
  background: #e5e7eb;
  margin: 2px 0;
}
.delete-menu-item.danger-item {
  color: #d32f2f;
}
.delete-menu-item.danger-item:hover {
  background: #fff0f0;
}

/* Action buttons (attach / voice) */
.action-btn {
  background: none;
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 6px;
  cursor: pointer;
  color: #555;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s, background 0.15s, border-color 0.15s;
  flex-shrink: 0;
}
.action-btn:hover {
  background: #f0f4ff;
  color: #4338ca;
  border-color: #c7d2fe;
}
.action-btn svg {
  width: 20px;
  height: 20px;
}
.action-btn.recording {
  background: #fee;
  border-color: #d32f2f;
  color: #d32f2f;
  animation: pulse 1.2s infinite;
}

/* Keep legacy icon-btn for other uses */
.icon-btn {
  background: none;
  border: 1px solid #ddd;
  border-radius: 6px;
  padding: 0.4rem 0.7rem;
  cursor: pointer;
  font-size: 1rem;
  color: #555;
}
.icon-btn:hover { background: #f0f0f0; }
.icon-btn.danger { color: #d32f2f; border-color: #f3c2c2; }
.icon-btn.danger:hover { background: #fee; }
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } }

/* STT gear spinner — rotating blue gear during transcription */
.stt-gear {
  width: 28px !important;
  height: 28px !important;
  color: #0078d4 !important;
  animation: spin 1s linear infinite !important;
}
@keyframes spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

.messages {
  flex: 1;
  overflow-y: auto;
  padding: 1.5rem;
  background: #fafbfc;
}
.message {
  margin-bottom: 1rem;
  display: flex;
  flex-direction: column;
  /* 修改记录：[Wed 2026-06-10 10:19 GMT+8] 调整 (便于回溯/恢复)
     - 背景：客户要求消息框随浏览器宽度自动缩放，像输入框一样。
     - 修正前：max-width: 80%;（限制消息框只占 80%，浏览器宽了消息框也只到 80%）
     - 修正后：max-width: 95%; min-width: 0;（上限 95% 避免贴边，下限 0 允许狭窄环境收缩）
     - 配合：.bubble 的 word-wrap: break-word 防止超长单词/URL 溢出。
     - 原理：.message 是 flex 容器，max-width 只设上限，默认 width: auto 会按内容收缩；
             加上 95% 后，浏览器越宽消息框越大（最多到 95%），浏览器越窄消息框越窄。
     - 对 Tor Down / Tor Reload / 未来任何聊条都生效。 */
  max-width: 95%;
  min-width: 0;
}
.message.user { align-self: flex-end; }
.message.assistant { align-self: flex-start; }
.message .bubble {
  padding: 0.7rem 1rem;
  border-radius: 12px;
  white-space: pre-wrap;
  word-wrap: break-word;
  line-height: 1.5;
  /* 修改记录：[Mon 2026-06-08 08:27 GMT+8] 调整 (便于回溯/恢复)
     - 在 .bubble 上显式指定 font-family，确保中文使用 微软雅黑
     - 修正前：仅靠 body 继承，依赖操作系统字体回退
     - 修正后：直接指定 "Microsoft YaHei", "微软雅黑" 为主字体 */
  font-family: "Microsoft YaHei", "微软雅黑", "PingFang SC", "Segoe UI", sans-serif;
}
.message.user .bubble { background: #667eea; color: #fff; border-bottom-right-radius: 2px; }
.message.assistant .bubble { background: #fff; color: #333; border: 1px solid #e5e7eb; border-bottom-left-radius: 2px; }
.message .meta { font-size: 0.75rem; color: #999; margin: 0.25rem 0.5rem; }
.message.attachments { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.4rem; }
.message.attachment {
  background: #f0f4ff;
  border: 1px solid #c7d2fe;
  border-radius: 6px;
  padding: 0.3rem 0.6rem;
  font-size: 0.8rem;
  color: #4338ca;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}
.message.attachment:hover { background: #e0e7ff; }

.input-area {
  background: #fff;
  border-top: 1px solid #e5e7eb;
  padding: 0.75rem 1rem 1rem;
}
.attachment-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
}
.attachment-pill {
  background: #f0f4ff;
  border: 1px solid #c7d2fe;
  border-radius: 16px;
  padding: 0.25rem 0.7rem;
  font-size: 0.8rem;
  color: #4338ca;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
}
.attachment-pill .remove { cursor: pointer; color: #999; }
.attachment-pill .remove:hover { color: #d32f2f; }
.attachment-pill.uploading { opacity: 0.6; }

.input-row { display: flex; align-items: end; gap: 0.5rem; }
.input-row .primary-btn { width: auto; flex-shrink: 0; }
#message-input {
  flex: 1 1 auto;
  min-width: 0;
  width: auto;
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 0.6rem 0.8rem;
  font-size: 0.95rem;
  font-family: inherit;
  resize: none;
  /* 修改记录：[Wed 2026-06-10 10:19 GMT+8] 调整 (便于回溯/恢复)
     - 背景：客户要求输入框高度在现有基础上再增加一个行高
     - 修正前：min-height: 80px;（约 3.5 行）
     - 修正后：min-height: 104px;（加 1 行高 ≈ 24px: 0.95rem × 1.5 line-height × 16px = 22.8px）
             → 视觉上从 3.5 行升到 4.5 行，足够输入中等长度的通知描述
     - max-height: 360px 保持不变，限制最长高度避免占用过多视口 */
  min-height: 104px;
  max-height: 360px;
  line-height: 1.5;
  outline: none;
}
#message-input:focus { border-color: #667eea; }

.flag-notice {
  background: #fff3cd;
  color: #856404;
  padding: 0.4rem 0.8rem;
  font-size: 0.8rem;
  border-bottom: 1px solid #ffeeba;
}

/* ===== Pairing-required banner ===== */
.pairing-banner {
  background: #fff7e6;
  border: 1px solid #ffd591;
  border-left: 4px solid #fa8c16;
  padding: 1rem 1.5rem;
  margin: 0.75rem 1rem 0;
  border-radius: 6px;
  color: #5b3e1a;
  font-size: 0.9rem;
}
.pairing-banner-content strong {
  display: block;
  margin-bottom: 0.5rem;
  color: #874d00;
  font-size: 1rem;
}
.pairing-banner p { margin: 0.35rem 0; }
.pairing-command {
  background: #2d2d2d;
  color: #f8f8f2;
  padding: 0.6rem 0.8rem;
  border-radius: 4px;
  font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
  font-size: 0.85rem;
  user-select: all;
  white-space: pre-wrap;
  word-break: break-all;
  margin: 0.5rem 0;
}
.pairing-meta { font-size: 0.8rem; color: #7a5a2a; }
.pairing-meta code { background: rgba(0,0,0,0.06); padding: 0 0.3em; border-radius: 3px; }
.pairing-actions {
  margin-top: 0.6rem;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  flex-wrap: wrap;
}
.pairing-hint { font-size: 0.8rem; color: #7a5a2a; }

/* ===== Markdown rendering inside bubbles ===== */
.bubble h1, .bubble h2, .bubble h3, .bubble h4 {
  margin: 0;
  line-height: 1.3;
  color: #111;
}
.bubble h1 { font-size: 1.3rem; }
.bubble h2 { font-size: 1.15rem; }
.bubble h3 { font-size: 1.05rem; }

/* ===== Section title blocks (Advisory / Details / Same Day PIR / SRC) =====
   修改记录：[Sun 2026-06-07 21:03 GMT+8] 调整 (便于回溯/恢复)
     - 修正前：3 个主标题只是普通粗体，区别不明显
     - 修正后：蓝色背景框 + 数字标识 + 加大字号，视觉上明显区别于正文
*/
.section-title-block {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 12px 0 8px;
  padding: 6px 14px;
  background: linear-gradient(135deg, #e0ebff 0%, #c7d2fe 100%);
  border-left: 4px solid #4169E1;
  border-radius: 6px;
  font-family: 'Microsoft YaHei', '微软雅黑', 'PingFang SC', sans-serif;
}
.section-title-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 28px;
  height: 28px;
  padding: 0 6px;
  background: #4169E1;
  color: #fff;
  font-weight: 700;
  font-size: 1.05rem;
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(65,105,225,0.4);
}
.section-title-text {
  font-weight: 700;
  font-size: 1.15rem;
  color: #4169E1;
  letter-spacing: 0.5px;
}

/* ===== Sub-sep band: 中文版本 / English Version 背景色带 =====
   修改记录：[Wed 2026-06-10 10:38 GMT+8] 新增 (便于回溯/恢复)
     - 背景：客户要求在 Tor Down / Tor Reload Same Day PIR 区的
             "中文版本" / "English Version" 两个 sub-sep 小节标题
             处加一个浅青色 #E0FFFF 背景色带，作为双语切换的视觉分隔。
     - 实现：chat-shell 前端 app.js 的 subSepBandify() 把
             <strong>中文版本</strong> / <strong>English Version</strong>
             所在 <p> 替换为 <div class="sub-sep-band">，
             这里给该 div 加上背景色 + 圆角 + 内边距。
     - 覆盖：任何 matched text 都生效，Tor Down / Tor Reload / 未来
             双语通知都能复用。不需按模板类型修改。
*/
.bubble .sub-sep-band {
  /* 修改记录：[Wed 2026-06-10 11:44 GMT+8] 调整 (便于回溯/恢复)
     - 背景：用户要求"中文版本" / "English Version" 背景色带再淡些
     - 修正前：background-color: #E0FFFF;（较深）
     - 修正后：background-color: #F0FFFF;（更淡的浅青色）
     - 对 Tor Down / Tor Reload / 未来任何双语通知都适用。 */
  background-color: #F0FFFF;
  border-radius: 4px;
  padding: 6px 12px;
  margin: 0.5rem 0;
  text-align: center;
  font-weight: 600;
  color: #0e6e7d;
  border: 1px solid #b0e6ee;
}
.bubble .sub-sep-band strong {
  color: inherit;
  font-weight: 700;
}
.bubble p {
  margin: 0;
  line-height: 1.6;
  /* 修改记录：[Mon 2026-06-08 08:27 GMT+8] 调整 (便于回溯/恢复)
     - 去除段落中所有中文之间的 letter-spacing，默认 0
     - 修正前：依赖浏览器默认 letter-spacing（某些字体会有轻微间距）
     - 修正后：显式 letter-spacing: 0，配合 微软雅黑 让中文紧凑 */
  letter-spacing: 0;
}
.bubble table { margin: 0; }
.bubble ul, .bubble ol { margin: 0; padding-left: 1.5rem; }
.bubble pre { margin: 0; }
.bubble blockquote { margin: 0; }
.bubble hr { margin: 0; }
.bubble > * + * {
  /* 修改记录：[Mon 2026-06-08 08:27 GMT+8] 调整 (便于回溯/恢复)
     - 缩小连续子元素之间的 margin-top，避免空行堆积
     - 修正前：margin-top: 0.3rem（连续多个 <p> 时累积产生明显空行）
     - 修正后：margin-top: 0.1rem（保留轻微呼吸感，但不再产生"额外空行"）
     - 原因：原始 .html 中段落间是 <p style="height:14px"> 1px 间隔；
              多个 .bubble > * + * 0.3rem 累积后导致 chat-shell 看上去空白过多 */
  margin-top: 0.1rem !important;
}
.bubble strong { font-weight: 600; color: #000; }
.bubble a { color: #0563c1; text-decoration: underline; }
.bubble a:hover { color: #004578; }
.bubble em { font-style: italic; }
.bubble code {
  background: #f3f4f6;
  border: 1px solid #e5e7eb;
  border-radius: 4px;
  padding: 0.1em 0.3em;
  font-size: 0.85em;
  font-family: 'Consolas','Monaco','Courier New',monospace;
}

/* ===== .en-term: 英文专业术语用 Segoe UI + 加粗 =====
   修改记录：[Wed 2026-06-10 13:47 GMT+8] 恢复 (便于回溯/恢复)
     - 背景：客户要求 1) 英文用 Segoe UI 2) 专业术语用 Segoe UI + 加粗 3) 中文微软雅黑
*/
.en-term {
  font-family: "Segoe UI", "Microsoft YaHei", "PingFang SC", sans-serif;
  font-weight: 600;
}

.bubble pre {
  background: #1e1e1e;
  color: #d4d4d4;
  border-radius: 6px;
  padding: 0.75rem 1rem;
  overflow-x: auto;
  font-size: 0.85rem;
  line-height: 1.45;
  margin: 0.6rem 0;
}
.bubble pre code {
  background: none;
  border: none;
  padding: 0;
  font-size: inherit;
  color: inherit;
}
.bubble table {
  border-collapse: collapse;
  width: 100%;
  margin: 0.25rem 0;
  font-size: 0.88rem;
}
.bubble th, .bubble td {
  border: 1px solid #d1d5db;
  padding: 0.4rem 0.6rem;
  text-align: left;
  vertical-align: top;
}
.bubble th {
  background: #f3f4f6;
  font-weight: 600;
  color: #374151;
}
.bubble td { background: #fff; }
.bubble tr:nth-child(even) td { background: #fafafa; }
.bubble ul, .bubble ol {
  /* 修改记录：[Mon 2026-06-08 08:27 GMT+8] 调整 (便于回溯/恢复)
     - 去除 ul/ol 默认的 0.4rem 上下外边距，ul/ol 之间的间距交给 .bubble > * + * 统一控制
     - 修正前：margin: 0.4rem 0（连续的 <p> 标题 + <ul> bullet 列表之间会双倍叠加空行）
     - 修正后：margin: 0（仅靠通用规则控制间距，避免与 li 边距重复叠加） */
  margin: 0;
  padding-left: 1.5rem;
}
.bubble li {
  /* 修改记录：[Mon 2026-06-08 08:27 GMT+8] 调整 (便于回溯/恢复)
     - 去除 bullet 之间的上下外边距，避免产生额外空行
     - 修正前：margin: 0.15rem 0（每个 li 上下都加 0.15rem，相邻 li 之间有 0.3rem 空白）
     - 修正后：margin: 0（与 .bubble > * + * 规则保持一致，仅由该规则控制间距）
     - 原因：原始 .html 文档 bullet 之间没有空行，但 chat-shell 渲染时多出 0.3rem/li 空白 */
  margin: 0;
  line-height: 1.5;
}
.bubble hr {
  border: none;
  border-top: 1px solid #e5e7eb;
  margin: 0.6rem 0;
}
.bubble blockquote {
  border-left: 3px solid #d1d5db;
  margin: 0.4rem 0;
  padding: 0.3rem 0.6rem;
  color: #6b7280;
  background: #f9fafb;
  border-radius: 0 4px 4px 0;
}
.bubble img {
  max-width: 100%;
  border-radius: 6px;
  margin: 0.5rem 0;
}

/* ===== MEDIA: attachment chip (matches existing .message.attachment style) =====
   修改记录：[Mon 2026-06-08 11:35 GMT+8] 调整 (便于回溯/恢复)
     - 原 .media-attachments 使用 flex 横排，导致多 chip 时是水平排列；
       但 11:35 反馈：仅一个 chip 加上面的 “HTML 文件已保存至” notice 时，
       chip 被拉伸、出现明显水平偏移。
     - 修正前：display:flex; flex-wrap:wrap; gap:0.4rem;
     - 修正后：display:flex; flex-direction:column; align-items:flex-start;
               （垂直堆叠、子项左对齐、不拉伸、）
     - 原因：HTML 文件名+路径 提示文字与 chip 需在同一左缘上对齐成两行。 */
.media-attachments {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.4rem;
  /* 修改记录：[Wed 2026-06-10 09:23 GMT+8] 修复 (便于回溯/恢复) ✅ 已验证
     - 背景：客户报告 chat-shell 渲染时，"最后一条 bullet" 与下方"HTML 文件已
             保存至："提示语之间看不到空行（两者几乎贴合）。
     - 根因（按 1️⃣2️⃣3️⃣ 排查路径）：
         1. AI 输出末尾的 \n\n 不会产生 <p></p> 空段
            → 实测 marked.parse(input, { gfm:true, breaks:true }) 在输入
              "• bullet\n\nHTML 文件已保存至：..." 时，只生成
              "<p>• bullet</p>\n<p>HTML 文件已保存至：...</p>"，中间没有
              <p></p>。所以 "<p></p> → <p class="bubble-spacer"></p>"
              的伪修复永远不会触发。
         2. "HTML 文件已保存至：" 不是 HTML 文件里的内容，是 chat-shell 前端
            在 renderMessage() 里检测到 *.html 路径后，动态创建
            <div class="media-saved-notice"> 追加进 .media-attachments
            容器的。
         3. .media-attachments 容器被 appendChild 到 .bubble 里，受
            ".bubble > * + * { margin-top: 0.1rem !important }" 压制。
            原写法 margin-top: 0.4rem 没有 !important，被覆掉只剩
            ~1.6px，肉眼几乎看不见。
     - 修正前：margin-top: 0.4rem;（被 !important 覆盖，实际只 0.1rem ≈1.6px）
     - 修正后：margin-top: 1rem !important;（加 !important 竞争 + 加大幅度，
              跳过 .bubble > * + * 的压制，产生明显 1rem 空行）
     - 验证：客户于 [Wed 2026-06-10 09:23 GMT+8] 反馈"终于修复好了"，
             强制刷新浏览器后看到 1rem 空行。
     - 复用：本修复对 tor_down / tor_reload / 未来任何 *.html / *.htm
              路径都生效，不需要按模板类型重复修复。 */
  margin-top: 1rem !important;
}
.media-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  background: #f0f4ff;
  border: 1px solid #c7d2fe;
  border-radius: 6px;
  padding: 0.3rem 0.6rem;
  font-size: 0.8rem;
  color: #4169E1;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  max-width: 100%;
}
.media-chip:hover {
  background: #e0e7ff;
  border-color: #4169E1;
}
.media-chip svg {
  flex-shrink: 0;
  color: #4169E1;
}
.media-chip:hover svg {
  color: #4169E1;
}
.media-chip-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 280px;
  font-weight: 500;
}

/* ===== Comms-skill dialog ===== */
.comms-dialog-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.45);
  display: flex; align-items: center; justify-content: center; z-index: 1000;
}
.comms-dialog {
  background: #fff; border-radius: 10px; padding: 1.5rem; max-width: 460px; width: 92%;
  box-shadow: 0 12px 40px rgba(0,0,0,0.25);
}
.comms-dialog h3 { margin: 0 0 0.5rem; font-size: 1.1rem; }
.comms-dialog label { display: block; font-size: 0.85rem; color: #4b5563; margin: 0.7rem 0 0.25rem; }
.comms-dialog input, .comms-dialog select {
  width: 100%; padding: 0.5rem 0.6rem; border: 1px solid #d1d5db; border-radius: 4px; font-size: 0.9rem;
  font-family: inherit;
}
.comms-dialog input:focus, .comms-dialog select:focus { outline: 2px solid #667eea; border-color: #667eea; }
.comms-hint { font-size: 0.85rem; color: #6b7280; margin: 0 0 0.5rem; }
.comms-actions { display: flex; gap: 0.6rem; justify-content: flex-end; margin-top: 1rem; }
.comms-status { margin-top: 0.6rem; font-size: 0.85rem; color: #4b5563; min-height: 1.4em; }

.comms-bubble { max-width: 720px; padding: 0.5rem 0.75rem; }
.comms-header {
  font-size: 0.85rem; color: #6b7280; padding: 0.3rem 0.4rem; border-bottom: 1px solid #e5e7eb; margin-bottom: 0.4rem;
}
.comms-iframe {
  width: 100%; height: 600px; border: 1px solid #e5e7eb; border-radius: 6px; background: #fff;
}

/* ===== Dark mode [Thu 2026-06-11 20:36 GMT+8] =====
   - 通过 body.dark-mode class 切换颜色
   - 不修改 6 个核心布局块（参考 LRN-20260611-009）
   - 仅覆盖背景/文本/按钮色 */
body.dark-mode {
 background: #1a1a1a;
 color: #e0e0e0;
}
body.dark-mode .sidebar {
 background: #232323;
 border-right-color: #333;
}
body.dark-mode .sidebar-header {
 border-bottom-color: #333;
}
body.dark-mode .session-item {
 color: #ccc;
}
body.dark-mode .session-item:hover {
 background: #2a2a2a;
}
body.dark-mode .session-item.active {
 background: #1e3a5f;
 border-color: #0078D4;
 color: #4FA3F7;
}
body.dark-mode .sidebar-footer {
 border-top-color: #333;
}
body.dark-mode .user-info {
 color: #999;
}
body.dark-mode .main-header {
 background: #232323;
 border-bottom-color: #333;
}
body.dark-mode .main-header h2 {
 color: #e0e0e0;
}
body.dark-mode .messages {
 background: #1a1a1a;
}
body.dark-mode .message.assistant .bubble {
 background: #2a2a2a;
 color: #e0e0e0;
 border-color: #333;
}
body.dark-mode .message.user .bubble {
 background: #0078D4;
 color: #fff;
}
body.dark-mode .message .meta {
 color: #777;
}
body.dark-mode .input-area {
 background: #232323;
 border-top-color: #333;
}
body.dark-mode #message-input {
 background: #2a2a2a;
 border-color: #444;
 color: #e0e0e0;
}
body.dark-mode #message-input:focus {
 border-color: #4FA3F7;
}
body.dark-mode .action-btn {
 background: #2a2a2a;
 border-color: #444;
 color: #ccc;
}
body.dark-mode .action-btn:hover {
 background: #333;
 color: #4FA3F7;
 border-color: #4FA3F7;
}
body.dark-mode .theme-btn:hover {
 color: #ccc;
 background: #333;
}
body.dark-mode .theme-btn.active {
 color: #4FA3F7;
 background: #1e3a5f;
 border-color: #0078D4;
}
body.dark-mode .primary-btn {
 background: #0078D4;
 color: #fff;
}
body.dark-mode .primary-btn:hover {
 background: #006abc;
}
body.dark-mode .bubble strong {
 color: #e0e0e0;
}
body.dark-mode .login-card {
 background: #232323;
 color: #e0e0e0;
}
body.dark-mode .login-card input {
 background: #1a1a1a;
 border-color: #444;
 color: #e0e0e0;
}
/* ===== Admin sidebar button ===== */
.admin-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 8px 12px;
  margin-bottom: 8px;
  background: #f0f4ff;
  border: 1px solid #c7d2fe;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.85rem;
  color: #4338ca;
  font-family: inherit;
  transition: background 0.15s, color 0.15s;
}
.admin-btn[hidden] {
  display: none !important;
}
.admin-btn:hover {
  background: #e0e7ff;
  color: #3730a3;
}
.admin-btn.active {
  background: #4338ca;
  color: #fff;
  border-color: #4338ca;
}

/* ===== Admin content ===== */
.admin-content {
  flex: 1;
  overflow-y: auto;
  padding: 1.5rem;
  background: #fafbfc;
}
.admin-table-wrap {
  background: #fff;
  border: 1px solid #e5e7eb;
  border-radius: 8px;
  overflow-x: auto;
}
.admin-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
}
.admin-table th, .admin-table td {
  padding: 10px 14px;
  text-align: left;
  border-bottom: 1px solid #f0f0f0;
  white-space: nowrap;
}
.admin-table th {
  background: #f9fafb;
  font-weight: 600;
  color: #374151;
  position: sticky;
  top: 0;
}
.admin-table tr:hover td {
  background: #f8faff;
}
.admin-table .role-badge {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 0.8rem;
  font-weight: 500;
}
.admin-table .role-operator {
  background: #fef3c7;
  color: #92400e;
}
.admin-table .role-user {
  background: #e0f2fe;
  color: #0c4a6e;
}
.admin-table .actions {
  display: flex;
  gap: 6px;
}
.admin-table .actions button {
  padding: 4px 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
  background: #fff;
  cursor: pointer;
  font-size: 0.8rem;
  font-family: inherit;
  transition: background 0.1s;
}
.admin-table .actions .edit-btn:hover {
  background: #f0f4ff;
  border-color: #c7d2fe;
  color: #4338ca;
}
.admin-table .actions .delete-btn:hover {
  background: #fee;
  border-color: #f3c2c2;
  color: #d32f2f;
}

/* ===== Modal ===== */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2000;
}
.modal-overlay[hidden] {
  display: none !important;
}
.modal {
  background: #fff;
  border-radius: 10px;
  padding: 1.5rem;
  max-width: 440px;
  width: 92%;
  box-shadow: 0 12px 40px rgba(0,0,0,0.25);
  font-family: inherit;
}
.modal h3 {
  margin: 0 0 1rem;
  font-size: 1.1rem;
}
.modal label {
  display: block;
  font-size: 0.85rem;
  color: #555;
  margin: 0.75rem 0 0.25rem;
}
.modal input, .modal select {
  width: 100%;
  padding: 0.5rem 0.6rem;
  border: 1px solid #ddd;
  border-radius: 6px;
  font-size: 0.9rem;
  font-family: inherit;
}
.modal input:focus, .modal select:focus {
  outline: none;
  border-color: #667eea;
}
.modal .required {
  color: #d32f2f;
}
.modal-actions {
  display: flex;
  gap: 0.6rem;
  justify-content: flex-end;
  margin-top: 1.25rem;
}
.modal-actions .primary-btn, .modal-actions .secondary-btn {
  padding: 0.5rem 1.5rem;
  border-radius: 6px;
  font-size: 0.9rem;
  cursor: pointer;
  font-family: inherit;
  border: 1px solid transparent;
  width: auto;
}
.modal-actions .primary-btn {
  background: #667eea;
  color: #fff;
  border: none;
}
.modal-actions .primary-btn:hover {
  background: #5568d3;
}
.modal-actions .secondary-btn {
  background: #fff;
  color: #555;
  border-color: #ddd;
}
.modal-actions .secondary-btn:hover {
  background: #f5f5f5;
}
.modal-error {
  color: #d32f2f;
  font-size: 0.85rem;
  margin: 0.5rem 0 0;
  min-height: 1.2em;
}

/* ===== Dark mode: admin ===== */
body.dark-mode .admin-btn {
  background: #1e3a5f;
  color: #4FA3F7;
  border-color: #0078D4;
}
body.dark-mode .admin-btn:hover {
  background: #0078D4;
  color: #fff;
}
body.dark-mode .admin-btn.active {
  background: #0078D4;
  color: #fff;
}
body.dark-mode .admin-content {
  background: #1a1a1a;
}
body.dark-mode .admin-table-wrap {
  background: #232323;
  border-color: #333;
}
body.dark-mode .admin-table th {
  background: #2a2a2a;
  color: #ccc;
}
body.dark-mode .admin-table td {
  color: #ccc;
  border-bottom-color: #333;
}
body.dark-mode .admin-table tr:hover td {
  background: #2a2a2a;
}
body.dark-mode .admin-table .actions button {
  background: #2a2a2a;
  border-color: #444;
  color: #ccc;
}
body.dark-mode .modal {
  background: #232323;
  color: #e0e0e0;
}
body.dark-mode .modal input, .dark-mode .modal select {
  background: #1a1a1a;
  border-color: #444;
  color: #e0e0e0;
}
body.dark-mode .modal-actions .secondary-btn {
  background: #2a2a2a;
  border-color: #444;
  color: #ccc;
}

.form-actions {
  display: flex;
  align-items: center;
  margin-top: 1rem;
  padding: 0 1.5rem;
}
.login-card .form-actions button {
  width: auto !important;
  margin-top: 0 !important;
  padding: 0.55rem 1.4rem;
  font-size: 0.9rem;
}
.login-card .form-actions .primary-btn {
  margin-right: auto;
}
.login-card .form-actions .secondary-btn {
  margin-left: 1rem;
}


/* Attachment chip in input area */
.attachment-list { display: flex; flex-wrap: wrap; gap: 4px; padding: 0.25rem 0.5rem; min-height: 0; }
.attachment-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  background: #f0f4ff;
  border: 1px solid #c7d2fe;
  border-radius: 6px;
  font-size: 0.82rem;
  color: #4338ca;
  font-family: "Microsoft YaHei", sans-serif;
}
.attachment-chip .attachment-remove {
  margin-left: 4px;
  cursor: pointer;
  font-size: 1rem;
  color: #999;
  line-height: 1;
  transition: color 0.1s;
}
.attachment-chip .attachment-remove:hover { color: #d32f2f; }

/* Image preview in chat bubbles */
.bubble img {
  max-width: 100%;
  max-height: 400px;
  border-radius: 8px;
  margin: 0.5rem 0;
  display: block;
}
.bubble .attachment-preview {
  display: inline-block;
  margin: 0.25rem 0.5rem 0.25rem 0;
  padding: 6px 12px;
  background: #f0f4ff;
  border: 1px solid #c7d2fe;
  border-radius: 6px;
  font-size: 0.82rem;
  color: #4338ca;
  text-decoration: none;
}
.bubble .attachment-preview:hover { background: #e0e7ff; }

/* Dark mode attachment chips */
body.dark-mode .attachment-chip {
  background: #1e3a5f;
  border-color: #0078D4;
  color: #4FA3F7;
}
body.dark-mode .bubble .attachment-preview {
  background: #1e3a5f;
  border-color: #0078D4;
  color: #4FA3F7; }


/* ===== KB-Search 结果样式 ===== */
.kb-result {
  font-size: 0.9rem;
}
.kb-header {
  font-size: 0.95rem;
  margin-bottom: 0.6rem;
  color: #1e40af;
  font-weight: 500;
}
.kb-item {
  background: #f8fafc;
  border: 1px solid #e2e8f0;
  border-left: 3px solid #3b82f6;
  border-radius: 6px;
  padding: 0.6rem 0.8rem;
  margin-bottom: 0.6rem;
}
.kb-item-head {
  font-size: 0.8rem;
  color: #475569;
  margin-bottom: 0.3rem;
}
.kb-item-text {
  color: #1e293b;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
}
.kb-images {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 0.5rem;
}
.kb-images a {
  display: inline-block;
  border: 1px solid #e2e8f0;
  border-radius: 4px;
  overflow: hidden;
  transition: transform 0.15s, box-shadow 0.15s;
}
.kb-images a:hover {
  transform: scale(1.05);
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
.kb-images img {
  max-width: 160px;
  max-height: 160px;
  display: block;
  object-fit: cover;
}
body.dark-mode .kb-header { color: #60a5fa; }
body.dark-mode .kb-item {
  background: #1e293b;
  border-color: #334155;
  border-left-color: #60a5fa;
}
body.dark-mode .kb-item-head { color: #94a3b8; }
body.dark-mode .kb-item-text { color: #e2e8f0; }
body.dark-mode .kb-images a { border-color: #334155; }

/* KB 内联图片（嵌入文字中间） */
.kb-inline-img {
  display: inline-block;
  margin: 0.3rem 0.2rem;
  vertical-align: middle;
}
.kb-inline-img img {
  max-width: 200px;
  max-height: 150px;
  border-radius: 4px;
  border: 1px solid #d1d5db;
  cursor: pointer;
  transition: opacity 0.15s;
}
.kb-inline-img img:hover {
  opacity: 0.85;
}
body.dark-mode .kb-inline-img img {
  border-color: #334155;
}
