*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  /* === Typography === */
  --font-body: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, -apple-system, sans-serif;
  --font-heading: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", system-ui, -apple-system, sans-serif;
  --font-mono: "SF Mono", "Fira Code", "Cascadia Code", Consolas, "Microsoft YaHei Mono", monospace;
  --font-size-xs: 11px;
  --font-size-sm: 13px;
  --font-size-base: 14px;
  --font-size-lg: 16px;
  --font-size-xl: 20px;
  --font-size-2xl: 26px;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  --font-weight-extrabold: 800;
  --letter-spacing: 0.02em;

  /* === Gray Scale === */
  --gray-50: #f9fafb;
  --gray-100: #f3f4f6;
  --gray-200: #e5e7eb;
  --gray-300: #d1d5db;
  --gray-500: #6b7280;
  --gray-700: #374151;
  --gray-900: #111827;
  --white: #ffffff;

  /* === Shared Tokens === */
  --primary: #004280;
  --primary-hover: #003366;
  --danger: #dc2626;
  --danger-hover: #b91c1c;
  --success: #059669;
  --shadow: 0 1px 3px rgba(0,0,0,.1);
  --shadow-md: 0 4px 6px rgba(0,0,0,.1);
  --radius: 8px;

  /* === Design System Tokens === */
  --bg: #f2f3f6;
  --surface: #ffffff;
  --surface-hover: #e6eff7;
  --border: #d9e1ef;
  --text: #333333;
  --text-secondary: #4d4d4d;
  --text-muted: #808080;
  --radius-lg: 16px;
  --radius-sm: 6px;
  --shadow-sm: 0 1px 3px rgba(0,0,0,.06);
  --shadow-md: 0 4px 16px rgba(0,0,0,.08);
  --shadow-lg: 0 8px 32px rgba(0,0,0,.1);
  --shadow-xl: 0 12px 48px rgba(0,0,0,.12);
  --transition: 0.2s ease;
  --transition-slow: 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  --primary-glow: rgba(0, 66, 128, 0.15);
  --primary-light: #e6eff7;
  --accent-blue: #336899;
  --accent-blue-hover: #2580b3;
  --accent-warm: #f59e0b;
  --accent-cool: #3eaedc;
  --success-light: #d1fae5;
  --success-dark: #065f46;
  --danger-light: #fee2e2;
  --danger-dark: #991b1b;
  --chart-line: #336899;
  --chart-fill: rgba(51, 104, 153, 0.12);
  /* 聊天区背景：--chat-sidebar-bg 左侧会话列表、--chat-bg 右侧消息区。
     浅色下「左浅灰 + 右白」，深色在 .dark-theme .chat-container 里覆盖。 */
  --chat-bg: var(--white);
  --chat-sidebar-bg: var(--gray-50);
  --brand-gradient: linear-gradient(135deg, #004280, #336899);
  --brand-accent-2: #336899;
  --btn-glow: rgba(0, 66, 128, 0.35);

  /* Login page — light（企业风：单一藏蓝品牌色，无渐变底色） */
  --login-bg: #f4f6fa;
  --login-text: #1b2333;
  --login-muted: #626d7f;
  --login-faint: #8a94a6;
  --login-card-bg: #ffffff;
  --login-card-border: #dbe3ef;
  --login-card-shadow: 0 1px 2px rgba(16, 24, 40, 0.05), 0 16px 40px rgba(16, 24, 40, 0.07);
  --login-brand-bg: linear-gradient(158deg, #00325c 0%, #004280 52%, #0a508f 100%);
  --login-grid-line: rgba(255, 255, 255, 0.07);
  --login-panel-grid: rgba(0, 66, 128, 0.045);
  --login-input-bg: #f7f9fc;
  --login-input-border: #8395af;
  --login-input-color: #1b2333;
  --login-input-placeholder: #626d7f;
  --login-input-focus-border: #004280;
  --login-input-focus-ring: rgba(0, 66, 128, 0.16);
  --login-input-focus-bg: #ffffff;
  --login-tab-bg: #eef2f8;
  --login-tab-active-bg: #ffffff;
  --login-tab-active-color: #004280;
  --login-alert-bg: #fef3f2;
  --login-alert-border: #f3c3bd;
  --login-alert-color: #b42318;
  --login-autofill-bg: #eef3fa;
  --login-autofill-color: #1b2333;
  --login-btn-bg: #004280;
  --login-btn-bg-hover: #003263;
  --login-btn-text: #ffffff;
  --login-toggle-bg: rgba(255, 255, 255, 0.92);
  --login-toggle-text: #1b2333;
  --login-toggle-border: #dbe3ef;
  --login-divider: #e6ebf3;
}

/* Dark Theme — 深色底 + 高对比卡片 */
.dark-theme {
  --bg: #050510;
  --surface: #1a1d27;
  --surface-hover: #232738;
  --border: #2d3146;
  --text: #edf1f7;
  --text-secondary: #9499b4;
  --text-muted: #5d6380;
  --gray-50: #1a1d27;
  --gray-100: #232738;
  --gray-200: #2d3146;
  --gray-300: #3a3f58;
  --gray-500: #5d6380;
  --gray-700: #9499b4;
  --gray-900: #edf1f7;
  --white: #1a1d27;
  --shadow-sm: 0 1px 3px rgba(0,0,0,.3);
  --shadow-md: 0 4px 16px rgba(0,0,0,.4);
  --shadow-lg: 0 8px 40px rgba(0,0,0,.5);
  --shadow-xl: 0 12px 48px rgba(0,0,0,.5);
  --primary-glow: rgba(99, 102, 241, 0.25);
  --primary-light: rgba(99, 102, 241, 0.15);
  /* 共享 token 深色覆盖：保持深色主题靛蓝/紫原样，不受浅色研华蓝影响 */
  --primary: #4f46e5;
  --primary-hover: #4338ca;
  --accent-blue: #2563eb;
  --accent-blue-hover: #1d4ed8;
  --accent-cool: #06b6d4;
  --chart-line: #4f46e5;
  --chart-fill: rgba(79, 70, 229, 0.08);
  --brand-gradient: linear-gradient(135deg, #4f46e5, #7c3aed);
  --brand-accent-2: #7c3aed;
  --btn-glow: rgba(0, 102, 255, 0.35);

  /* Login page — dark（同一套藏蓝体系，只按深色底提亮，不再切到靛紫） */
  --login-bg: #0d1017;
  --login-text: #eef1f6;
  --login-muted: #9aa4b6;
  --login-faint: #77808f;
  --login-card-bg: #14171f;
  --login-card-border: #262b36;
  --login-card-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 16px 40px rgba(0, 0, 0, 0.45);
  --login-brand-bg: linear-gradient(158deg, #0a1626 0%, #0f2036 55%, #12283f 100%);
  --login-grid-line: rgba(255, 255, 255, 0.055);
  --login-panel-grid: rgba(255, 255, 255, 0.028);
  --login-input-bg: #171b24;
  --login-input-border: #5a6577;
  --login-input-color: #eef1f6;
  --login-input-placeholder: #949cad;
  --login-input-focus-border: #7fa9d6;
  --login-input-focus-ring: rgba(127, 169, 214, 0.22);
  --login-input-focus-bg: #1b202a;
  --login-tab-bg: #1b202a;
  --login-tab-active-bg: #262b36;
  --login-tab-active-color: #cfe1f4;
  --login-alert-bg: rgba(220, 38, 38, 0.12);
  --login-alert-border: rgba(248, 113, 113, 0.4);
  --login-alert-color: #fca5a5;
  --login-autofill-bg: #1b202a;
  --login-autofill-color: #eef1f6;
  --login-btn-bg: #2f6aa8;
  --login-btn-bg-hover: #3a7bbd;
  --login-btn-text: #ffffff;
  --login-toggle-bg: rgba(20, 23, 31, 0.9);
  --login-toggle-text: #eef1f6;
  --login-toggle-border: #333947;
  --login-divider: #262b36;
}

/* Admin dark theme */
.dark-theme .admin-sidebar {
  background: var(--surface);
  border-color: var(--border);
}
.dark-theme .admin-sidebar-brand {
  background: var(--surface);
  border-color: var(--border);
}
.dark-theme .admin-nav-item:hover {
  background: var(--surface-hover);
}
.dark-theme .admin-nav-item.active {
  background: var(--surface-hover);
}
.dark-theme .admin-content {
  background: var(--surface);
  border-color: var(--border);
}
.dark-theme .data-table-wrapper {
  border-color: var(--border);
}
.dark-theme .data-table th {
  background: var(--surface-hover);
  color: var(--text-secondary);
}
.dark-theme .data-table td {
  border-color: var(--border);
}
.dark-theme .data-table tbody tr:nth-child(even) td {
  background: rgba(255,255,255,.02);
}
.dark-theme .stat-card {
  background: var(--bg);
  border-color: var(--border);
}
.dark-theme .chart-panel {
  background: var(--bg);
  border-color: var(--border);
}
.dark-theme .inline-form {
  background: var(--bg);
  border-color: var(--border);
}
.dark-theme .edit-form {
  background: var(--bg);
  border-color: var(--border);
}
.dark-theme .log-filter-bar label {
  color: var(--text-secondary);
}
.dark-theme .chart-toolbar h3 {
  color: var(--text);
}

body {
  font-family: var(--font-body);
  font-size: var(--font-size-base);
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transition: background var(--transition-slow), color var(--transition-slow);
}

/* Dark theme body gradient — matches login page atmosphere */
html.dark-theme body {
  background-color: var(--bg);
  background-image:
    radial-gradient(ellipse at 30% 20%, rgba(26, 26, 94, 0.5) 0%, transparent 50%),
    radial-gradient(ellipse at 70% 80%, rgba(15, 32, 64, 0.4) 0%, transparent 50%);
}

/* Light theme body gradient — advantech cool blue */
html:not(.dark-theme) body {
  background-color: var(--bg);
  background-image:
    radial-gradient(ellipse at 30% 20%, rgba(0, 66, 128, 0.06) 0%, transparent 50%),
    radial-gradient(ellipse at 70% 80%, rgba(51, 104, 153, 0.05) 0%, transparent 50%),
    radial-gradient(ellipse at 50% 40%, rgba(62, 174, 220, 0.04) 0%, transparent 70%);
}

/* ===== Login — 企业风：左侧品牌 / 右侧表单，浅深共用一套藏蓝 ===== */
.login-page {
  /* 登录/注册页内的强调色统一，深色不再切到靛紫 */
  --primary: #004280;
  --primary-hover: #003263;
  --primary-glow: rgba(0, 66, 128, 0.18);
  --brand-gradient: linear-gradient(135deg, #004280, #0f5a9c);
  display: block;
  min-height: 100vh; min-height: 100dvh;
  /* 内容比视口高时（横屏手机/拖矮窗口）必须能滚动，否则登录按钮点不到 */
  overflow-x: hidden; overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--login-bg);
  color: var(--login-text);
  animation: fadeIn 0.3s ease-out;
  transition: background 0.3s ease, color 0.3s ease;
}
.dark-theme .login-page {
  --primary: #7fa9d6;
  --primary-hover: #9dc0e2;
  --primary-glow: rgba(127, 169, 214, 0.22);
  --brand-gradient: linear-gradient(135deg, #2f6aa8, #3f80c0);
}

/* 左右分栏容器；窄屏自动变成「顶部品牌条 + 下方表单」 */
.login-shell { display: flex; flex-direction: column; min-height: 100vh; min-height: 100dvh; }

/* 品牌区：静态网格底纹，零动画、零 JS */
.login-brand {
  position: relative;
  display: flex; flex-direction: column; gap: 6px;
  padding: 20px;
  background: var(--login-brand-bg);
  color: #fff;
}
.login-brand::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(to right, var(--login-grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--login-grid-line) 1px, transparent 1px);
  background-size: 34px 34px;
}
.login-brand > * { position: relative; z-index: 1; }
.login-brand-head { display: flex; align-items: center; gap: 10px; }
/* 官方字标（白字透明底，任何深色品牌底上都能无缝显示） */
.login-brand-logo { display: block; height: 26px; width: auto; max-width: 100%; }
.login-brand-name {
  padding-left: 12px; border-left: 1px solid rgba(255, 255, 255, 0.3);
  font-size: 15px; font-weight: 600; letter-spacing: 0.12em; line-height: 1.4;
  color: rgba(255, 255, 255, 0.9);
}
/* 下面这些只在宽屏出现 */
.login-brand-title { display: none; }
.login-brand-desc { display: none; }
.login-brand-points { display: none; }
.login-brand-foot { display: none; }

/* 表单区 */
.login-panel {
  position: relative; flex: 1 1 auto;
  display: flex; align-items: center; justify-content: center;
  padding: 24px 16px 40px;
  background: var(--login-bg);
}
.login-panel::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(to right, var(--login-panel-grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--login-panel-grid) 1px, transparent 1px);
  background-size: 34px 34px;
}

/* 卡片（登录用 .login-card，注册页沿用 .glass-container） */
.login-card,
.glass-container {
  position: relative; z-index: 1;
  width: 100%; max-width: 384px;
  /* margin:auto：卡片高过视口时不会被裁掉顶部 */
  margin: auto;
  padding: 30px 26px 22px;
  background: var(--login-card-bg);
  border: 1px solid var(--login-card-border);
  border-radius: 14px;
  box-shadow: var(--login-card-shadow);
  transition: background 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}
.glass-container > * { position: relative; z-index: 1; }

.login-card-title { font-size: 20px; font-weight: 600; letter-spacing: 0.01em; color: var(--login-text); }
.login-card-sub { margin-top: 6px; font-size: 12.5px; line-height: 1.6; color: var(--login-muted); }
.login-title {
  text-align: center; font-size: 20px; letter-spacing: 0.01em;
  margin-bottom: 6px;
  color: var(--login-text);
  font-weight: 600;
}
.login-logo { display: block; margin: 0 auto 16px; max-width: 200px; max-height: 80px; }
.login-form { display: flex; flex-direction: column; gap: 14px; position: relative; z-index: 1; }
/* 登录/注册/找回密码页：间距统一交给 .login-form 的 gap。
   全局 .form-group 自带 margin-bottom: 14px，叠加后同一张卡里会出现 28px 与 14px 两套间距。 */
.login-page .login-form > .form-group { margin-bottom: 0; }
.form-group { min-width: 0; }

/* 密码可见性切换 */
.pw-group { position: relative; }
.pw-group .glass-input { padding-right: 62px; }
.pw-toggle {
  position: absolute; right: 5px; top: 50%; transform: translateY(-50%);
  min-height: 44px; padding: 0 9px;
  border: 0; border-radius: 6px; background: transparent;
  font-family: inherit; font-size: 12.5px; line-height: 1;
  color: var(--login-muted); cursor: pointer;
  transition: color 0.15s ease, background 0.15s ease;
}
.pw-toggle:hover { color: var(--primary); background: rgba(127, 127, 127, 0.1); }
.pw-toggle:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }

/* 输入框：实底 + 可见描边，聚焦用 3px 环形描边而不是发光 */
.glass-input {
  width: 100%; min-height: 46px; padding: 11px 14px;
  background: var(--login-input-bg);
  border: 1px solid var(--login-input-border);
  border-radius: 9px;
  font-family: inherit; font-size: 14px; line-height: 1.4;
  color: var(--login-input-color);
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.glass-input::placeholder { color: var(--login-input-placeholder); opacity: 1; }
.glass-input:hover { border-color: var(--login-muted); }
.glass-input:focus {
  border-color: var(--login-input-focus-border);
  box-shadow: 0 0 0 3px var(--login-input-focus-ring);
  background: var(--login-input-focus-bg);
}
/* 覆盖浏览器自动填充背景 */
.glass-input:-webkit-autofill,
.glass-input:-webkit-autofill:hover,
.glass-input:-webkit-autofill:focus,
.glass-input:-webkit-autofill:active {
  -webkit-box-shadow: 0 0 0 1000px var(--login-autofill-bg) inset !important;
  -webkit-text-fill-color: var(--login-autofill-color) !important;
  caret-color: var(--login-autofill-color);
  border: 1px solid var(--login-input-border);
  border-radius: 9px;
}

/* 主按钮：实色藏蓝，去掉渐变/高光扫过/位移。加上 .login-page 前缀压过后面的 .btn-primary */
.login-page .glass-btn {
  width: 100%; min-height: 46px; padding: 12px 16px;
  border: none; border-radius: 9px;
  background: var(--login-btn-bg);
  color: var(--login-btn-text);
  font-family: inherit; font-size: 15px; font-weight: 600; letter-spacing: 0.14em;
  cursor: pointer;
  transition: background 0.15s ease, box-shadow 0.15s ease;
}
.login-page .glass-btn:hover { background: var(--login-btn-bg-hover); box-shadow: 0 4px 14px rgba(0, 66, 128, 0.18); }
.login-page .glass-btn:active { background: var(--login-btn-bg-hover); }
.login-page .glass-btn:disabled { opacity: 0.6; cursor: default; box-shadow: none; }
.glass-btn:focus-visible,
.login-tab:focus-visible,
.login-theme-toggle:focus-visible,
.reg-captcha-img:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* 错误提示 */
.login-page .alert-error {
  background: var(--login-alert-bg);
  border: 1px solid var(--login-alert-border);
  color: var(--login-alert-color);
  border-radius: 8px;
  font-size: 12.5px; line-height: 1.55;
  animation: shake 0.4s ease-in-out;
}

/* 主题切换按钮：文字按钮，放在 DOM 末尾（键盘 Tab 最后才到） */
.login-theme-toggle {
  position: fixed; top: 14px; right: 16px; z-index: 30;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 40px; padding: 0 14px;
  background: var(--login-toggle-bg);
  color: var(--login-toggle-text);
  border: 1px solid var(--login-toggle-border);
  border-radius: 8px;
  font-family: inherit; font-size: 12.5px; line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.login-theme-toggle:hover { border-color: var(--primary); }

/* Keyframes */
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-8px); }
  40% { transform: translateX(8px); }
  60% { transform: translateX(-5px); }
  80% { transform: translateX(5px); }
}
/* ===== End Login ===== */

/* ===== Navbar (Glass, dual-theme) ===== */
.navbar-glass {
  position: sticky; top: 0; z-index: 100;
  display: flex; align-items: center; justify-content: space-between;
  height: 60px; padding: 0 24px;
  background: rgba(255,255,255,0.75);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-bottom: 1px solid var(--border);
  transition: background var(--transition), border-color var(--transition);
}
.dark-theme .navbar-glass {
  background: rgba(11,13,23,0.75);
  border-bottom: 1px solid rgba(255,255,255,0.06);
  box-shadow: 0 1px 0 rgba(0,212,255,0.06);
}
.nav-left { display: flex; align-items: center; gap: 16px; }
.nav-brand {
  font-family: var(--font-heading);
  font-size: 19px; font-weight: 700;
  color: var(--primary); text-decoration: none;
  letter-spacing: 0.5px;
}
.dark-theme .nav-brand {
  text-shadow: 0 0 16px var(--primary-glow);
}
.nav-brand-icon { display: inline-block; vertical-align: -3px; margin-right: 6px; color: var(--primary); }
.nav-right { display: flex; align-items: center; gap: 8px; }
.nav-link {
  color: var(--text-secondary); text-decoration: none;
  font-size: 13px; font-weight: 500; padding: 7px 14px;
  border-radius: var(--radius-sm); transition: all var(--transition);
}
.nav-link:hover {
  background: var(--surface-hover); color: var(--text);
}
.nav-link.nav-active {
  background: var(--primary-light); color: var(--primary);
  font-weight: 600;
  box-shadow: inset 0 -2px 0 var(--primary);
}
.nav-user-avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 50%;
  background: linear-gradient(135deg, var(--primary), var(--brand-accent-2));
  color: #fff; font-size: 13px; font-weight: 600;
  margin-left: 8px; cursor: default;
  box-shadow: 0 0 0 2px var(--surface);
}
.nav-user-name {
  font-size: 13px; color: var(--text-secondary);
  margin-right: 4px;
}
/* ===== User Dropdown Menu ===== */
.user-dropdown {
  position: relative;
  display: inline-flex;
}
.user-dropdown-trigger {
  cursor: pointer;
  padding: 7px 12px;
  border-radius: var(--radius-sm);
  transition: background 0.15s;
  user-select: none;
}
.user-dropdown-trigger:hover {
  background: var(--surface-hover);
}
.user-dropdown-menu {
  position: absolute;
  top: 100%;
  right: 0;
  margin-top: 6px;
  min-width: 140px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-6px);
  transition: all 0.2s ease;
  z-index: 300;
  overflow: hidden;
}
.user-dropdown-menu.open {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.user-dropdown-item {
  display: block;
  padding: 10px 16px;
  font-size: 13px;
  color: var(--text);
  text-decoration: none;
  transition: background 0.15s;
  cursor: pointer;
  white-space: nowrap;
}
.user-dropdown-item:hover {
  background: var(--surface-hover);
}
.user-dropdown-item-danger {
  color: var(--danger);
}
.user-dropdown-item-danger:hover {
  background: rgba(220,38,38,0.1) !important;
  color: var(--danger-hover);
}
.user-dropdown-divider {
  height: 1px;
  background: var(--border);
  margin: 0;
}
/* Dark theme dropdown */
.dark-theme .user-dropdown-menu {
  border-color: rgba(255,255,255,0.1);
  box-shadow: 0 8px 32px rgba(0,0,0,0.5);
}

.nav-btn-icon {
  width: 14px; height: 14px; vertical-align: middle; margin-right: 4px;
}
.nav-logout {
  color: var(--danger);
}
.nav-logout:hover {
  background: rgba(220,38,38,0.1); color: var(--danger-hover);
}

/* ===== Subtle Background Texture ===== */
/* 2026-11-05 首页改版 A：点阵 0.4 → 0.2。
   24px 的点阵铺满全屏、再叠四团光斑，背景比前景（几张白卡）还热闹，像在草图纸上摆纸。
   压到 0.2 后背景只留一层"纸纹"，不抢卡片。 */
body::before {
  content: '';
  position: fixed; inset: 0; z-index: -1;
  background-image: radial-gradient(var(--border) 0.5px, transparent 0.5px);
  background-size: 24px 24px;
  opacity: 0.2;
  pointer-events: none;
}

/* ===== Page Transition ===== */
.main-content {
  max-width: 1600px; margin: 0 auto; padding: 24px;
  animation: pageEnter 0.45s ease-out;
  transition: background var(--transition);
}
@keyframes pageEnter {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Staggered card entrance (used by KB grid and stats grid) */
.kb-grid > *,
.stats-grid > * {
  animation: cardEnter 0.4s ease-out both;
}
.kb-grid > *:nth-child(1) { animation-delay: 0.02s; }
.kb-grid > *:nth-child(2) { animation-delay: 0.06s; }
.kb-grid > *:nth-child(3) { animation-delay: 0.10s; }
.kb-grid > *:nth-child(4) { animation-delay: 0.14s; }
.kb-grid > *:nth-child(5) { animation-delay: 0.18s; }
.kb-grid > *:nth-child(6) { animation-delay: 0.22s; }
.kb-grid > *:nth-child(7) { animation-delay: 0.26s; }
.kb-grid > *:nth-child(8) { animation-delay: 0.30s; }
.stats-grid > *:nth-child(1) { animation-delay: 0.04s; }
.stats-grid > *:nth-child(2) { animation-delay: 0.10s; }
.stats-grid > *:nth-child(3) { animation-delay: 0.16s; }
.stats-grid > *:nth-child(4) { animation-delay: 0.22s; }
@keyframes cardEnter {
  from { opacity: 0; transform: translateY(16px) scale(0.97); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

/* ===== Dashboard (Dark Theme) ===== */
/* 2026-11-05 首页改版 A：整块内容收窄到 1120 居中。
   之前标题/菜单贴容器左缘（x=177）、轮播却 960 居中（x=473），三套对齐基准让人找不到落点。
   现在标题、菜单、面板、轮播共用同一条中轴；窄屏下 max-width 自动跟随容器收缩。
   2026-11-06 改版 B：中轴 1120 → 1440。1920 屏上 1120 只占 58% 宽，两侧大片空底，
   而 .main-content 本身容得下 1600-2×24；1440 正好落在「铺满但不贴边」的位置，
   1366/1440 屏上由容器宽度兜底（1318 / 1392），不会出横向滚动。 */
.dashboard {
  position: relative;
  max-width: 1440px;
  margin-inline: auto;
  min-height: calc(100vh - 60px - 48px);
}

/* ===== 主页面玻璃层：背景光斑 =====
   卡片用 backdrop-filter 磨砂，背后必须有东西可透，否则「半透明」只会变成灰卡。
   光斑要落在卡片区域的正后方（而不是四个角），否则中间一片纯色，玻璃感看不出来。 */
.dash-ambient {
  position: fixed; inset: 0;
  z-index: 0; pointer-events: none;
  background:
    radial-gradient(900px 720px at 6% 22%,
      rgba(0, 96, 204, 0.34) 0%, rgba(0, 96, 204, 0.13) 40%, transparent 68%),
    radial-gradient(820px 660px at 94% 34%,
      rgba(45, 170, 225, 0.32) 0%, rgba(45, 170, 225, 0.12) 42%, transparent 70%),
    radial-gradient(760px 620px at 52% 66%,
      rgba(108, 160, 220, 0.24) 0%, rgba(108, 160, 220, 0.08) 45%, transparent 72%),
    radial-gradient(1100px 780px at 40% 110%,
      rgba(24, 82, 150, 0.30) 0%, rgba(24, 82, 150, 0.10) 45%, transparent 72%);
}
.dark-theme .dash-ambient {
  background:
    radial-gradient(820px 660px at 12% 0%,
      rgba(0, 120, 255, 0.30) 0%, rgba(0, 120, 255, 0.10) 44%, transparent 70%),
    radial-gradient(760px 600px at 88% 16%,
      rgba(0, 212, 255, 0.22) 0%, rgba(0, 212, 255, 0.08) 46%, transparent 72%),
    radial-gradient(1000px 760px at 50% 108%,
      rgba(79, 70, 229, 0.26) 0%, rgba(79, 70, 229, 0.08) 46%, transparent 74%);
}
/* 光斑在内容之下；顶栏 z-index 100 不受影响 */
.dashboard > *:not(.dash-ambient) {
  position: relative;
  z-index: 1;
}
/* KB Section layout */
.kb-section {
  margin-bottom: 36px;
}
.kb-section-header {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 18px;
  padding-left: 2px;
  position: relative;
}
.kb-section-accent {
  display: block;
  width: 4px; height: 22px;
  border-radius: 2px;
  flex-shrink: 0;
}
.kb-section-icon {
  font-size: 18px; line-height: 1;
  flex-shrink: 0;
}
.kb-section-header h3 {
  font-size: 17px;
  font-weight: var(--font-weight-semibold);
  color: var(--text);
  letter-spacing: 0.3px;
}
.kb-section-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px;
  padding: 0 6px;
  border-radius: 10px;
  background: var(--gray-100);
  color: var(--text-secondary);
  font-size: 11px; font-weight: 600;
  line-height: 1;
}
.kb-section-divider {
  height: 1px;
  background: linear-gradient(to right, var(--border), transparent);
  margin: 4px 0 28px 0;
}
.kb-section-empty {
  padding: 32px 0;
  text-align: center;
  color: var(--text-muted);
  font-size: 14px;
}
.kb-section-header::after {
  content: '';
  position: absolute;
  bottom: -8px;
  left: 2px;
  width: 36px;
  height: 2px;
  border-radius: 1px;
  background: var(--primary);
  opacity: 0.25;
}

.kb-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 20px;
}

/* KB Card (参考稿：左上图标 + 右上更新徽标 + 标题 + 副标题)
   注意：实际生效的卡片样式在文件末尾「企业风 / 玻璃覆盖段」里，这里是基础定义 */
.kb-card {
  position: relative;
  display: flex; flex-direction: column; align-items: stretch;
  padding: 20px 20px 18px;
  background: var(--surface);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  text-decoration: none; color: var(--text);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  overflow: hidden;
}
.kb-card::before {
  content: '';
  position: absolute; inset: 0;
  border-radius: inherit;
  background: radial-gradient(600px circle at var(--mx, 50%) var(--my, 50%), rgba(79,70,229,0.06), transparent 40%);
  opacity: 0;
  transition: opacity 0.4s;
  pointer-events: none;
}
.kb-card::after {
  content: '';
  position: absolute; inset: -1px;
  border-radius: inherit;
  opacity: 0;
  transition: opacity 0.4s;
  pointer-events: none;
}
.kb-card[data-type="chat"]::after {
  background: linear-gradient(135deg, rgba(79,70,229,0.08), rgba(6,182,212,0.06));
}
.kb-card[data-type="url"]::after,
.kb-card[data-type="proxy"]::after {
  background: linear-gradient(135deg, rgba(245,158,11,0.08), rgba(239,68,68,0.04));
}
.kb-card:hover {
  transform: translateY(-5px);
  box-shadow: var(--shadow-lg);
}
.kb-card:hover::before { opacity: 1; }
.kb-card:hover::after { opacity: 1; }
.kb-card[data-type="chat"]:hover {
  border-color: rgba(99,102,241,0.3);
  box-shadow: var(--shadow-lg), 0 0 30px var(--primary-glow);
}
.kb-card[data-type="url"]:hover,
.kb-card[data-type="proxy"]:hover {
  border-color: rgba(245,158,11,0.25);
  box-shadow: var(--shadow-lg), 0 0 30px rgba(245,158,11,0.1);
}
.dark-theme .kb-card:hover {
  box-shadow: var(--shadow-lg), 0 0 40px rgba(79,70,229,0.12);
}

.kb-card-type-badge {
  position: absolute; top: 10px; right: 10px;
  display: inline-flex; align-items: center; gap: 3px;
  padding: 3px 8px; border-radius: 20px;
  font-size: 10px; font-weight: 600; letter-spacing: 0.3px;
  z-index: 2; line-height: 1;
}
.kb-card[data-type="chat"] .kb-card-type-badge {
  background: var(--primary-light); color: var(--primary);
}
.kb-card[data-type="url"] .kb-card-type-badge,
.kb-card[data-type="proxy"] .kb-card-type-badge {
  background: #fef3c7; color: #92400e;
}

.kb-card-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 10px;
  margin-bottom: 14px;
}
.kb-card-icon {
  width: 40px; height: 40px; border-radius: 10px;
  overflow: hidden; flex-shrink: 0;
  transition: transform 0.3s, box-shadow 0.3s;
}
.kb-card:hover .kb-card-icon {
  transform: scale(1.05);
}
.kb-card-icon img {
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.14); /* 放大裁掉图片自带的白边 */
}
.kb-card-icon-default {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(135deg, var(--primary), var(--brand-accent-2));
  color: var(--white); font-size: 17px; font-weight: 700;
}
.kb-card-info { text-align: left; width: 100%; }
.kb-card-info h3 {
  font-size: 16px; font-weight: var(--font-weight-semibold);
  margin-bottom: 5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kb-card-desc {
  font-size: 12.5px; line-height: 1.55;
  color: var(--text-secondary);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-all;
}
/* 站点页脚 · 备案号（2026-11-11） */
.site-footer {
  flex-shrink: 0;
  margin-top: auto;
  padding: 16px 16px 20px;
  text-align: center;
  font-size: 12px;
  line-height: 1.8;
  color: var(--text-secondary, #94a3b8);
}
.site-footer a { color: inherit; text-decoration: none; }
.site-footer a:hover { text-decoration: underline; }
.site-footer-sep { opacity: .45; margin: 0 2px; }

/* 小妍卡片：经营理念三支点（2026-11-10，纯文字） */
.kb-card-creed { margin-top: 4px; font-size: 11.5px; line-height: 1.6; color: #1e5aa8; letter-spacing: .2px; word-break: keep-all; }
html.dark-theme .kb-card-creed { color: #8ab6ee; }
/* 系统卡片角标（Skill 分享） */
.kb-entry-pill {
  display: inline-block;
  padding: 3px 9px; border-radius: 20px;
  background: var(--primary-light);
  color: var(--primary);
  font-size: 11px; font-weight: 600;
  line-height: 1.5; white-space: nowrap;
}
/* 右上角更新徽标 */
.kb-card-upd {
  flex-shrink: 0;
  max-width: 55%;
  line-height: 1;
  padding-top: 2px;
}
.kb-upd-date {
  font-size: 11px; color: var(--text-muted);
  white-space: nowrap;
}
.kb-upd-fresh {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11.5px; font-weight: 500; color: #16a34a;
  white-space: nowrap;
}
.kb-upd-dot {
  display: inline-block;
  width: 7px; height: 7px; border-radius: 50%;
  background: #22c55e;
  box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.15);
}
.kb-card-meta {
  display: flex; justify-content: center; gap: 12px;
  font-size: 11px; color: var(--text-secondary);
  margin-top: 8px;
}
.kb-card-meta span {
  display: flex; align-items: center; gap: 3px;
}

/* Dashboard skeleton loading */
.skeleton-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 20px; }
.skeleton-card {
  height: 180px; border-radius: var(--radius-lg);
  background: var(--surface); border: 1px solid var(--border);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
}
.skeleton-icon {
  width: 64px; height: 64px; border-radius: 14px;
  background: var(--surface-hover); animation: pulse 1.5s ease-in-out infinite;
}
.skeleton-line {
  width: 60%; height: 14px; border-radius: 4px;
  background: var(--surface-hover); animation: pulse 1.5s ease-in-out infinite;
}
.skeleton-line.short { width: 40%; }
@keyframes pulse {
  0%, 100% { opacity: 0.5; }
  50% { opacity: 0.2; }
}

/* Dashboard empty state */
.dashboard-empty {
  text-align: center; padding: 80px 20px;
}
.dashboard-empty-icon {
  font-size: 48px; margin-bottom: 16px;
  opacity: 0.3;
}
.dashboard-empty h3 {
  font-size: 18px; font-weight: var(--font-weight-semibold); margin-bottom: 8px;
  color: var(--text);
}
.dashboard-empty p {
  color: var(--text-secondary); font-size: 14px; margin-bottom: 20px;
}

/* ===== Chat (Dark Immersive) ===== */
.dark-theme .chat-container {
  --chat-bg: #0f1117 !important;
  --chat-sidebar-bg: #131625 !important;
  --chat-msg-user: linear-gradient(135deg, #4f46e5, #6366f1) !important;
  --chat-msg-ai: rgba(255,255,255,0.06) !important;
  --chat-msg-text: rgba(255,255,255,0.92) !important;
  --chat-input-bg: rgba(255,255,255,0.06) !important;
  --chat-input-border: rgba(255,255,255,0.12) !important;
}

.chat-container {
  display: flex;
  height: calc(100vh - 60px - 48px);
  gap: 0;
  background: var(--chat-bg, var(--white));
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}

/* Chat Sidebar */
.chat-sidebar {
  width: 280px; min-width: 280px;
  background: var(--chat-sidebar-bg, var(--gray-50));
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  transition: background var(--transition);
}
.chat-sidebar-header {
  display: flex; gap: 8px; padding: 14px 14px 10px;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.chat-sidebar-header .btn { flex: 1; text-align: center; }
.chat-sidebar-title {
  padding: 12px 14px; font-weight: 700; font-size: 13px;
  text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border);
}
.chat-sidebar-search {
  padding: 8px 14px;
}
.chat-sidebar-search input {
  width: 100%; padding: 7px 10px; font-size: 12px;
  background: var(--surface-hover); border: none;
  border-radius: var(--radius-sm); outline: none;
  color: var(--text);
}
.chat-sidebar-search input::placeholder { color: var(--text-secondary); }

.conversation-list {
  flex: 1; overflow-y: auto; padding: 6px 8px;
}
.conv-item {
  padding: 10px 30px 10px 12px;
  border-radius: 8px; cursor: pointer;
  margin-bottom: 2px; position: relative;
  transition: background 0.15s;
}
.conv-item:hover { background: var(--surface-hover); }
.conv-item.active {
  background: var(--primary-light);
  box-shadow: inset 3px 0 0 var(--primary);
}
.dark-theme .conv-item.active {
  background: rgba(79,70,229,0.15);
  box-shadow: inset 3px 0 0 #6366f1;
}
.conv-name {
  font-size: 13px; font-weight: 500;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.conv-time {
  font-size: 10px; color: var(--text-secondary); margin-top: 2px;
}
.conv-empty, .conv-loading {
  padding: 24px 16px; text-align: center;
  color: var(--text-secondary); font-size: 13px;
}
.conv-delete-btn {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 22px; height: 22px; border: none; background: transparent;
  color: var(--text-secondary); font-size: 15px; line-height: 1;
  cursor: pointer; border-radius: 4px; padding: 0;
  opacity: 0; transition: all 0.15s;
  display: flex; align-items: center; justify-content: center;
}
.conv-item:hover .conv-delete-btn { opacity: 1; }
.conv-delete-btn:hover { background: rgba(220,38,38,0.15); color: var(--danger); }

/* Chat Main Area */
.chat-main {
  flex: 1; display: flex; flex-direction: column;
  min-width: 0;
  transition: background var(--transition);
}
.chat-topbar {
  display: flex; align-items: center; justify-content: flex-start; gap: 12px;
  padding: 10px 20px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  transition: background var(--transition);
}
.chat-topbar h3 {
  font-size: 15px; font-weight: 600;
  min-width: 0; flex: 1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-topbar-toggle {
  display: none;
}
.chat-sidebar-overlay {
  display: none;
}
.chat-messages {
  flex: 1; overflow-y: auto; padding: 20px;
  background: var(--chat-bg, var(--white));
  transition: background var(--transition);
}
.chat-welcome {
  text-align: center; padding: 80px 20px 60px;
  position: relative;
}
.chat-welcome::before {
  content: '';
  position: absolute; top: 10%; left: 50%; transform: translateX(-50%);
  width: 300px; height: 300px;
  background: radial-gradient(circle, rgba(79,70,229,0.06), transparent 70%);
  border-radius: 50%;
  pointer-events: none;
}
.chat-welcome h3 {
  font-family: var(--font-heading);
  font-size: 26px; font-weight: var(--font-weight-bold); margin-bottom: 8px;
  color: var(--text);
  letter-spacing: var(--letter-spacing);
  position: relative;
}
.chat-welcome h3::after {
  content: '';
  display: block; width: 40px; height: 3px;
  background: linear-gradient(90deg, var(--primary), transparent);
  border-radius: 2px;
  margin: 14px auto 0;
}
.chat-welcome p {
  color: var(--text-secondary); font-size: 14px;
  margin-top: 12px;
}
.chat-welcome-prompts {
  display: flex; flex-wrap: wrap; gap: 8px; justify-content: center;
  margin-top: 28px;
  position: relative;
}
.chat-welcome-prompts .prompt-chip {
  padding: 9px 18px; border-radius: 20px;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text-secondary); font-size: 13px; cursor: pointer;
  transition: all 0.2s;
  box-shadow: var(--shadow-sm);
}
.chat-welcome-prompts .prompt-chip:hover {
  border-color: var(--primary); color: var(--primary);
  background: var(--primary-light);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(79,70,229,0.12);
}

/* Messages */
.msg {
  margin-bottom: 20px; display: flex;
  animation: msgFadeIn 0.3s ease-out;
}
@keyframes msgFadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}
.msg-user { justify-content: flex-end; flex-wrap: wrap; }
.msg-user .msg-content {
  background: var(--chat-msg-user, var(--primary));
  color: var(--chat-msg-text, var(--white));
  border-radius: 16px 16px 4px 16px;
}
.msg-ai { justify-content: flex-start; flex-direction: column; align-items: flex-start; }
.msg-ai .msg-content {
  background: var(--chat-msg-ai, var(--gray-100));
  color: var(--chat-msg-text, var(--gray-900));
  border-radius: 16px 16px 16px 4px;
}
/* 系统提示（居中灰色胶囊，如文件上传成功/失败提示） */
.msg-system {
  display: flex;
  justify-content: center;
  margin: 2px 0 16px;
}
.msg-system-inner {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text-secondary);
  font-size: 12px;
  line-height: 1.6;
  padding: 5px 14px;
  border-radius: 999px;
  max-width: 85%;
  text-align: center;
}
.msg-system-inner b { color: var(--text); font-weight: 600; }
.msg-system-inner .file-icon { margin-right: 2px; }
.msg-system-error { border-color: var(--danger); color: var(--danger); }
.msg-system-error b { color: var(--danger); }
/* 用户消息气泡内的附件缩略条 */
.msg-user .msg-attachments {
  display: flex; flex-wrap: wrap; gap: 6px;
  flex-basis: 100%;
  justify-content: flex-end;
  margin-top: 8px;
}
.msg-attach-chip {
  display: inline-flex; align-items: center; gap: 5px;
  background: rgba(255,255,255,0.15);
  border: 1px solid rgba(255,255,255,0.35);
  border-radius: 8px;
  padding: 3px 10px;
  font-size: 12px;
  max-width: 200px;
  position: relative;
}
.msg-attach-chip .file-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 附件状态：已就绪 ✓ / 上传中 spinner+百分比 / 失败 */
.msg-attach-chip .attach-status {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: 11px; font-weight: 600;
  flex-shrink: 0;
}
.msg-attach-chip .attach-status.ready { color: #4ade80; }
.msg-attach-chip .attach-status.uploading { color: rgba(255,255,255,0.92); }
.msg-attach-chip .attach-status.up-failed { color: #f87171; }
.msg-attach-chip .attach-spinner {
  width: 10px; height: 10px;
  border: 2px solid rgba(255,255,255,0.3);
  border-top-color: #fff;
  border-radius: 50%;
  animation: attach-spin 0.7s linear infinite;
}
@keyframes attach-spin { to { transform: rotate(360deg); } }
.msg-attach-chip .up-pct { font-variant-numeric: tabular-nums; }
/* 悬浮显示完整文件名 */
.msg-attach-chip::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 6px);
  right: 0;
  background: rgba(17,17,19,0.94);
  color: #fff;
  font-size: 12px;
  line-height: 1.5;
  padding: 5px 10px;
  border-radius: 6px;
  white-space: normal;
  max-width: 320px;
  text-align: left;
  opacity: 0;
  pointer-events: none;
  transform: translateY(4px);
  transition: opacity 0.15s, transform 0.15s;
  z-index: 30;
  box-shadow: var(--shadow-sm);
}
.msg-attach-chip:hover::after {
  opacity: 1;
  transform: translateY(0);
}
.msg-meta {
  font-size: 10px; color: var(--text-secondary);
  margin-bottom: 4px; padding: 0 6px;
}
.msg-user .msg-meta { text-align: right; }
.msg-content {
  padding: 12px 18px;
  max-width: 75%; font-size: 14px;
  line-height: 1.7; word-break: break-word;
  word-wrap: break-word;
  box-shadow: var(--shadow-sm);
}
.msg-content h1, .msg-content h2, .msg-content h3, .msg-content h4 {
  margin: 12px 0 6px; font-weight: 600; line-height: 1.3;
}
.msg-content h1 { font-size: 18px; } .msg-content h2 { font-size: 16px; }
.msg-content h3 { font-size: 15px; }
.msg-content p { margin: 4px 0; }
.msg-content ul, .msg-content ol { margin: 6px 0; padding-left: 20px; }
.msg-content li { margin: 2px 0; }
.msg-content table { border-collapse: collapse; margin: 8px 0; width: 100%; font-size: 13px; }
.msg-content th, .msg-content td {
  border: 1px solid var(--border); padding: 6px 10px; text-align: left;
}
.msg-content th { background: var(--surface-hover); font-weight: 600; }
.msg-content blockquote {
  border-left: 3px solid var(--primary);
  margin: 8px 0; padding: 4px 12px;
  color: var(--text-secondary);
  background: var(--surface-hover);
  border-radius: 0 4px 4px 0;
}
.msg-content a { color: var(--primary); text-decoration: underline; }
.msg-content hr { border: none; border-top: 1px solid var(--border); margin: 12px 0; }
.msg-content img { max-width: 100%; border-radius: 6px; }

/* ===== Reasoning Trail (Agent Thoughts) ===== */
.reasoning-trail {
  margin-bottom: 12px;
  width: 75%;   /* 固定宽度，与正文回答气泡对齐；避免随句子长短来回变化 */
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface);
  font-size: 13px;
  line-height: 1.6;
}
.reasoning-header {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin: 6px 6px 0;
  padding: 4px 10px;
  cursor: pointer;
  user-select: none;
  color: var(--text-secondary);
  font-size: 12px;
  border-radius: 6px;
  transition: background 0.15s;
  max-width: calc(100% - 12px);
}
.reasoning-header:hover {
  background: var(--surface-hover);
}
.reasoning-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  flex-shrink: 0;
  color: var(--text-muted);
}
.reasoning-toggle svg {
  display: block;
  transition: transform 0.15s ease;
}
.reasoning-toggle.reasoning-open svg {
  transform: rotate(90deg);
}
.reasoning-label {
  color: var(--text-secondary);
  font-weight: 500;
}
/* 大模型推理中：标题呼吸动效（思考结束由 markReasoningDone 移除） */
.reasoning-trail.reasoning-thinking .reasoning-label {
  animation: reasoning-pulse 1.6s ease-in-out infinite;
}
@keyframes reasoning-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.55; }
}
.reasoning-time {
  font-size: 11px;
  color: var(--text-muted);
  font-weight: 400;
}
.reasoning-count {
  margin-left: 4px;
  font-size: 11px;
  font-weight: 400;
  color: var(--text-muted);
}
.reasoning-body {
  border-top: 1px solid var(--border);
  padding: 2px 0;
}
.reasoning-collapsed {
  display: none;
}
.reasoning-steps {
  padding: 4px 0;
}
.reasoning-step {
  padding: 6px 12px;
  border-left: 3px solid var(--primary);
  margin: 4px 8px;
  background: var(--bg);
  border-radius: 0 6px 6px 0;
}
.reasoning-thought {
  display: flex;
  align-items: flex-start;
  gap: 4px;
  cursor: pointer;
  user-select: none;
  color: var(--text);
  font-size: 13px;
  margin-bottom: 3px;
}
.reasoning-thought-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  flex-shrink: 0;
  color: var(--text-muted);
  margin-top: 2px;
}
.reasoning-thought-toggle svg {
  display: block;
  transition: transform 0.15s ease;
}
.reasoning-thought-open .reasoning-thought-toggle svg {
  transform: rotate(90deg);
}
.reasoning-thought-text {
  flex: 1;
  min-width: 0;
  /* 字幕式折叠态：单行显示"最新一句"，超长省略 */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  line-height: 1.5;
}
.reasoning-thought-open .reasoning-thought-text {
  white-space: pre-wrap;
  word-break: break-word;
}
/* 字幕式：当前正在思考的活动行呼吸动效 */
.reasoning-thought.reasoning-active .reasoning-thought-text {
  animation: reasoning-pulse 1.6s ease-in-out infinite;
}
/* 推理过程中间输出（agent_thought 的 answer 字段）：阶段性生成的回复反馈 */
.reasoning-answer {
  font-size: 13px;
  color: var(--text);
  background: var(--surface-hover);
  border-left: 3px solid var(--primary);
  margin: 4px 0;
  padding: 5px 10px;
  border-radius: 0 6px 6px 0;
  white-space: pre-wrap;
  word-break: break-word;
}
.reasoning-observation {
  font-size: 12px;
  color: var(--text-muted);
  padding: 2px 0 2px 20px;
  word-break: break-word;
}
/* 过程旁白（agent_message 的非答案部分）：弱化样式，区别于 agent_thought 中间输出（💬） */
.reasoning-narration {
  font-size: 12px;
  color: var(--text-muted);
  font-style: italic;
  padding: 2px 12px;
  margin: 2px 0;
  word-break: break-word;
  white-space: pre-wrap;
}

/* 单个工具调用：可折叠按钮（对齐原版 Dify：🔨 工具名 ▸） */
.reasoning-tool-call {
  margin: 4px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  background: var(--bg);
}
.reasoning-tool-header {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 4px 10px;
  cursor: pointer;
  user-select: none;
  color: var(--text-secondary);
  font-size: 12px;
  transition: background 0.15s;
}
.reasoning-tool-header:hover {
  background: var(--surface-hover);
}
.reasoning-tool-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: var(--text-muted);
}
.reasoning-tool-icon svg {
  display: block;
}
.reasoning-tool-name {
  font-weight: 500;
  color: var(--text-secondary);
  font-family: var(--font-mono);
  font-size: 12px;
  flex-shrink: 0;
}
/* 工具入参摘要：折叠态下一行显示"这一步在做什么"（超长省略，展开可看完整请求） */
.reasoning-tool-summary {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--text-muted);
  font-size: 11.5px;
  font-family: var(--font-mono);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.reasoning-tool-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  flex-shrink: 0;
  color: var(--text-muted);
}
.reasoning-tool-arrow svg {
  display: block;
  transition: transform 0.15s ease;
}
.reasoning-tool-arrow.reasoning-open svg {
  transform: rotate(90deg);
}
/* 工具调用状态徽标（对齐原版 Dify Using/Used） */
.reasoning-tool-status {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
  padding: 1px 8px;
  border-radius: 999px;
  font-size: 11px;
  line-height: 1.5;
  flex-shrink: 0;
}
.reasoning-tool-status.running {
  color: var(--accent-cool);
  background: var(--primary-light);
}
.reasoning-tool-status.done {
  color: var(--success);
  background: rgba(16, 185, 129, 0.12);
}
.reasoning-tool-status.interrupted {
  color: #f59e0b;
  background: rgba(245, 158, 11, 0.12);
}
.reasoning-tool-status .spinner {
  width: 10px;
  height: 10px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: reasoning-spin 0.8s linear infinite;
}
@keyframes reasoning-spin {
  to { transform: rotate(360deg); }
}
.reasoning-tool-body {
  border-top: 1px solid var(--border);
  padding: 8px 12px;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.6;
  word-break: break-all;
  background: var(--surface);
}
.reasoning-tool-io {
  display: flex;
  gap: 8px;
  margin-bottom: 4px;
}
.reasoning-tool-io:last-child {
  margin-bottom: 0;
}
.reasoning-tool-io-label {
  flex-shrink: 0;
  color: var(--text-muted);
  min-width: 28px;
}
.reasoning-tool-io-content {
  margin: 0;
  color: var(--text);
  white-space: pre-wrap;
  word-break: break-word;
  flex: 1;
}

/* 消息统计行（耗时 / Token / tokens/s / 成本 / 时间）—— 对齐原版 Dify */
.msg-stats {
  margin-top: 8px;
  padding-left: 6px;
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.5;
}

/* 单条问答成本（估算值，悬停看明细）；等宽数字避免刷新时宽度跳动 */
.msg-cost {
  color: #2563eb;
  font-variant-numeric: tabular-nums;
  cursor: help;
}
.dark-theme .msg-cost { color: #7fb0f5; }

/* agent 气泡反馈行内的复制按钮：与 👍👎 视觉一致（默认半透明，hover 浮现） */
.msg-feedback .msg-action-btn {
  width: 24px; height: 22px;
  font-size: 12px;
  border-radius: 6px;
  opacity: 0.4;
}
.msg-feedback .msg-action-btn:hover {
  opacity: 1;
  background: var(--surface-hover);
  color: var(--primary);
  border-color: var(--primary);
}

/* Feedback buttons */
.msg-feedback {
  display: flex; gap: 4px; padding: 4px 0 0 6px;
  opacity: 0; transition: opacity 0.25s;
}
.msg-ai:hover .msg-feedback,
.msg-feedback:has(.feedback-btn.active) { opacity: 1; }
.feedback-btn {
  background: none; border: 1px solid var(--border); border-radius: 6px;
  cursor: pointer; font-size: 13px; padding: 2px 7px; line-height: 1.3;
  transition: all 0.15s; opacity: 0.4;
}
.feedback-btn:hover { opacity: 1; background: var(--surface-hover); }
.feedback-btn.active { opacity: 1; border-color: var(--primary); background: var(--primary-light); }
.feedback-btn.feedback-like.active { border-color: #22c55e; background: rgba(34,197,94,0.1); }
.feedback-btn.feedback-dislike.active { border-color: #ef4444; background: rgba(239,68,68,0.1); }

/* 用户消息操作：复制/重发（hover 显示，位于气泡左侧） */
.msg-user .msg-actions {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 0 8px 0 4px;
  opacity: 0;
  transition: opacity 0.15s;
}
.msg-user:hover .msg-actions { opacity: 1; }
.msg-action-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 13px;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
  padding: 0;
  line-height: 1;
}
.msg-action-btn:hover {
  background: var(--surface-hover);
  color: var(--primary);
  border-color: var(--primary);
}

/* Code blocks in chat */
.msg-content pre {
  position: relative;
  background: #1a1b2e; color: #e2e8f0;
  font-family: var(--font-mono);
  padding: 14px 16px; border-radius: 10px;
  overflow-x: auto; margin: 10px 0; font-size: 13px;
  border: 1px solid rgba(255,255,255,0.06);
}
.msg-content code {
  background: rgba(0,0,0,.08); padding: 2px 6px;
  border-radius: 4px; font-size: 13px;
}
.msg-content pre code { background: none; padding: 0; }
.code-lang-label {
  position: absolute; top: 6px; right: 36px;
  font-size: 10px; color: rgba(255,255,255,0.3);
  text-transform: uppercase; letter-spacing: 0.5px;
}
.copy-btn {
  position: absolute; top: 6px; right: 6px;
  width: 24px; height: 24px; border: none; border-radius: 4px;
  background: rgba(255,255,255,0.08); color: rgba(255,255,255,0.5);
  font-size: 12px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: all 0.2s; opacity: 0;
}
.msg-content pre:hover .copy-btn { opacity: 1; }
.copy-btn:hover { background: rgba(255,255,255,0.15); color: #fff; }
.copy-btn.copied { opacity: 1; background: rgba(5,150,105,0.3); color: #34d399; }

/* Typing indicator */
.typing-indicator {
  display: flex; align-items: center; gap: 4px;
  padding: 12px 18px; margin-bottom: 20px;
}
.typing-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--text-secondary);
  animation: typingBounce 1.4s ease-in-out infinite;
}
.typing-dot:nth-child(2) { animation-delay: 0.2s; }
.typing-dot:nth-child(3) { animation-delay: 0.4s; }
@keyframes typingBounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
  30% { transform: translateY(-6px); opacity: 0.8; }
}

/* Scroll-to-bottom button */
.scroll-bottom-btn {
  position: absolute; bottom: 100px; left: 50%; transform: translateX(-50%);
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text-secondary); cursor: pointer;
  box-shadow: var(--shadow-md);
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; transition: all 0.2s; z-index: 5;
}
.scroll-bottom-btn:hover { transform: translateX(-50%) translateY(-2px); border-color: var(--primary); color: var(--primary); }

/* ===== Chat Input Area ===== */
.chat-input-area {
  padding: 0 16px 12px;
  /* 与消息区同底色、不要分隔线：输入区融进对话流，只靠输入框自身的边框区分 */
  background: var(--chat-bg);
  position: relative;
}
/* 输入框下方的 AI 生成提示：常驻、低调，不抢输入区焦点 */
.chat-disclaimer {
  margin: 6px 0 0;
  text-align: center;
  font-size: 11px;
  line-height: 1.5;
  color: var(--text-muted);
  letter-spacing: 0.02em;
  user-select: none;
  pointer-events: none;
}
.dark-theme .chat-disclaimer { color: var(--text-secondary); }
.chat-input-card {
  display: flex; flex-wrap: wrap; align-items: stretch;
  /* 与消息区同底色，整块输入框只靠 1px 边框成形（改 --bg 会重新出现灰色块） */
  background: var(--chat-bg);
  border: 1px solid var(--border);
  border-radius: 16px;
  transition: border-color 0.2s, box-shadow 0.2s, background 0.2s;
  overflow: hidden;
  padding: 8px 12px;
  gap: 8px;
}
/* 同底色下边框是唯一的分界，鼠标移入时略微加深，避免看不出这里能输入 */
.chat-input-card:hover { border-color: var(--gray-300); }
.chat-input-card:focus-within {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-glow);
}
.chat-attach-btn {
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  width: 32px; min-height: 32px;
  align-self: flex-end;
  background: none; border: none; cursor: pointer;
  color: var(--text-muted);
  border-radius: 8px;
  transition: background 0.15s, color 0.15s;
  padding: 0;
}
.chat-attach-btn:hover {
  background: var(--surface-hover);
  color: var(--text);
}
.chat-input-inner {
  flex: 1;
  display: flex;
  min-height: 32px;
}
.chat-input-inner textarea {
  flex: 1;
  padding: 5px 0;
  border: none; outline: none; resize: none;
  font-size: 14px; line-height: 1.5;
  font-family: inherit;
  background: transparent;
  color: var(--text);
  max-height: 150px;
  align-self: center;
}
.chat-input-inner textarea::placeholder {
  color: var(--text-muted);
}
.chat-send-btn {
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  width: 32px; min-height: 32px;
  align-self: flex-end;
  border: none; cursor: pointer;
  border-radius: 8px;
  background: var(--primary);
  color: #fff;
  transition: background 0.15s, transform 0.12s, opacity 0.15s;
  padding: 0;
}
.chat-send-btn:hover {
  background: var(--primary-hover, #4338ca);
}
.chat-send-btn:active {
  transform: scale(0.92);
}
.chat-send-btn:disabled {
  opacity: 0.35; cursor: default; transform: none;
}
.chat-send-btn.is-stop {
  background: var(--danger);
}
.chat-send-btn.is-stop:hover {
  background: #dc2626;
}

/* File preview inside card */
.chat-input-card .file-preview {
  display: none; flex-wrap: wrap; gap: 6px;
  padding: 0 0 8px;
  flex: 1 1 100%;
}
.chat-input-card .file-preview.has-files {
  display: flex;
}
.chat-input-card .file-preview-item {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 10px 4px 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px; font-size: 13px;
  transition: border-color 0.15s, opacity 0.2s;
}
.chat-input-card .file-preview-item .file-icon { flex-shrink: 0; }
.chat-input-card .file-preview-item .file-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 120px;
  color: var(--text);
}
.chat-input-card .file-preview-item .file-size {
  color: var(--text-muted); font-size: 11px; white-space: nowrap;
}
.chat-input-card .file-preview-item .file-remove {
  cursor: pointer; opacity: 0.35; padding: 1px 2px;
  line-height: 1; font-size: 16px; flex-shrink: 0; margin-left: 2px;
  transition: opacity 0.15s;
}
.chat-input-card .file-preview-item .file-remove:hover { opacity: 1; }
.chat-input-card .file-preview-item.uploading { opacity: 0.5; }
.chat-input-card .file-preview-item.upload-error {
  border-color: var(--danger);
  background: rgba(239,68,68,0.08);
}

/* Drag overlay */
.chat-input-area.drag-over .chat-input-card {
  position: relative;
}
.chat-input-area.drag-over .chat-input-card::after {
  content: '松开以上传文件';
  position: absolute; inset: 0; z-index: 10;
  display: flex; align-items: center; justify-content: center;
  background: rgba(79,70,229,0.08);
  backdrop-filter: blur(2px);
  border-radius: 16px;
  font-size: 14px; color: var(--primary); font-weight: 500;
  pointer-events: none;
}

/* ===== Viewer ===== */
.viewer-container {
  display: flex; flex-direction: column;
  height: calc(100vh - 60px);
  overflow: hidden;
  position: relative;
}
.viewer-toolbar {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 20px;
  background: var(--surface); border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
.viewer-toolbar .viewer-title {
  flex: 1; font-weight: 600; font-size: 15px;
  color: var(--text);
}
.viewer-iframe {
  flex: 1; width: 100%; border: none; background: var(--white);
}
/* 查看器页面：取消 1600px 最大宽度与内边距，让内嵌页面以最大宽度显示，
   保持其原始页面格式，不被压缩或拉伸 */
.main-content:has(.viewer-container) {
  max-width: none;
  padding: 0;
}
.main-content:has(.viewer-container) .viewer-container {
  height: calc(100vh - 60px);
}
.viewer-loading {
  position: absolute; inset: 0; top: 44px; z-index: 2;
  display: flex; align-items: center; justify-content: center; gap: 12px;
  background: var(--bg); color: var(--text-secondary); font-size: 14px;
}
.viewer-spinner {
  width: 20px; height: 20px;
  border: 2px solid var(--border);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: viewerSpin 0.6s linear infinite;
}
@keyframes viewerSpin { to { transform: rotate(360deg); } }
.viewer-error {
  position: absolute; inset: 0; top: 44px; z-index: 2;
  display: flex; align-items: center; justify-content: center; gap: 12px;
  background: var(--bg); color: var(--danger); font-size: 14px;
}

/* ===== Admin Layout ===== */
.admin-container {
  display: flex; gap: 24px;
  align-items: flex-start;
}
.admin-sidebar {
  position: sticky;
  top: 84px;
  width: 220px; min-width: 220px;
  background: var(--bg);
  padding: 0 0 16px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  overflow-y: auto;
  height: fit-content;
  max-height: calc(100vh - 108px);
  display: flex; flex-direction: column;
}
.admin-sidebar-brand {
  display: flex; align-items: center; gap: 8px;
  padding: 16px 18px 14px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.admin-sidebar-brand-icon {
  width: 28px; height: 28px; border-radius: 8px;
  background: linear-gradient(135deg, var(--primary), var(--brand-accent-2));
  color: #fff; display: flex; align-items: center; justify-content: center;
  font-size: 14px; font-weight: 700; flex-shrink: 0;
}
.admin-sidebar-brand h3 {
  font-size: 13px; font-weight: 700;
  letter-spacing: 0.5px;
  color: var(--text);
  margin: 0;
}
.admin-nav-section {
  padding: 12px 8px 6px 18px;
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 1px; color: var(--text-muted);
}
.admin-nav-item {
  display: flex; align-items: center; gap: 10px;
  margin: 1px 8px;
  padding: 9px 14px; border-radius: 8px;
  color: var(--text-secondary); text-decoration: none;
  font-size: 14px; font-weight: 500;
  transition: all 0.15s;
  position: relative;
  cursor: pointer;
}
.admin-nav-item:hover {
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 1px 3px rgba(0,0,0,.04);
}
.admin-nav-item.active {
  background: var(--surface);
  color: var(--primary);
  font-weight: 600;
  box-shadow: 0 1px 3px rgba(0,0,0,.06);
}
.admin-nav-item.active::before {
  content: '';
  position: absolute; left: -8px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 20px;
  background: var(--primary);
  border-radius: 0 3px 3px 0;
}
.admin-nav-item .nav-icon { font-size: 15px; width: 22px; text-align: center; flex-shrink: 0; }
.admin-nav-item .icon { display: inline-flex; vertical-align: middle; }

.admin-content {
  flex: 1;
  background: var(--surface);
  padding: 28px;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  min-width: 0;
  border: 1px solid var(--border);
}
.admin-content h2 {
  font-family: var(--font-heading);
  font-size: 22px; font-weight: var(--font-weight-bold); margin-bottom: 20px;
  color: var(--text);
  letter-spacing: 0.3px;
}

/* Stats Grid */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
  margin-bottom: 32px;
}
.stat-card {
  position: relative;
  background: var(--bg); padding: 24px;
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid var(--border);
  transition: transform 0.2s, box-shadow 0.2s;
}
.stat-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); }
.stat-card::before {
  content: ''; position: absolute; top: 0; left: 0;
  width: 100%; height: 3px;
}
.stat-card:nth-child(1)::before { background: linear-gradient(90deg, var(--primary), var(--brand-accent-2)); }
.stat-card:nth-child(2)::before { background: linear-gradient(90deg, #059669, #34d399); }
.stat-card:nth-child(3)::before { background: linear-gradient(90deg, #d97706, #fbbf24); }
.stat-card:nth-child(4)::before { background: linear-gradient(90deg, #dc2626, #f87171); }
.stat-number {
  font-size: 32px; font-weight: var(--font-weight-extrabold);
  font-family: var(--font-heading);
  color: var(--text); line-height: 1.2;
  letter-spacing: -0.02em;
}
.stat-label {
  font-size: 13px; color: var(--text-secondary);
  margin-top: 4px; font-weight: 500;
}

/* Charts */
.chart-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 16px;
}
.chart-toolbar h3 { font-size: 15px; font-weight: 600; color: var(--text); }
.chart-toggle { display: flex; gap: 8px; }
.chart-container { position: relative; height: 360px; width: 100%; }
.charts-grid { display: grid; grid-template-columns: 1fr; gap: 24px; }
.chart-panel {
  background: var(--bg); padding: 20px;
  border-radius: var(--radius); border: 1px solid var(--border);
}

/* ===== Forms ===== */
.form-group { margin-bottom: 14px; }
.form-group label {
  display: block; font-size: 13px; font-weight: 600;
  margin-bottom: 5px; color: var(--text-secondary);
}
.form-input {
  width: 100%; padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius); font-size: 14px;
  outline: none; background: var(--bg);
  color: var(--text);
  transition: border-color 0.2s, box-shadow 0.2s;
}
.form-input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-glow);
}
.form-input::placeholder { color: var(--text-secondary); }
select.form-input { cursor: pointer; }
.form-inline { width: 180px; display: inline-block; margin-right: 8px; }
.form-inline-sm { width: 120px; display: inline-block; margin-right: 4px; }
.inline-form {
  margin-bottom: 20px; padding: 20px;
  background: var(--bg); border-radius: var(--radius);
  border: 1px solid var(--border);
}
.kb-form {
  padding: 20px; background: var(--bg);
  border-radius: var(--radius); border: 1px solid var(--border);
}
.add-form-details { margin-bottom: 20px; }
.add-form-details summary {
  cursor: pointer; padding: 8px 16px;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); color: var(--text);
  font-size: 14px; font-weight: 500;
  display: inline-flex; align-items: center; gap: 6px;
}
.add-form-details[open] summary {
  border-radius: var(--radius) var(--radius) 0 0;
  border-bottom: none;
}

/* ===== Buttons ===== */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 6px;
  padding: 10px 20px; border-radius: var(--radius); font-size: 14px;
  font-weight: 500; cursor: pointer; border: none;
  text-decoration: none; text-align: center;
  transition: all 0.15s;
  line-height: 1.4;
}
.btn-primary { background: var(--primary); color: var(--white); }
.btn-primary:hover { background: var(--primary-hover); box-shadow: 0 4px 12px var(--primary-glow); }
.btn-outline {
  background: transparent; color: var(--text-secondary);
  border: 1px solid var(--border);
}
.btn-outline:hover { background: var(--surface-hover); color: var(--text); border-color: var(--gray-300); }
.btn-danger { background: var(--danger); color: var(--white); }
.btn-danger:hover { background: var(--danger-hover); }
.btn-sm { padding: 6px 12px; font-size: 12px; border-radius: var(--radius-sm); }
.btn-block { display: flex; width: 100%; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* ===== Data Tables ===== */
.data-table-wrapper {
  border: 1px solid var(--border);
  border-radius: var(--radius); overflow: hidden;
}
.data-table {
  width: 100%; border-collapse: collapse; font-size: 13px;
}
.data-table th {
  text-align: left; padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  font-family: var(--font-heading);
  font-weight: 600; font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--text-secondary);
  background: var(--bg);
  white-space: nowrap;
}
.data-table td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
}
.data-table tbody tr:nth-child(even) td { background: var(--bg); }
.data-table tbody tr:hover td { background: var(--surface-hover); }
.data-table tbody tr:last-child td { border-bottom: none; }
.td-actions { white-space: nowrap; }
.td-empty {
  text-align: center; color: var(--text-secondary);
  padding: 32px 14px;
}
.td-query { max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.td-answer { max-width: 250px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.td-ip code { font-size: 12px; font-family: 'SF Mono', Consolas, monospace; }

/* 反馈分析弹窗内容 */
.fb-detail-section strong {
  display: block; font-size: 12px; color: var(--text-secondary);
  margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.5px;
}
.fb-detail-content {
  font-size: 14px; line-height: 1.7;
  padding: 10px 14px; background: var(--bg);
  border-radius: 8px; border: 1px solid var(--border);
  white-space: pre-wrap; word-break: break-word;
}
.fb-detail-content.markdown-body {
  white-space: normal;
}
.fb-detail-content.markdown-body p { margin: 0 0 6px; }
.fb-detail-content.markdown-body p:last-child { margin-bottom: 0; }
.fb-detail-content.markdown-body code {
  background: rgba(0,0,0,0.06); padding: 1px 5px; border-radius: 4px; font-size: 13px;
}
.dark-theme .fb-detail-content.markdown-body code { background: rgba(255,255,255,0.08); }
.fb-detail-content.markdown-body pre {
  background: rgba(0,0,0,0.06); padding: 12px; border-radius: 8px; overflow-x: auto; margin: 6px 0;
}
.dark-theme .fb-detail-content.markdown-body pre { background: rgba(0,0,0,0.3); }
.fb-detail-content.markdown-body pre code { background: none; padding: 0; }
.fb-detail-content.markdown-body ul,
.fb-detail-content.markdown-body ol { margin: 4px 0; padding-left: 20px; }

/* ===== Badges ===== */
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 10px; border-radius: 20px;
  font-size: 11px; font-weight: 600; white-space: nowrap;
}
.badge-admin { background: #fef3c7; color: #92400e; }
.badge-user { background: #dbeafe; color: #1e40af; }
.badge-success { background: #d1fae5; color: #065f46; }
.badge-danger { background: #fee2e2; color: #991b1b; }
.badge-url { background: #fef3c7; color: #92400e; }
.badge-proxy { background: #ede9fe; color: #5b21b6; }
.badge-embed { background: #cffafe; color: #155e75; }
.badge-html { background: #d1fae5; color: #065f46; }
.badge-dify { background: #f0fdf4; color: #166534; }
.badge-genieai { background: #dbeafe; color: #1e40af; }
.badge-dify { background: #fce7f3; color: #9d174d; }
.badge-info { background: var(--primary-light); color: var(--primary); font-size:12px; padding:2px 8px; border-radius:10px; }

/* ===== Alerts ===== */
.alert {
  padding: 12px 16px; border-radius: var(--radius);
  margin-bottom: 16px; font-size: 14px;
  display: flex; align-items: center; gap: 8px;
}
.alert-error { background: #fee2e2; color: #991b1b; }
.alert-success { background: #d1fae5; color: #065f46; }

/* ===== Accessibility ===== */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ===== Toast Notification ===== */
.toast-container {
  position: fixed; top: 76px; right: 24px; z-index: 9999;
  display: flex; flex-direction: column; gap: 8px;
}
.toast {
  padding: 12px 20px; border-radius: var(--radius);
  font-size: 14px; font-weight: 500;
  box-shadow: var(--shadow-lg);
  display: flex; align-items: center; gap: 10px;
  animation: toastIn 0.3s ease-out;
  max-width: 360px;
}
@keyframes toastIn {
  from { opacity: 0; transform: translateX(20px); }
  to { opacity: 1; transform: translateX(0); }
}
.toast-success { background: #065f46; color: #d1fae5; }
.toast-error { background: #991b1b; color: #fee2e2; }
.toast-icon { font-size: 16px; }

/* ===== Edit inline ===== */
.edit-form {
  margin-top: 8px; padding: 16px;
  background: var(--bg); border-radius: var(--radius);
  border: 1px solid var(--border);
}

/* ===== Permissions ===== */
.perm-checkbox-list {
  display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px;
}
.perm-checkbox-label {
  display: flex; align-items: center; gap: 4px; font-size: 13px;
  padding: 5px 12px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-sm); cursor: pointer; user-select: none;
  transition: all 0.15s;
}
.perm-checkbox-label:hover { border-color: var(--primary); }
.perm-checkbox-label:has(input:checked) {
  background: var(--primary-light); border-color: var(--primary);
}
.perm-checkbox-label input[type="checkbox"] { accent-color: var(--primary); }
.perm-empty { color: var(--text-secondary); font-size: 13px; }

/* ===== Empty State ===== */
.empty-state {
  text-align: center; padding: 80px 20px;
}
.empty-state h2 { font-size: 48px; margin-bottom: 8px; color: var(--text); }
.empty-state p { margin-bottom: 16px; color: var(--text-secondary); }

/* ===== Logs Filter ===== */
.log-filter-bar {
  display: flex; align-items: center;
  justify-content: space-between;
  margin-bottom: 16px; flex-wrap: wrap; gap: 8px;
}
.filter-form {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
}
.filter-form label { font-size: 13px; color: var(--text-secondary); }
.filter-input { width: 140px; padding: 6px 10px; font-size: 13px; }

/* ===== Pagination ===== */
.pagination {
  display: flex; align-items: center;
  justify-content: space-between;
  margin-top: 20px; padding: 16px 0 4px;
  border-top: 1px solid var(--border);
}
.pagination span { font-size: 13px; color: var(--text-secondary); }
.pagination-btns { display: flex; gap: 4px; align-items: center; }
.pagination-btns .btn { min-width: 32px; }

/* ===== Modal ===== */
.modal-overlay {
  position: fixed; top: 0; left: 0;
  width: 100%; height: 100%;
  background: rgba(0,0,0,0.5);
  z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  animation: modalOverlayIn 0.2s ease-out;
}
@keyframes modalOverlayIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
.modal-content {
  background: var(--surface); border-radius: var(--radius-lg);
  width: 90%; max-width: 800px;
  max-height: 80vh;
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-lg), 0 20px 60px rgba(0,0,0,0.15);
  border: 1px solid var(--border);
  animation: modalIn 0.25s ease-out;
}
@keyframes modalIn {
  from { opacity: 0; transform: scale(0.95) translateY(10px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}
.modal-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 24px;
  border-bottom: 1px solid var(--border);
}
.modal-header h3 { font-size: 17px; font-weight: var(--font-weight-bold); color: var(--text); margin: 0; }
.modal-body {
  flex: 1; overflow-y: auto; padding: 24px;
}

/* 回答图片预览模态框 */
.share-img-modal { max-width: 560px; width: 92vw; }
.share-img-body {
  padding: 12px;
  overflow: auto;
  display: flex;
  justify-content: center;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.share-img-body img {
  max-width: 100%;
  height: auto;
  display: block;
  border-radius: 6px;
}

/* Modal form helpers */
.modal-body .form-group { margin-bottom: 18px; }
.modal-body .form-group label { font-size: 13px; font-weight: 600; margin-bottom: 6px; color: var(--text); }
.form-row-inline { display: flex; gap: 16px; align-items: flex-start; }
.modal-actions {
  display: flex; gap: 8px; justify-content: flex-end;
  margin-top: 24px; padding-top: 16px;
  border-top: 1px solid var(--border);
}
.modal-actions .btn { min-width: 80px; padding: 10px 24px; }

/* Conversation detail in modal */
.conv-msg { margin-bottom: 16px; }

/* ===== Icon preview ===== */
.icon-preview {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px;
  background: var(--gray-50);
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  min-height: 60px;
}
.icon-preview img {
  max-width: 64px; max-height: 64px;
  border-radius: 6px;
  border: 1px solid var(--border);
  object-fit: contain;
  background: var(--white);
}
.icon-preview-empty {
  color: var(--text-muted);
  font-size: 13px;
}
.conv-msg-user { text-align: right; }
.conv-msg-user .conv-bubble {
  background: var(--primary); color: var(--white);
  display: inline-block;
  border-radius: 12px 12px 4px 12px;
}
.conv-msg-ai .conv-bubble {
  background: var(--bg); color: var(--text);
  display: inline-block;
  border-radius: 12px 12px 12px 4px;
  border: 1px solid var(--border);
}
.conv-bubble {
  padding: 10px 16px; max-width: 85%;
  font-size: 14px; line-height: 1.7; word-break: break-word;
}
/* Markdown 渲染样式 */
.conv-bubble.markdown-body p { margin: 0 0 8px; }
.conv-bubble.markdown-body p:last-child { margin-bottom: 0; }
.conv-bubble.markdown-body ul,
.conv-bubble.markdown-body ol { margin: 4px 0; padding-left: 20px; }
.conv-bubble.markdown-body li { margin-bottom: 2px; }
.conv-bubble.markdown-body code {
  background: rgba(0,0,0,0.06); padding: 2px 6px; border-radius: 4px;
  font-size: 13px; font-family: 'SF Mono', Consolas, monospace;
}
.dark-theme .conv-bubble.markdown-body code {
  background: rgba(255,255,255,0.08);
}
.conv-bubble.markdown-body pre {
  background: rgba(0,0,0,0.06); padding: 12px; border-radius: 8px;
  overflow-x: auto; margin: 8px 0;
}
.dark-theme .conv-bubble.markdown-body pre {
  background: rgba(0,0,0,0.3);
}
.conv-bubble.markdown-body pre code {
  background: none; padding: 0; border-radius: 0;
}
.conv-bubble.markdown-body h1,
.conv-bubble.markdown-body h2,
.conv-bubble.markdown-body h3,
.conv-bubble.markdown-body h4 { margin: 8px 0 4px; }
.conv-bubble.markdown-body table { border-collapse: collapse; margin: 8px 0; width: 100%; }
.conv-bubble.markdown-body th,
.conv-bubble.markdown-body td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; }
.conv-bubble.markdown-body blockquote {
  border-left: 3px solid var(--primary); margin: 8px 0; padding: 4px 12px;
  color: var(--text-secondary); background: var(--surface-hover);
  border-radius: 0 6px 6px 0;
}
.conv-bubble.markdown-body a { color: var(--primary); text-decoration: underline; }
/* 版本更新条目 Markdown 渲染 */
.version-md-content { font-size: 12px; color: var(--text-secondary); line-height: 1.75; }
.version-md-content p { margin: 0 0 6px; }
.version-md-content p:last-child { margin-bottom: 0; }
.version-md-content ul,
.version-md-content ol { margin: 4px 0; padding-left: 20px; }
.version-md-content li { margin-bottom: 3px; }
.version-md-content li::marker { color: var(--primary); }
.version-md-content code {
  background: rgba(0,0,0,0.06); padding: 2px 6px; border-radius: 4px;
  font-size: 12px; font-family: 'SF Mono', Consolas, monospace;
}
.dark-theme .version-md-content code { background: rgba(255,255,255,0.08); }
.version-md-content pre {
  background: rgba(0,0,0,0.06); padding: 10px 12px; border-radius: 8px;
  overflow-x: auto; margin: 8px 0;
}
.dark-theme .version-md-content pre { background: rgba(0,0,0,0.3); }
.version-md-content pre code { background: none; padding: 0; border-radius: 0; }
.version-md-content h1,
.version-md-content h2,
.version-md-content h3,
.version-md-content h4 { margin: 8px 0 4px; color: var(--text); }
.version-md-content h1 { font-size: 15px; }
.version-md-content h2 { font-size: 14px; }
.version-md-content h3 { font-size: 13px; }
.version-md-content table { border-collapse: collapse; margin: 8px 0; width: 100%; }
.version-md-content th,
.version-md-content td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; }
.version-md-content blockquote {
  border-left: 3px solid var(--primary); margin: 8px 0; padding: 4px 12px;
  color: var(--text-secondary); background: var(--surface-hover);
  border-radius: 0 6px 6px 0;
}
.version-md-content a { color: var(--primary); text-decoration: underline; }
.version-md-content strong { color: var(--text); font-weight: 600; }
.conv-label {
  font-size: 11px; color: var(--text-secondary);
  margin-bottom: 4px; padding: 0 4px;
}

/* ===== Login Logs Page ===== */
/* Stats row */
.log-stats-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  margin-bottom: 22px;
}
.log-stat-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow-sm);
  transition: transform 0.2s, box-shadow 0.2s;
}
.log-stat-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}
.log-stat-icon {
  width: 44px;
  height: 44px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  flex-shrink: 0;
}
.log-stat-info {
  min-width: 0;
}
.log-stat-num {
  font-size: 24px;
  font-weight: 700;
  color: var(--text);
  line-height: 1.2;
  letter-spacing: -0.02em;
}
.log-stat-label {
  font-size: 12px;
  color: var(--text-secondary);
  margin-top: 2px;
  font-weight: 500;
}
/* Toolbar */
.log-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.log-filter-form {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.log-filter-group {
  display: flex;
  align-items: center;
  gap: 6px;
}
.log-filter-group label {
  font-size: 12px;
  color: var(--text-secondary);
  font-weight: 500;
  white-space: nowrap;
}
.log-date-input {
  padding: 6px 10px;
  font-size: 13px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  color: var(--text);
  outline: none;
  font-family: inherit;
}
.log-date-input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-glow);
}
.log-export-btn {
  flex-shrink: 0;
}
/* Table */
.log-table {
  border-radius: 10px;
}
.log-data-table {
  table-layout: fixed;
}
.log-data-table td, .log-data-table th {
  padding: 12px 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.col-id { width: 6%; }
.col-user { width: 14%; }
.col-nick { width: 12%; }
.col-time { width: 18%; white-space: nowrap; }
.col-ip { width: 22%; }
.col-loc { width: 18%; }
.col-device { width: 10%; }
.log-nickname {
  font-size: 13px;
  color: var(--text);
}
.log-id-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 28px;
  height: 24px;
  padding: 0 6px;
  border-radius: 6px;
  background: var(--gray-100);
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  font-family: var(--font-mono);
}
.log-username {
  font-weight: 500;
  color: var(--text);
  font-size: 13px;
}
.log-ip {
  font-size: 12px;
  font-family: var(--font-mono);
  display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.log-empty { color: var(--text-muted); }
.device-badge {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
}
.device-desktop {
  background: var(--primary-light);
  color: var(--primary);
}
.device-mobile {
  background: #fef3c7;
  color: #d97706;
}
.dark-theme .device-desktop {
  background: rgba(99,102,241,0.15);
  color: #a5b4fc;
}
.dark-theme .device-mobile {
  background: rgba(251,191,36,0.15);
  color: #fbbf24;
}
.log-pagination {
  margin-top: 16px;
}
.log-page-info {
  font-size: 12px;
  color: var(--text-secondary);
}
.log-page-btns { gap: 3px; }
.log-page-ellipsis {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 24px; padding: 0 4px;
  font-size: 12px; color: var(--text-secondary);
}

/* Map section */
.log-map-section {
  margin-top: 28px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.log-map-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 18px 22px;
  border-bottom: 1px solid var(--border);
}
.log-map-header span {
  font-size: 18px;
  line-height: 1;
}
.log-map-header h3 {
  font-size: 15px;
  font-weight: var(--font-weight-semibold);
  color: var(--text);
  margin: 0;
}
.log-map-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 10px;
  border-radius: 12px;
  background: var(--primary-light);
  color: var(--primary);
  font-size: 11px;
  font-weight: 600;
  margin-left: auto;
}
.log-map-body {
  padding: 6px;
}

/* Responsive */
@media (max-width: 1024px) {
  .log-stats-row { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
  .log-stats-row { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .log-stat-card { padding: 12px 14px; }
  .log-stat-num { font-size: 20px; }
  .log-toolbar { flex-direction: column; align-items: stretch; }
  .log-filter-form { flex-wrap: wrap; }
  .log-map-body { padding: 2px; }
}
@media (max-width: 480px) {
  .log-stats-row { grid-template-columns: 1fr 1fr; gap: 8px; }
  .log-stat-card { padding: 10px 12px; gap: 10px; }
  .log-stat-icon { width: 36px; height: 36px; font-size: 16px; }
  .log-stat-num { font-size: 18px; }
}

/* ===== China Map Card (legacy, for logs.ejs) ===== */
.map-card {
  margin-top: 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.map-card-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
}
.map-card-icon {
  font-size: 18px;
  line-height: 1;
}
.map-card-header h3 {
  font-size: 15px;
  font-weight: var(--font-weight-semibold);
  color: var(--text);
  margin: 0;
}
.map-card-body {
  padding: 12px;
}

/* ===== Responsive ===== */

/* Tablet — 中等屏幕 */
@media (max-width: 1024px) {
  .main-content { padding: 20px; }
  .admin-sidebar { width: 180px; min-width: 180px; }
  .kb-grid { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 16px; }
}

/* Mobile — 小屏幕 */
@media (max-width: 768px) {
  .main-content { padding: 16px; }

  /* Chat: sidebar 改为滑出抽屉 */
  .chat-container { flex-direction: row; height: calc(100vh - 60px - 32px); }
  .chat-sidebar {
    position: fixed; top: 60px; left: 0;
    z-index: 200; width: 280px; max-width: 80vw;
    height: calc(100vh - 60px);
    transform: translateX(-100%);
    transition: transform 0.3s ease;
    box-shadow: var(--shadow-lg);
    max-height: none;
  }
  .chat-sidebar.open { transform: translateX(0); }
  .chat-sidebar-overlay {
    /* 不能加 !important：chat.ejs 打开抽屉时用内联 style 设为 block */
    display: none;
    position: fixed; top: 60px; left: 0; right: 0; bottom: 0;
    background: rgba(0,0,0,0.4);
    z-index: 199;
  }
  .chat-topbar { padding: 8px 14px; gap: 8px; justify-content: flex-start; }
  .chat-topbar h3 { font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
  .chat-topbar-toggle { display: inline-flex !important; flex-shrink: 0; }
  .chat-messages { padding: 16px; }
  .msg-content { max-width: 90%; }

  .admin-container { flex-direction: column; }
  .admin-sidebar {
    position: static;
    width: 100%; min-width: 0;
    max-height: none;
    height: auto;
    overflow: visible;
    display: flex; flex-wrap: wrap; gap: 4px;
  }
  .admin-sidebar h3 { width: 100%; margin-bottom: 8px; }
  .admin-content { padding: 16px; width: 100%; }

  .kb-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
  .kb-card { padding: 16px 14px 14px; }
  .kb-card-icon { width: 36px; height: 36px; border-radius: 9px; }

  .stats-grid { grid-template-columns: repeat(2, 1fr); }
  .navbar-glass { padding: 0 12px; }
  .nav-right .nav-link .nav-btn-icon { display: none; }
  .navbar-glass .nav-brand-text { display: none; }
  .chat-input-area { padding: 0 12px 10px; }
  .viewer-container { height: calc(100vh - 60px); }
  .admin-sidebar .admin-nav-item { padding: 8px 12px; font-size: 13px; }
}

/* Extra small — 手机竖屏 */
@media (max-width: 480px) {
  .kb-grid { grid-template-columns: 1fr; }
  .kb-card { padding: 16px; }
  .kb-card-icon { width: 36px; height: 36px; border-radius: 9px; }
  .kb-card-info h3 { font-size: 15px; }
  .kb-card-desc { font-size: 12px; }
  .kb-section { margin-bottom: 20px; }
  .kb-section-header { margin-bottom: 10px; }
  .kb-section-header h3 { font-size: 15px; }
  .kb-section-divider { margin: 0 0 16px 0; }
  .kb-section-empty { padding: 16px 0; font-size: 13px; }
  .main-content { padding: 12px; }
  .chat-topbar { padding: 6px 10px; gap: 6px; justify-content: flex-start; }
  .chat-topbar h3 { font-size: 13px; }
  .chat-input-area { padding: 6px 10px 10px; }
  .chat-messages { padding: 12px; }
  .msg-content { max-width: 95%; padding: 10px 14px; font-size: 13px; }
}

/* Small mobile */
@media (max-width: 640px) {
  .stats-grid { grid-template-columns: 1fr; }
  .filter-form { flex-direction: column; align-items: stretch; }
  .filter-input { width: 100%; }
  .nav-right { gap: 4px; }
}

/* 数据表格横向滚动 */
.data-table-wrapper {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* ===== KB Stats Table ===== */
.kb-stats-table-wrap { overflow-x: auto; margin-top: 16px; }
.kb-stats-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.kb-stats-table th { text-align: left; padding: 12px 10px; font-weight: 600; color: var(--text-secondary); border-bottom: 2px solid var(--border); white-space: nowrap; }
.kb-stats-table td { padding: 14px 10px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.kb-stats-table tbody tr:hover { background: var(--surface-hover); }
.kb-stats-table tbody tr:last-child td { border-bottom: none; }
.kb-stats-table .kb-inactive { opacity: 0.55; }
.kb-stats-table .num-col { text-align: center; width: 70px; }
.kb-stats-table .action-col { text-align: center; width: 100px; }
.kb-stats-table .kb-name-cell { display: flex; align-items: center; gap: 10px; }
.kb-stats-icon { width: 28px; height: 28px; border-radius: 8px; object-fit: cover; flex-shrink: 0; }
.kb-stats-icon-placeholder { display: inline-flex; align-items: center; justify-content: center; background: var(--primary-light); color: var(--primary); font-weight: 700; font-size: 13px; }
.kb-stats-name { font-weight: 500; color: var(--text); }

/* ===== Version Badge ===== */
.version-badge {
  position: fixed;
  right: 16px;
  bottom: 10px;
  font-size: 11px;
  color: var(--text-muted);
  background: var(--surface);
  padding: 2px 10px;
  border-radius: 10px;
  border: 1px solid var(--border);
  opacity: 0.6;
  z-index: 50;
  user-select: none;
  pointer-events: none;
  font-family: var(--font-mono);
  letter-spacing: 0.3px;
  line-height: 1.6;
}

/* 卡片游客权限角标（V1.1.0 卡片分级访问） */
.kb-card-lock {
  position: absolute;
  top: 10px; right: 10px;
  width: 24px; height: 24px;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px;
  border-radius: 50%;
  background: rgba(125, 125, 125, 0.22);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 2;
}

/* viewer 页：卡片标题居中显示在顶部导航栏（V1.1.2） */
.nav-center-title {
  position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  max-width: min(52%, 520px);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 15px; font-weight: 600; color: var(--text);
  pointer-events: none;
}
@media (max-width: 640px) {
  .nav-center-title { max-width: 42%; font-size: 13px; }
}

/* ===== 表单分组与统一控件（设置页 UI 规范 V1.0.9） ===== */
/* 功能分组：组间大留白，组内紧凑 */
.form-section { margin-top: 28px; }
.form-section:first-child { margin-top: 0; }
.form-section > .form-group:first-child { margin-top: 14px; }
.form-section-title {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 700; color: var(--text);
  padding-bottom: 8px; border-bottom: 1px solid var(--border);
}
.form-section-title::before {
  content: ""; width: 3px; height: 14px;
  border-radius: 2px; background: var(--primary);
}
/* 单选/复选行：统一内联排布 */
.check-row, .radio-row {
  display: flex; align-items: center; gap: 6px;
  cursor: pointer; font-size: 14px; color: var(--text);
  padding: 4px 0;
}
.check-row input, .radio-row input {
  width: 15px; height: 15px;
  accent-color: var(--primary); cursor: pointer;
}
/* 字段级错误提示：输入框下方预留固定空间 */
.field-error {
  display: none;
  font-size: 12px; color: var(--danger);
  margin-top: 5px; min-height: 16px; line-height: 16px;
}
.field-error.visible { display: block; }
.form-group.has-error .form-input { border-color: var(--danger); }

/* ===== Skill 分享页（前台 /skills，公开）===== */
.skills-page { max-width: 1200px; margin: 0 auto; }
.skills-hero {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap; margin-bottom: 18px;
}
.skills-hero-main { display: flex; gap: 14px; align-items: flex-start; }
.skills-hero-icon {
  width: 48px; height: 48px; border-radius: 14px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 24px; line-height: 1;
  background: linear-gradient(135deg, var(--primary), var(--brand-accent-2));
  box-shadow: 0 6px 18px var(--primary-glow);
}
.skills-hero-text h1 {
  font-size: 23px; font-weight: var(--font-weight-semibold);
  color: var(--text); letter-spacing: 0.3px;
}
.skills-hero-text p {
  margin-top: 6px; font-size: 13px; line-height: 1.7;
  color: var(--text-secondary); max-width: 640px;
}
.skills-hero-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.skills-stats { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 20px; }
.skills-stat {
  display: flex; align-items: baseline; gap: 8px;
  padding: 9px 14px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--surface);
}
.skills-stat-num { font-size: 19px; font-weight: 700; color: var(--text); line-height: 1; }
.skills-stat-label { font-size: 12px; color: var(--text-muted); }

.skills-toolbar { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; flex-wrap: wrap; }
.skills-search { max-width: 320px; }
.skills-count { font-size: 12px; color: var(--text-muted); }

.skills-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 16px;
}
.skill-card {
  display: flex; flex-direction: column;
  padding: 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  transition: transform var(--transition), box-shadow var(--transition), border-color var(--transition);
}
.skill-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
  border-color: var(--accent-blue);
}
.skill-card-head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 12px; }
.skill-card-icon {
  width: 40px; height: 40px; border-radius: 10px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 20px; line-height: 1;
  background: var(--primary-light, #e6eff7);
}
.skill-card-title { flex: 1; min-width: 0; }
.skill-card-title h3 {
  font-size: 15.5px; font-weight: var(--font-weight-semibold); color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.skill-card-id {
  display: inline-block; margin-top: 3px;
  font-family: var(--font-mono); font-size: 11.5px; color: var(--text-muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}
.skill-ver-pill {
  flex-shrink: 0; padding: 3px 9px; border-radius: 20px;
  background: var(--primary-light, #e6eff7); color: var(--primary);
  font-size: 11.5px; font-weight: 600; line-height: 1.5; white-space: nowrap;
}
.skill-card-desc {
  font-size: 12.5px; line-height: 1.65; color: var(--text-secondary);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden; word-break: break-word;
}
.skill-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.skill-tag {
  padding: 2px 8px; border-radius: 6px;
  background: var(--gray-100, #f3f4f6); color: var(--text-secondary);
  font-size: 11px; line-height: 1.6;
}
.skill-card-meta {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  margin-top: 14px; font-size: 11.5px; color: var(--text-muted);
}
.skill-card-meta .kb-upd-dot { width: 6px; height: 6px; margin-right: 4px; box-shadow: none; vertical-align: middle; }
.skill-card-actions { display: flex; gap: 8px; margin-top: 14px; }
.skill-card-actions .btn { flex: 1; text-align: center; justify-content: center; }
/* 下载按钮稍宽，避免「下载 v1.0.1」被挤压换行 */
.skill-card-actions .btn-dl { flex: 1.45; white-space: nowrap; }

/* ===== Skill 详情弹窗（分享页卡片「详情」） ===== */
.skill-detail-head { display: flex; align-items: center; gap: 12px; }
.skill-detail-icon {
  width: 44px; height: 44px; border-radius: 12px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; line-height: 1;
  background: linear-gradient(135deg, var(--primary), var(--brand-accent-2));
  box-shadow: 0 6px 18px var(--primary-glow);
}
.skill-detail-title { flex: 1; min-width: 0; }
.skill-detail-title h3 { font-size: 16px; font-weight: var(--font-weight-semibold); color: var(--text); word-break: break-word; }
.skill-detail-title code {
  display: inline-block; margin-top: 3px;
  font-family: var(--font-mono); font-size: 11.5px; color: var(--text-muted);
  word-break: break-all;
}
.skill-detail-meta {
  margin-top: 16px; border: 1px solid var(--border); border-radius: 10px; overflow: hidden;
}
.skill-detail-meta-row {
  display: grid; grid-template-columns: 96px 1fr; gap: 10px;
  padding: 8px 14px; font-size: 12.5px; color: var(--text-secondary);
  border-bottom: 1px solid var(--border);
}
.skill-detail-meta-row:last-child { border-bottom: none; }
.skill-detail-meta-row strong { font-weight: 500; color: var(--text); word-break: break-word; }
.skill-detail-label {
  margin: 18px 0 8px; font-size: 12px; font-weight: 600;
  color: var(--text-muted); letter-spacing: 0.4px;
}
.skill-detail-desc {
  padding: 14px 16px; font-size: 13px; line-height: 1.85; color: var(--text-secondary);
  background: var(--gray-100, #f7f8fa); border: 1px solid var(--border); border-radius: 10px;
  white-space: pre-wrap; word-break: break-word;
}
.skill-detail-sha { margin-top: 16px; }
.skill-detail-sha code {
  display: block; margin-top: 4px;
  font-family: var(--font-mono); font-size: 11.5px; line-height: 1.7;
  color: var(--text-muted); word-break: break-all;
}

.skills-empty { text-align: center; padding: 64px 20px; }
.skills-empty-icon { font-size: 42px; opacity: 0.35; margin-bottom: 12px; }
.skills-empty h3 { font-size: 16px; font-weight: 600; color: var(--text); margin-bottom: 6px; }
.skills-empty p { font-size: 13px; color: var(--text-muted); }

@media (max-width: 640px) {
  .skills-grid { grid-template-columns: 1fr; }
  .skills-search { max-width: none; flex: 1; }
  .skills-hero-actions { width: 100%; }
  .skills-hero-actions .btn { flex: 1; text-align: center; justify-content: center; }
  .skills-hero-icon { width: 40px; height: 40px; font-size: 20px; border-radius: 12px; }
  .skills-hero-text h1 { font-size: 20px; }
}

/* 窄屏：三个按钮换行，下载独占一行 */
@media (max-width: 440px) {
  .skill-card-actions { flex-wrap: wrap; }
  .skill-card-actions .btn-dl { flex: 1 1 100%; }
  .skill-card-actions .btn { flex: 1 1 0; }
  .skill-detail-meta-row { grid-template-columns: 84px 1fr; }
}

/* ===== 独立视图模式（卡片「新标签页打开」带 ?bare=1） =====
   不渲染主站顶部导航，页面内容顶满窗口，高度按「无 60px 导航」重新计算 */
body.bare-mode .chat-container { height: calc(100vh - 48px); }
body.bare-mode .main-content:has(.viewer-container) .viewer-container { height: 100vh; }
body.bare-mode .main-content { animation: none; }
@media (max-width: 768px) {
  body.bare-mode .chat-container { height: calc(100vh - 32px); }
}

/* ===== 意见建议浮动按钮（前台右下角） ===== */
.fb-fab {
  position: fixed; right: 26px; bottom: 26px; z-index: 800;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 12px 18px; border: none; border-radius: 999px; cursor: pointer;
  background: var(--primary); color: #fff;
  font-size: 13.5px; font-weight: 600; font-family: inherit;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.16), 0 2px 6px rgba(0, 0, 0, 0.08);
  transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
}
.fb-fab:hover { transform: translateY(-2px); box-shadow: 0 14px 30px rgba(0, 0, 0, 0.2); }
.fb-fab:active { transform: translateY(0); }
.fb-fab-icon { font-size: 16px; line-height: 1; }
@media (max-width: 640px) {
  .fb-fab { right: 14px; bottom: 14px; padding: 12px; border-radius: 50%; }
  .fb-fab-text { display: none; }
}

/* 类型选择 chips */
.fb-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.fb-chip {
  padding: 7px 13px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--border); background: var(--surface);
  color: var(--text-secondary); font-size: 12.5px; font-family: inherit;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.fb-chip:hover { border-color: var(--primary); color: var(--primary); }
.fb-chip.active {
  background: var(--primary-light); border-color: var(--primary);
  color: var(--primary); font-weight: 600;
}
.fb-opt { font-weight: 400; color: var(--text-muted); font-size: 12px; }
.fb-req { color: var(--danger); }
.fb-counter { margin-top: 6px; text-align: right; font-size: 11.5px; color: var(--text-muted); }
.fb-error {
  margin-top: 12px; padding: 9px 12px; border-radius: 8px;
  background: var(--danger-light); border: 1px solid var(--danger);
  color: var(--danger-dark); font-size: 12.5px; line-height: 1.7;
}
.dark-theme .fb-error { background: rgba(220, 38, 38, 0.12); color: #fca5a5; border-color: rgba(220, 38, 38, 0.4); }

/* ===== 后台：意见建议详情弹窗 ===== */
.sugg-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.sugg-head-meta { margin-left: auto; font-size: 12px; color: var(--text-muted); }
.sugg-title { margin-top: 14px; font-size: 15px; font-weight: 600; color: var(--text); line-height: 1.6; word-break: break-word; }
.sugg-content {
  margin-top: 10px; padding: 14px 16px; border-radius: 10px;
  background: var(--gray-100); border: 1px solid var(--border);
  font-size: 13px; line-height: 1.85; color: var(--text-secondary);
  white-space: pre-wrap; word-break: break-word;
}
.sugg-kv { margin-top: 14px; border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
.sugg-kv-row {
  display: grid; grid-template-columns: 88px 1fr; gap: 10px;
  padding: 8px 14px; font-size: 12.5px; color: var(--text-secondary);
  border-bottom: 1px solid var(--border);
}
.sugg-kv-row:last-child { border-bottom: none; }
.sugg-kv-row strong { font-weight: 500; color: var(--text); word-break: break-all; }

/* ===== 意见建议列表：窄屏保持列宽，横向滚动 ===== */
.sugg-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.sugg-table { min-width: 920px; }
.sugg-table th:nth-child(4), .sugg-table td:nth-child(4) { min-width: 280px; }
.sugg-table td:nth-child(4) > div { word-break: break-word; }

/* ===== 注册页 ===== */
.reg-page { display: flex; align-items: flex-start; justify-content: center; padding: 24px 16px 40px; }
.reg-panel { width: 100%; max-width: 420px; padding: 30px 26px 22px; }
.reg-sub { margin: 4px 0 16px; font-size: 12.5px; text-align: center; color: var(--login-muted); }
.reg-form { gap: 12px; }
/* 验证码两行与登录页同构：右侧操作列固定宽度，两行输入框因此严格等宽 */
.reg-code-row, .reg-captcha-row { display: grid; grid-template-columns: minmax(0, 1fr) 108px; gap: 8px; align-items: stretch; }
.reg-code-row .glass-input, .reg-captcha-row .glass-input { width: 100%; min-width: 0; }
.reg-send { white-space: nowrap; padding: 0 6px; font-size: 13px; }
.reg-send[disabled] { opacity: 0.6; cursor: default; }
.reg-captcha-img {
  width: 108px; height: 46px; border-radius: 10px;
  cursor: pointer; border: 1px solid var(--border); background: var(--surface);
}
.reg-msg { min-height: 18px; font-size: 12.5px; line-height: 1.6; color: var(--text-secondary); }
.reg-msg.err { color: var(--danger, #dc2626); }
.reg-msg.ok { color: var(--success, #059669); }
.reg-foot { margin-top: 4px; font-size: 12.5px; text-align: center; color: var(--text-secondary); }
.reg-foot a { color: var(--primary); text-decoration: none; margin-left: 4px; }
.reg-foot a:hover { text-decoration: underline; }

/* ===== 登录页：两个 Tab（密码 / 验证码），微信降为页脚一行说明 ===== */
.login-tabs {
  display: flex; gap: 4px; padding: 4px;
  margin: 22px 0 16px;
  background: var(--login-tab-bg); border-radius: 10px;
}
.login-tab {
  flex: 1; min-height: 44px; padding: 0 8px;
  border: 0; background: transparent; border-radius: 8px;
  font-family: inherit; font-size: 13.5px; color: var(--login-muted);
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.login-tab:hover { color: var(--login-text); }
.login-tab.active {
  background: var(--login-tab-active-bg);
  color: var(--login-tab-active-color);
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.08);
}
/* 两栏叠在同一个网格单元里：容器高度恒等于较高的那一栏，切换 Tab 时卡片高度不变。
   隐藏栏用 visibility 而非 display，这样它仍参与高度计算，也不会被 Tab 键聚焦到。 */
.login-panes { display: grid; grid-template-columns: minmax(0, 1fr); min-width: 0; align-items: stretch; }
.login-pane {
  grid-area: 1 / 1; min-width: 0;
  display: flex; flex-direction: column;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.18s ease;
}
.login-pane.active { opacity: 1; visibility: visible; pointer-events: auto; }
/* 表单撑满内容区：首行贴顶、主按钮贴底，剩下的余量在内部均分。
   两个 Tab 的首行与登录按钮因此停在同一位置，切换时不上下跳；内容少的一栏也不会有大块空洞。
   注意别给主按钮加 margin-top:auto —— auto margin 会吃掉全部余量，justify-content 就失效了。 */
.login-pane > .login-form { flex: 1 1 auto; justify-content: space-between; }
.login-pane > .login-form > .btn:last-child { margin-top: 0; }
/* 验证码两行：右侧操作列固定 124px（与图形码图片同宽），两行左侧输入框严格等宽 */
.otp-row { display: grid; grid-template-columns: minmax(0, 1fr) 124px; gap: 8px; align-items: stretch; }
.otp-row .glass-input { width: 100%; min-width: 0; }
/* 图形验证码与同一行的输入框等高，避免一行里两个高度 */
.otp-row .reg-captcha-img { height: 46px; width: 124px; object-fit: contain; align-self: stretch; }
.otp-send {
  white-space: nowrap;
  min-height: 46px; padding: 0 6px; font-size: 13px; letter-spacing: 0;
  background: var(--login-input-bg); border: 1px solid var(--login-input-border); border-radius: 9px;
  color: var(--login-text); cursor: pointer;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.otp-send:hover { border-color: var(--primary); color: var(--primary); }
.otp-send[disabled] { opacity: 0.6; cursor: default; color: var(--login-muted); }
/* 预留一行提示的高度，出错/成功提示出现时不会把卡片顶高 */
.login-hint { font-size: 12px; line-height: 1.6; min-height: 20px; color: var(--login-muted); text-align: center; }
.login-hint.err { color: var(--danger, #dc2626); }
.login-hint.ok { color: var(--success, #059669); }
.dark-theme .login-hint.err { color: #fca5a5; }
.dark-theme .login-hint.ok { color: #6ee7b7; }
/* 图形码挪到验证码下方后，补一句填写顺序说明（个人中心排版比登录页紧，上边距收一点） */
.login-card .otp-order-hint { margin: -6px 0 10px; }

/* 页脚：找回密码 / 注册 / 微信扫码说明 */
.login-foot {
  margin-top: 20px; padding-top: 16px;
  border-top: 1px solid var(--login-divider);
  display: flex; flex-direction: column; gap: 8px;
}
.login-alt { font-size: 12.5px; line-height: 1.5; text-align: center; color: var(--login-muted); }
.login-alt-main { font-size: 13px; color: var(--login-text); }
.login-alt-main a { font-weight: 600; }
.login-alt-sub { font-size: 12px; color: var(--login-muted); }
.login-alt a { color: var(--primary); text-decoration: none; font-weight: 500; }
.login-alt a:hover { text-decoration: underline; }
/* 登录限流的事前告知（对应 routes/auth.js 的 loginAccountLimiter） */
.login-security { font-size: 12px; }
/* 密码字段下方：左侧大写锁定提示 / 右侧忘记密码。
   容器常驻 min-height，提示出现或消失都不会撑高卡片、不破坏两栏等高。 */
.login-aux-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; margin-top: -4px; min-height: 18px;
}
.login-aux { margin: 0 0 0 auto; font-size: 12px; line-height: 1.5; text-align: right; color: var(--login-muted); }
.pw-caps { font-size: 11.5px; line-height: 1.4; color: #b45309; font-weight: 500; white-space: nowrap; }
.pw-caps:empty { display: none; }
.dark-theme .pw-caps { color: #fbbf24; }

/* 宽屏：左右分栏，左侧承载品牌，右侧只做登录 */
@media (min-width: 900px) {
  .login-shell { flex-direction: row; align-items: stretch; }
  .login-brand {
    flex: 0 0 44%; max-width: 620px;
    padding: 56px 52px 44px;
    justify-content: space-between; gap: 28px;
  }
  .login-brand-logo { height: 34px; }
  .login-brand-body { margin-top: clamp(8px, 2.4vh, 22px); }
  .login-brand-title {
    display: block; margin-top: 4px;
    font-size: 27px; line-height: 1.38; font-weight: 600; letter-spacing: 0.01em;
    color: #fff;
  }
  .login-brand-desc {
    display: block; margin-top: 12px; max-width: 25em;
    font-size: 13.5px; line-height: 1.75; color: rgba(255, 255, 255, 0.78);
  }
  .login-brand-points {
    display: flex; flex-direction: column; gap: 10px;
    margin-top: 28px; list-style: none;
    font-size: 13px; line-height: 1.5; color: rgba(255, 255, 255, 0.80);
  }
  .login-brand-points li { display: flex; align-items: flex-start; gap: 9px; }
  .login-brand-points li::before {
    content: ''; flex: 0 0 auto;
    width: 6px; height: 6px; margin-top: 7px; border-radius: 2px;
    background: rgba(255, 255, 255, 0.55);
  }
  .login-brand-foot {
    display: block; font-size: 11.5px; letter-spacing: 0.14em; text-transform: uppercase;
    color: rgba(255, 255, 255, 0.74);
  }
  .login-panel { padding: 48px 32px; }
  .login-card, .glass-container { max-width: 404px; }
}
/* 品牌栏是深色，顶部主题按钮要跟着反色（窄屏时它正好压在品牌栏上） */
.dark-theme .login-tab.active { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.07), 0 1px 2px rgba(0, 0, 0, 0.35); }

@media (max-width: 899px) {
  /* 窄屏 h1 不占视觉空间，但保留在无障碍树里 */
  .login-brand-title {
    display: block; position: absolute;
    width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  }
  .login-theme-toggle {
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
    border-color: rgba(255, 255, 255, 0.28);
  }
  .login-theme-toggle:hover { border-color: rgba(255, 255, 255, 0.6); }
}

/* 矮视口（横屏手机 / 被拖矮的桌面窗口）：收紧纵向留白，尽量让按钮留在首屏 */
@media (max-height: 620px) {
  .login-brand { padding-top: 14px; padding-bottom: 14px; }
  .login-card, .glass-container { padding: 22px 22px 16px; }
  .login-card-title { font-size: 18px; }
  .login-tabs { margin: 14px 0 12px; }
  .login-form { gap: 10px; }
  .login-foot { margin-top: 12px; padding-top: 10px; gap: 6px; }
}

@media (max-width: 520px) {
  .reg-panel { padding: 24px 18px 20px; }
  /* 图形码宽度不再在此缩小：验证码行已改成「左侧输入框 + 固定宽操作列」的网格，
     单缩图片会让它与同列的按钮宽度对不上、只剩一块空白。 */
  .login-brand { padding: 16px; }
  .login-brand-logo { height: 24px; }
  .login-brand-name { font-size: 12px; padding-left: 9px; letter-spacing: 0.06em; }
  .login-panel { padding: 18px 14px 32px; }
  .login-card, .glass-container { padding: 24px 18px 18px; border-radius: 12px; }
  .login-tab { font-size: 13px; }
}

/* 极矮视口（横屏手机）：再省掉副标题，尽量少滚动 */
@media (max-height: 480px) {
  .login-card-sub { display: none; }
  .login-brand-title { font-size: 22px; }
  .login-brand-desc { display: none; }
  .login-brand-points { display: none; }
}

/* 尊重系统「减少动态效果」：关掉所有动画与过渡 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ===== 后台邀请码：窄屏保持列宽，横向滚动 ===== */
.invite-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.invite-table { min-width: 1120px; }
.invite-table td:nth-child(4) { max-width: 320px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ===== P4：找回密码 / 个人中心 / 改密三通道 ===== */
.forgot-tabs { margin: 16px 0 14px; }
.forgot-card { max-width: 420px; }
.forgot-form { gap: 12px; }
.forgot-form .login-hint { min-height: 20px; text-align: left; }
.login-notice { margin-top: 14px; padding: 10px 12px; border-radius: 9px; font-size: 12.5px; line-height: 1.5; }

.profile-card {
  background: var(--surface, #fff);
  border: 1px solid var(--border, #e2e8f0);
  border-radius: var(--radius, 12px);
  padding: 22px 24px;
  margin-bottom: 18px;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.04);
}
.profile-card-title { margin: 0 0 16px; font-size: 16px; font-weight: 600; color: var(--text); }
/* 账号信息卡内：一条一行、竖向排成一列，label 左 / 值右，虚线分隔 */
.profile-info-list { display: flex; flex-direction: column; }
.profile-info-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding: 9px 0; min-width: 0;
  border-bottom: 1px dashed var(--border);
}
.profile-info-row:last-child { border-bottom: 0; padding-bottom: 2px; }
.profile-info-row .profile-label { flex: none; }
.profile-info-row .profile-value { text-align: right; }
.profile-label { font-size: 12px; color: var(--text-secondary); }
.profile-value { font-size: 14px; color: var(--text); word-break: break-all; }
.profile-card-actions { display: flex; gap: 10px; margin-top: 20px; flex-wrap: wrap; }
.profile-hint { margin: 0 0 14px; font-size: 12.5px; line-height: 1.6; color: var(--text-secondary); }
.profile-reauth-ok { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; font-size: 13.5px; color: var(--success, #059669); }
.profile-reauth-form { margin-top: 14px; padding-top: 14px; border-top: 1px dashed var(--border); }
.profile-mini-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 14px; }
.profile-mini-tab {
  padding: 7px 14px; min-height: 36px; font-family: inherit; font-size: 13px;
  border: 1px solid var(--border); background: var(--bg); color: var(--text-secondary);
  border-radius: 8px; cursor: pointer;
}
.profile-mini-tab.active { background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600; }
.profile-field-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.profile-field-row .form-input { flex: 1 1 220px; }
.profile-otp-grid { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; align-items: center; margin-bottom: 10px; }
.profile-otp-grid .reg-captcha-img { width: 124px; height: 42px; object-fit: contain; }
.profile-otp-grid .btn { min-height: 42px; white-space: nowrap; }
.profile-msg { min-height: 18px; margin-top: 10px; font-size: 12.5px; line-height: 1.6; color: var(--text-secondary); }
.profile-msg.err { color: var(--danger, #dc2626); }
.profile-msg.ok { color: var(--success, #059669); }
.profile-bind-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 18px; }
.profile-bind-grid .profile-card { margin-bottom: 0; }
.profile-bound { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; flex-wrap: wrap; }
.profile-bound-value { font-size: 16px; font-weight: 600; color: var(--text); letter-spacing: 0.02em; }
.profile-badge { padding: 3px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 600; }
.profile-badge.ok { background: #d1fae5; color: #065f46; }
.profile-badge.warn { background: #fef3c7; color: #92400e; }
.dark-theme .profile-badge.ok { background: rgba(16, 185, 129, 0.18); color: #6ee7b7; }
.dark-theme .profile-badge.warn { background: rgba(245, 158, 11, 0.18); color: #fcd34d; }
.profile-card-muted { opacity: 0.78; }

.pw-method-tabs {
  display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 18px; padding: 4px;
  background: rgba(127, 127, 127, 0.07); border-radius: 10px;
}
.pw-method-tab {
  flex: 1 1 auto; min-height: 38px; padding: 0 12px; font-family: inherit; font-size: 13px;
  color: var(--text-secondary); background: transparent; border: 0; border-radius: 8px; cursor: pointer;
}
.pw-method-tab.active { background: var(--surface, #fff); color: var(--primary); font-weight: 600; box-shadow: 0 1px 3px rgba(15, 23, 42, 0.08); }
.pw-verify-tip { margin: 0 0 12px; font-size: 12.5px; color: var(--text-secondary); }
.pw-verify-tip strong { color: var(--text); }
.pw-verify-hint { margin: -6px 0 12px; font-size: 12px; color: var(--text-secondary); }
.pw-otp-row { display: flex; gap: 10px; align-items: stretch; margin-bottom: 12px; }
.pw-otp-row .form-input { flex: 1; min-width: 0; }
.pw-otp-row .reg-captcha-img { width: 124px; height: 44px; object-fit: contain; flex: 0 0 auto; }
.pw-otp-row .btn { flex: 0 0 auto; white-space: nowrap; }

@media (max-width: 520px) {
  .profile-card { padding: 18px 16px; }
  .profile-otp-grid .reg-captcha-img { width: 108px; }
  .forgot-card { padding: 24px 18px 18px; }
}
/* ===== App theme aligned with login page (2026-11-03) =====
   登录后全站与登录页共用一套「克制企业风」：藏蓝主色、实色底、
   极淡静态网格、无大面积渐变 / 无位移动效。
   例外：主页面知识卡片自 2026-11-04 起改为半透明磨砂玻璃（见第 5 节），
   气泡感的来源是 .dash-ambient 的冷色柔光，其余页面不铺。
   本段为覆盖段，放在文件末尾；删除本段即可回到旧主题。
   ============================================================ */

/* --- 1. 设计变量：浅色与登录页右侧表单区同源 --- */
html {
  --app-bg: #f4f6fa;
  --app-grid: rgba(0, 66, 128, 0.045);
  --bg: #f4f6fa;
  --surface: #ffffff;
  --surface-hover: #eef2f8;
  --border: #dbe3ef;
  --text: #1b2333;
  --text-secondary: #4d5a6e;
  --text-muted: #626d7f;
  --primary: #004280;
  --primary-hover: #003263;
  --primary-light: #eaf1f9;
  --primary-glow: rgba(0, 66, 128, 0.12);
  --brand-gradient: #004280;
  --brand-accent-2: #0a508f;
  --btn-glow: rgba(0, 66, 128, 0.18);
  --radius-lg: 12px;
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, 0.05);
  --shadow-md: 0 4px 14px rgba(16, 24, 40, 0.09);
  --shadow-lg: 0 12px 32px rgba(16, 24, 40, 0.12);
}

/* 深色：同一套藏蓝按底色提亮，不再切到靛紫 */
html.dark-theme {
  --app-bg: #0d1017;
  --app-grid: rgba(255, 255, 255, 0.028);
  --bg: #0d1017;
  --surface: #14171f;
  --surface-hover: #1b202a;
  --border: #262b36;
  --text: #eef1f6;
  --text-secondary: #9aa4b6;
  --text-muted: #77808f;
  --gray-50: #14171f;
  --gray-100: #1b202a;
  --gray-200: #262b36;
  --gray-300: #333947;
  --gray-500: #77808f;
  --gray-700: #9aa4b6;
  --gray-900: #eef1f6;
  --primary: #7fa9d6;
  --primary-hover: #9dc0e2;
  --primary-light: rgba(127, 169, 214, 0.15);
  --primary-glow: rgba(127, 169, 214, 0.18);
  --brand-gradient: #2f6aa8;
  --brand-accent-2: #3f80c0;
  --btn-glow: rgba(127, 169, 214, 0.18);
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.35);
  --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.40);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.50);
}

/* --- 2. 背景：实色 + 极淡静态网格，去掉光晕渐变 --- */
html:not(.dark-theme) body:not(.login-page),
html.dark-theme body:not(.login-page) {
  background-color: var(--app-bg);
  background-image: none;
}
body:not(.login-page)::before {
  background-image:
    linear-gradient(to right, var(--app-grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--app-grid) 1px, transparent 1px);
  background-size: 34px 34px;
  opacity: 1;
}

/* --- 3. 顶栏：与登录页左侧品牌区同款藏蓝 + 静态网格 --- */
.navbar-glass {
  background: var(--login-brand-bg, #004280);
  border-bottom: 1px solid rgba(0, 32, 64, 0.35);
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
.navbar-glass::before {
  content: '';
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(to right, var(--login-grid-line, rgba(255,255,255,0.07)) 1px, transparent 1px),
    linear-gradient(to bottom, var(--login-grid-line, rgba(255,255,255,0.07)) 1px, transparent 1px);
  background-size: 34px 34px;
}
html.dark-theme .navbar-glass {
  background: var(--login-brand-bg, #0f2036);
  border-bottom-color: #1b3550;
  box-shadow: none;
}
/* 只提升左右两块，不能通配 > *：会破坏 .nav-center-title 的 absolute 居中，
   也不能给 navbar 加 overflow:hidden：会裁掉用户下拉菜单 */
.navbar-glass > .nav-left,
.navbar-glass > .nav-right { position: relative; z-index: 1; }
.navbar-glass > .nav-center-title { position: absolute; z-index: 1; }
.navbar-glass .nav-brand {
  display: inline-flex; align-items: center; gap: 12px;
  font-size: 15px; font-weight: 600; letter-spacing: 0.12em;
  color: #fff; text-shadow: none;
}
.navbar-glass .nav-brand-logo { display: block; height: 22px; width: auto; max-width: 190px; }
.navbar-glass .nav-brand-sep { width: 1px; height: 18px; background: rgba(255,255,255,0.32); flex: none; }
.navbar-glass .nav-brand-text { color: rgba(255,255,255,0.92); }
html.dark-theme .nav-brand { text-shadow: none; }
.navbar-glass .nav-link,
.navbar-glass .nav-user-name,
.navbar-glass .nav-center-title { color: rgba(255,255,255,0.82); }
.navbar-glass .nav-link:hover,
.navbar-glass .user-dropdown-trigger:hover { background: rgba(255,255,255,0.12); color: #fff; }
.navbar-glass .nav-link.nav-active {
  background: rgba(255,255,255,0.16); color: #fff;
  box-shadow: inset 0 -2px 0 rgba(255,255,255,0.85);
}
/* button 元素自带 UA 默认背景（ButtonFace≈rgb(240,240,240)），网站浅/深主题
   切换影响不到它。顶栏按钮原先靠内联 background:none 压住，改成文字按钮后
   内联样式被移除，白块就露出来了 —— 这里显式声明浅/深两套配色。 */
.navbar-glass .nav-theme-toggle {
  background: rgba(255, 255, 255, 0.94);
  color: #1b2333;
  border: 1px solid #dbe3ef;
  border-radius: 8px;
  font-size: 12.5px; line-height: 1;
  padding: 7px 12px;
}
.navbar-glass .nav-theme-toggle:hover {
  background: #ffffff;
  color: #004280;
  border-color: #004280;
}
html.dark-theme .navbar-glass .nav-theme-toggle {
  background: rgba(20, 23, 31, 0.92);
  color: #eef1f6;
  border-color: #333947;
}
html.dark-theme .navbar-glass .nav-theme-toggle:hover {
  background: rgba(28, 33, 43, 0.96);
  color: #cfe1f4;
  border-color: #7fa9d6;
}

/* --- 4. 主内容：去掉位移入场动画 --- */
.main-content { animation: none; }
.kb-grid > *, .stats-grid > * { animation: none; }

/* --- 5. 知识卡片：半透明磨砂玻璃 + 亮边高光（透出背后网格与冷光），保留细边框、
   去掉光晕色块与位移动效。玻璃要成立的前提是背后有东西可透，见下方 .dash-ambient --- */
.kb-card {
  background: linear-gradient(160deg, rgba(255,255,255,0.62) 0%, rgba(255,255,255,0.30) 100%);
  border: 1px solid rgba(255,255,255,0.88);
  border-radius: 12px;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.95),
    inset 0 -1px 0 rgba(255,255,255,0.28),
    0 1px 2px rgba(16, 24, 40, 0.05),
    0 16px 32px -20px rgba(16, 24, 40, 0.32);
  backdrop-filter: blur(16px) saturate(150%);
  -webkit-backdrop-filter: blur(16px) saturate(150%);
  transition: border-color 0.18s ease, box-shadow 0.18s ease, background 0.18s ease,
              transform 0.22s cubic-bezier(0.2, 0.8, 0.3, 1);
}
html.dark-theme .kb-card {
  background: linear-gradient(160deg, rgba(34, 40, 53, 0.72) 0%, rgba(20, 23, 31, 0.50) 100%);
  border-color: rgba(255, 255, 255, 0.09);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    inset 0 -1px 0 rgba(255, 255, 255, 0.03),
    0 1px 2px rgba(0, 0, 0, 0.35),
    0 16px 32px -20px rgba(0, 0, 0, 0.60);
}
/* 悬停：边框流光（conic-gradient 环形描边，只在 hover 时运行，离开即暂停淡出） */
@property --kb-beam-angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
@keyframes kb-beam-spin { to { --kb-beam-angle: 360deg; } }
.kb-card::after { content: none; display: none; }
.kb-card::before {
  content: '';
  position: absolute; inset: 0;
  border-radius: inherit;
  padding: 2px;
  background: conic-gradient(from var(--kb-beam-angle),
      transparent 0deg 208deg,
      rgba(59, 130, 246, 0.50) 262deg,
      #3b82f6 288deg,
      #22d3ee 310deg,
      transparent 344deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0;
  transition: opacity 0.22s ease;
  animation: kb-beam-spin 1.9s linear infinite;
  animation-play-state: paused;
  pointer-events: none;
  z-index: 2;
}
.kb-card:hover::before,
.kb-card:focus-visible::before { opacity: 1; animation-play-state: running; }
.kb-card:hover,
.kb-card[data-type="chat"]:hover,
.kb-card[data-type="url"]:hover,
.kb-card[data-type="proxy"]:hover {
  transform: translateY(-2px);
  border-color: rgba(59, 130, 246, 0.62);
  background: linear-gradient(160deg, rgba(255,255,255,0.90) 0%, rgba(255,255,255,0.60) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,1),
    0 1px 2px rgba(16, 24, 40, 0.06),
    0 18px 34px -18px rgba(16, 24, 40, 0.26),
    0 0 26px -10px rgba(59, 130, 246, 0.55);
}
html.dark-theme .kb-card:hover,
html.dark-theme .kb-card[data-type="chat"]:hover,
html.dark-theme .kb-card[data-type="url"]:hover,
html.dark-theme .kb-card[data-type="proxy"]:hover {
  border-color: rgba(34, 211, 238, 0.50);
  background: linear-gradient(160deg, rgba(44, 51, 67, 0.86) 0%, rgba(26, 30, 40, 0.66) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.10),
    0 1px 2px rgba(0, 0, 0, 0.40),
    0 18px 34px -18px rgba(0, 0, 0, 0.62),
    0 0 30px -12px rgba(34, 211, 238, 0.65);
}
/* 悬停：图标放大（离开回缩，transform 不占布局不影响右侧徽标） */
.kb-card-icon {
  transition: transform 0.26s cubic-bezier(0.2, 0.8, 0.3, 1), box-shadow 0.26s ease;
}
.kb-card:hover .kb-card-icon,
.kb-card:focus-visible .kb-card-icon {
  transform: scale(1.12);
  box-shadow: 0 6px 16px -8px rgba(0, 66, 128, 0.45);
}
html.dark-theme .kb-card:hover .kb-card-icon,
html.dark-theme .kb-card:focus-visible .kb-card-icon {
  box-shadow: 0 6px 18px -8px rgba(34, 211, 238, 0.32);
}
@media (prefers-reduced-motion: reduce) {
  .kb-card::before { animation: none; }
  .kb-card:hover { transform: none; }
  .kb-card:hover .kb-card-icon { transform: none; }
}
.kb-card-icon-default { background: #004280; color: #fff; }
html.dark-theme .kb-card-icon-default { background: #2f6aa8; color: #fff; }
.kb-section-divider { background: var(--border); }
.kb-section-header::after { opacity: 0.5; }
.btn-primary:hover { box-shadow: 0 4px 12px rgba(0, 66, 128, 0.18); }

/* --- 6. 首页欢迎区（呼应登录页品牌区文案） --- */
.dash-head { margin: 2px 0 26px; }
.dash-head h1 {
  font-size: 22px; font-weight: 600; letter-spacing: 0.01em;
  color: var(--text);
}
.dash-head p { margin-top: 6px; font-size: 13px; line-height: 1.6; color: var(--text-muted); }
/* 2026-11-05 首页改版 A：原来这条 1px 细线横贯 1552px（标题宽度的 9 倍），像根多余的线；
   收成 40px 的短横线当标题的收尾，既保留分隔又不切分页面。 */
.dash-head-rule {
  width: 40px; height: 2px;
  border-radius: 1px;
  background: var(--primary);
  opacity: 0.38;
  margin-top: 18px;
}

/* --- 7. 深色聊天：气泡改藏蓝，与全站同色系 --- */
html.dark-theme .chat-container {
  --chat-bg: #14171f !important;
  --chat-sidebar-bg: #0d1017 !important;
  --chat-msg-user: #2f6aa8 !important;
}
/* --- 9. 登录页窄屏按钮：深色主题下不再保持半透明白块 --- */
/* 窄屏时按钮压在藏蓝品牌栏上，@media(max-width:899px) 原规则强制半透明白底白字；
   深色主题下让按钮回到深块亮字，与浅色明确区分。 */
@media (max-width: 899px) {
  html.dark-theme .login-theme-toggle {
    background: rgba(20, 23, 31, 0.86);
    color: #eef1f6;
    border-color: rgba(127, 169, 214, 0.42);
  }
  html.dark-theme .login-theme-toggle:hover { border-color: #7fa9d6; }
}

/* ===== End App theme aligned with login page ===== */

/* ===== Admin 用户详情弹窗 ===== */
.ud-grid {
  display: grid; grid-template-columns: 76px minmax(0, 1fr);
  gap: 10px 14px; font-size: 13px; line-height: 1.6;
}
.ud-label { color: var(--text-muted); }
.ud-value { color: var(--text); overflow-wrap: anywhere; }
.ud-note {
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--border);
  font-size: 12px; line-height: 1.6; color: var(--text-muted);
}
.user-muted { color: var(--text-muted); }
.user-verify-tag {
  display: inline-block; margin-left: 6px; padding: 0 5px;
  font-size: 11.5px; line-height: 1.6; border-radius: 4px; white-space: nowrap;
  color: var(--text-muted); border: 1px solid var(--border);
}
.user-verify-tag.is-ok {
  color: #0f766e; border-color: rgba(15, 118, 110, 0.35); background: rgba(15, 118, 110, 0.08);
}
.dark-theme .user-verify-tag.is-ok {
  color: #6ee7b7; border-color: rgba(110, 231, 183, 0.35); background: rgba(110, 231, 183, 0.1);
}
/* ===== End Admin 用户详情弹窗 ===== */

/* ===== 分组排序面板（后台 knowledge 配置页）===== */
.gb-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin-bottom: 16px;
}
.gb-head {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  margin-bottom: 10px;
}
.gb-title { margin: 0; font-size: 14px; font-weight: var(--font-weight-semibold); color: var(--text); }
.gb-hint { font-size: 12px; color: var(--text-muted); }
.gb-list {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: 6px;
}
.gb-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  transition: border-color var(--transition), background var(--transition);
}
.gb-item:hover { border-color: var(--accent-blue); }
.gb-index {
  flex: 0 0 auto; width: 20px; text-align: center;
  font-size: 12px; color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.gb-name {
  flex: 1 1 auto; min-width: 0;
  font-size: 13px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gb-name.is-free { color: var(--text-muted); }
.gb-count { flex: 0 0 auto; font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.gb-actions { flex: 0 0 auto; display: flex; gap: 4px; }
.gb-btn {
  width: 28px; height: 26px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; line-height: 1;
  color: var(--text); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  cursor: pointer; transition: background var(--transition), border-color var(--transition), color var(--transition);
}
.gb-btn:hover:not(:disabled) { background: var(--surface-hover); border-color: var(--accent-blue); color: var(--primary); }
.gb-btn:disabled { opacity: .35; cursor: not-allowed; }
.gb-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap; margin-top: 8px;
}
.gb-status { font-size: 12px; min-height: 16px; }
.gb-status.is-saving { color: var(--text-muted); }
.gb-status.is-ok { color: var(--success); }
.gb-status.is-err { color: var(--danger); }
.gb-tip { font-size: 11.5px; color: var(--text-muted); }
@media (max-width: 640px) {
  .gb-name { white-space: normal; }
  .gb-tip { display: none; }
}
/* ===== End 分组排序面板 ===== */

/* =====================================================================
   UI fixes 2026-11-03
   - 补齐视图中使用但此前未定义的类
   - 移动端导航 / 表格 / 触控目标
   - 深色主题下的徽标对比度
   ===================================================================== */

/* 视图中已在用、CSS 里缺失的类（邀请码页 / 个人中心 / 改密页） */
.form-control {
  width: 100%; padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius); font-size: 14px;
  outline: none; background: var(--bg); color: var(--text);
  transition: border-color 0.2s, box-shadow 0.2s;
}
.form-control:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-glow);
}
.form-hint {
  display: block; margin-top: 6px;
  font-size: 12px; color: var(--text-secondary); line-height: 1.5;
}
.page-header {
  margin: 0 0 20px; padding-bottom: 14px;
  border-bottom: 1px solid var(--border);
}
.page-header h1 { margin: 0 0 6px; font-size: 22px; }
.page-header p { margin: 0; color: var(--text-secondary); font-size: 14px; }
.badge-muted { background: var(--surface-hover); color: var(--text-secondary); }

/* 键盘焦点：全站统一可见的焦点环 */
:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.chat-sidebar-search input:focus-visible {
  outline: 2px solid var(--primary); outline-offset: 1px;
}
.chat-sidebar-search input:focus { border-color: var(--primary); }

/* 统计卡自适应：6 张卡不再挤在 4 列网格里留大洞 */
.stats-grid { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }

/* 数据表窄屏横向滚动，而不是把文字压成多行 */
.data-table-wrapper, .kb-stats-table-wrap, .log-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.data-table { min-width: 720px; }
.kb-stats-table { min-width: 600px; }

/* 触屏设备：删除按钮不再依赖 hover */
@media (hover: none) {
  .conv-delete-btn { opacity: 1; }
  .btn-sm { min-height: 34px; }
  .kb-card { min-height: 84px; }
}

/* 手机端导航：隐藏品牌字、收窄 logo、保证 44px 触控目标 */
@media (max-width: 640px) {
  .navbar-glass { padding: 0 10px; gap: 6px; }
  .navbar-glass .nav-brand-text,
  .navbar-glass .nav-brand-sep { display: none; }
  .navbar-glass .nav-brand-logo { width: 110px; height: auto; max-width: 38vw; }
  .navbar-glass .nav-brand { min-width: 0; }
  .navbar-glass .nav-right { gap: 2px; min-width: 0; }
  .navbar-glass .nav-link {
    padding: 8px 10px; min-height: 40px;
    display: inline-flex; align-items: center;
  }
  .navbar-glass .nav-user-name {
    max-width: 72px; overflow: hidden; text-overflow: ellipsis;
    white-space: nowrap; min-height: 40px;
    display: inline-flex; align-items: center;
  }
  .user-dropdown-menu { right: 0; left: auto; }
}

/* 后台移动端：侧栏改为横向滚动，不再用 flex-wrap 铺满首屏 */
@media (max-width: 768px) {
  .admin-sidebar {
    flex-wrap: nowrap; overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 6px;
  }
  .admin-sidebar h3 { display: none; }
  .admin-sidebar .admin-nav-item { flex: 0 0 auto; }
  .admin-content { padding: 14px 12px; }
  .page-header h1 { font-size: 19px; }
}

/* 分页在手机端换行，避免横向溢出 */
.pagination, .log-pagination { flex-wrap: wrap; gap: 6px; }

/* 深色主题：浅底徽标改成半透明底色，避免刺眼色块 */
.dark-theme .badge-admin,
.dark-theme .badge-url { background: rgba(245, 158, 11, 0.18); color: #fcd34d; }
.dark-theme .badge-user,
.dark-theme .badge-genieai { background: rgba(59, 130, 246, 0.18); color: #93c5fd; }
.dark-theme .badge-success,
.dark-theme .badge-html { background: rgba(16, 185, 129, 0.18); color: #6ee7b7; }
.dark-theme .badge-danger { background: rgba(239, 68, 68, 0.18); color: #fca5a5; }
.dark-theme .badge-proxy { background: rgba(139, 92, 246, 0.18); color: #c4b5fd; }
.dark-theme .badge-embed { background: rgba(6, 182, 212, 0.18); color: #67e8f9; }
.dark-theme .badge-dify { background: rgba(236, 72, 153, 0.18); color: #f9a8d4; }

/* 按钮化的用户菜单触发器：清掉 <button> 默认外观 */
button.user-dropdown-trigger {
  background: transparent; border: 0; padding: 6px 8px;
  font-family: inherit; line-height: 1.2;
}
/* 图表加载失败占位 */
.chart-error {
  display: flex; align-items: center; justify-content: center;
  height: 100%; min-height: 180px;
  color: var(--text-secondary); font-size: 14px;
}

/* ===== 文档库 /docs：搜索、结果列表、PDF.js 阅读器 ===== */
.docs-page {
  max-width: 1180px;
  margin: 0 auto;
  padding: 24px 20px 64px;
}

.docs-hero {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
}
.docs-hero-main { display: flex; align-items: center; gap: 14px; min-width: 0; }
.docs-hero-icon {
  width: 46px; height: 46px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; border-radius: 12px;
  background: var(--primary-light); color: var(--primary);
}
.docs-hero-text h1 { font-size: 22px; font-weight: 600; color: var(--text); margin-bottom: 4px; }
.docs-hero-text p { font-size: 13px; line-height: 1.7; color: var(--text-secondary); }
.docs-hero-text p strong { color: var(--primary); font-weight: 600; }
.docs-hero-actions { flex: 0 0 auto; }

.docs-searchbar {
  display: flex; gap: 10px;
  margin-bottom: 20px;
}
.docs-search-input {
  flex: 1;
  min-width: 0; /* input 默认有 ~20 字符的固有宽度，不禁掉会把窄屏整页撑出横向滚动 */
  height: 44px;
  padding: 0 16px; font-size: 14px;
  border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface); color: var(--text);
  transition: border-color var(--transition), box-shadow var(--transition);
}
.docs-search-input:focus {
  outline: none; border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-glow);
}
.docs-search-btn { height: 44px; padding: 0 26px; border-radius: 10px; }

.docs-layout {
  display: grid;
  grid-template-columns: 236px minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}
.docs-results { min-width: 0; }

/* 系列最多三十多个，比视口高；不加内滚动会顶住页面滚不动、下面的项也点不到 */
.docs-side {
  position: sticky;
  top: 78px;
  max-height: calc(100vh - 96px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-right: 4px;
}
.docs-side::-webkit-scrollbar { width: 6px; }
.docs-side::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
.docs-side-block { margin-bottom: 20px; }
.docs-side-block h3 {
  font-size: 12px; font-weight: 600; letter-spacing: .04em;
  color: var(--text-muted); text-transform: uppercase;
  margin-bottom: 8px; padding-left: 2px;
}
.docs-facet {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 7px 10px; margin-bottom: 2px;
  border-radius: 8px; font-size: 13px;
  color: var(--text-secondary); text-decoration: none;
  transition: background var(--transition), color var(--transition);
}
.docs-facet:hover { background: var(--surface-hover); color: var(--text); }
.docs-facet.is-active { background: var(--primary-light); color: var(--primary); font-weight: 500; }
.docs-facet-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.docs-facet-count { flex: 0 0 auto; font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.docs-facet.is-active .docs-facet-count { color: var(--primary); }

.docs-results-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 12px; flex-wrap: wrap;
}
.docs-results-info { font-size: 13px; color: var(--text-secondary); }
.docs-results-info strong { color: var(--text); font-weight: 600; }
.docs-active-filter {
  display: inline-block; margin-left: 8px; padding: 2px 8px;
  font-size: 12px; border-radius: 6px;
  background: var(--primary-light); color: var(--primary);
}
.docs-sort-select { height: 34px; padding: 0 10px; font-size: 13px; width: auto; }

.docs-list { list-style: none; display: flex; flex-direction: column; gap: 12px; }
.doc-item {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 16px 18px;
  transition: border-color var(--transition), box-shadow var(--transition);
}
.doc-item:hover { border-color: var(--primary); box-shadow: var(--shadow-md); }
.doc-item-head { margin-bottom: 8px; }
.doc-item-title {
  display: inline-flex; align-items: baseline; gap: 8px;
  font-size: 15px; font-weight: 500; color: var(--text); text-decoration: none;
  line-height: 1.5;
}
.doc-item-title:hover { color: var(--primary); }
.doc-item-icon {
  flex: 0 0 auto; font-size: 10px; font-weight: 700; letter-spacing: .04em;
  padding: 2px 5px; border-radius: 4px;
  background: var(--primary-light); color: var(--primary);
  transform: translateY(-1px);
}
.doc-item-name { word-break: break-word; }

.doc-item-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  font-size: 12px; color: var(--text-muted);
}
.doc-chip {
  padding: 2px 8px; border-radius: 6px;
  background: var(--gray-100); color: var(--text-secondary);
  font-size: 12px;
}
.doc-chip-tag { background: var(--primary-light); color: var(--primary); }
.doc-chip-warn { background: rgba(186, 117, 23, .12); color: #8a5a10; }
html.dark-theme .doc-chip-warn { background: rgba(250, 199, 117, .16); color: #f0c274; }

.doc-item-snippet {
  margin-top: 10px; font-size: 13px; line-height: 1.75;
  color: var(--text-secondary);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.doc-item-snippet mark {
  background: #ffe9a8; color: inherit;
  padding: 0 2px; border-radius: 3px;
}
html.dark-theme .doc-item-snippet mark { background: rgba(255, 214, 102, .28); color: #ffeab8; }

.doc-item-actions { display: flex; gap: 8px; margin-top: 12px; }

.docs-empty { text-align: center; padding: 64px 20px; }
.docs-empty-icon { font-size: 34px; margin-bottom: 10px; }
.docs-empty h3 { font-size: 16px; font-weight: 500; color: var(--text); margin-bottom: 6px; }
.docs-empty p { font-size: 13px; color: var(--text-muted); margin-bottom: 16px; }

.docs-pager { display: flex; align-items: center; gap: 6px; margin-top: 20px; flex-wrap: wrap; }
.docs-page-btn {
  min-width: 34px; padding: 6px 12px; text-align: center;
  font-size: 13px; border-radius: 8px;
  border: 1px solid var(--border); background: var(--surface);
  color: var(--text-secondary); text-decoration: none;
}
.docs-page-btn:hover { border-color: var(--primary); color: var(--primary); }
.docs-page-btn.is-current { background: var(--primary); border-color: var(--primary); color: #fff; }
.docs-page-btn.is-disabled { opacity: .45; }
.docs-page-info { margin-left: 6px; font-size: 12px; color: var(--text-muted); }

/* ——— PDF 阅读器 ——— */
.pdfv-page {
  display: flex; flex-direction: column;
  /* 顶栏 60px + .main-content 上下各 24px */
  height: calc(100vh - 60px - 48px);
  height: calc(100dvh - 60px - 48px);
}
.pdfv-bar {
  display: flex; align-items: center; gap: 14px;
  padding: 8px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
}
.pdfv-back {
  font-size: 13px; color: var(--text-secondary); text-decoration: none;
  padding: 5px 10px; border-radius: 8px; flex: 0 0 auto;
}
.pdfv-back:hover { background: var(--surface-hover); color: var(--primary); }
.pdfv-title {
  flex: 1 1 220px; min-width: 0;
  font-size: 14px; font-weight: 500; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pdfv-tools { display: flex; align-items: center; gap: 4px; flex: 0 0 auto; }
.pdfv-btn {
  min-width: 30px; height: 30px; padding: 0 8px;
  border: 1px solid var(--border); border-radius: 7px;
  background: var(--surface); color: var(--text-secondary);
  font-size: 13px; cursor: pointer; line-height: 1;
}
.pdfv-btn:hover { border-color: var(--primary); color: var(--primary); }
.pdfv-btn-text { padding: 0 10px; }
.pdfv-pageno {
  width: 46px; height: 30px; text-align: center;
  border: 1px solid var(--border); border-radius: 7px;
  background: var(--surface); color: var(--text); font-size: 13px;
}
.pdfv-total, .pdfv-zoom { font-size: 12px; color: var(--text-muted); min-width: 40px; text-align: center; }
.pdfv-sep { width: 1px; height: 20px; background: var(--border); margin: 0 6px; }

.pdfv-meta {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 16px; font-size: 12px; color: var(--text-muted);
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.pdfv-q { color: var(--primary); }

.pdfv-stage {
  position: relative;
  flex: 1 1 auto; overflow: auto;
  background: var(--gray-100);
  padding: 20px 0 40px;
}
html.dark-theme .pdfv-stage { background: #0a0d12; }
.pdfv-pages { display: flex; flex-direction: column; align-items: center; gap: 18px; }
/* 单页纸张：与阅读器外壳 .pdfv-page 区分，避免同名类导致外壳也吃到纸张样式 */
.pdfv-sheet { background: #fff; box-shadow: 0 2px 12px rgba(0,0,0,.14); overflow: hidden; }
.pdfv-sheet canvas { display: block; }

.pdfv-hint {
  position: absolute; top: 40%; left: 50%; transform: translate(-50%, -50%);
  padding: 12px 20px; border-radius: 10px;
  background: var(--surface); color: var(--text-secondary);
  font-size: 13px; box-shadow: var(--shadow-md);
  max-width: 80%; text-align: center; line-height: 1.7;
}
.pdfv-hint.is-error { color: var(--danger); }

@media (max-width: 900px) {
  .docs-layout { grid-template-columns: 1fr; }
  .docs-side { position: static; display: flex; gap: 16px; overflow-x: auto; padding-bottom: 4px; }
  .docs-side-block { margin-bottom: 0; flex: 0 0 auto; min-width: 170px; max-height: 210px; overflow-y: auto; }
  .docs-page { padding: 16px 14px 48px; }
  .docs-hero { flex-direction: column; }
  .pdfv-page { height: calc(100dvh - 60px - 32px); }
  .pdfv-bar { gap: 8px; padding: 6px 10px; }
  .pdfv-title { order: 3; flex-basis: 100%; }
  .pdfv-btn-text { display: none; }
}

/* ===== 个人中心：绑定 / 换绑区（未通过身份复核时整块置灰） ===== */
.profile-lock {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap; margin: 0 0 12px; padding: 9px 12px;
  border: 1px dashed var(--border); border-radius: 8px;
  background: rgba(127, 127, 127, 0.08);
  font-size: 12.5px; line-height: 1.6; color: var(--text-secondary);
}
/* fieldset 默认带边框和内边距，这里清零，只借它的 disabled 能力 */
.bind-fields { border: 0; margin: 0; padding: 0; min-width: 0; }
.bind-fields[disabled] { opacity: 0.5; }
.bind-fields[disabled] .form-input,
.bind-fields[disabled] .btn { cursor: not-allowed; }
/* img 不受 fieldset disabled 约束，单独挡掉点击并去色 */
.bind-fields[disabled] .reg-captcha-img { pointer-events: none; filter: grayscale(1); }

/* ===== 基本资料表单（个人中心）===== */
.profile-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 14px 20px;
  margin-bottom: 14px;
}
.profile-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.profile-inline-field { display: flex; gap: 8px; align-items: center; }
.profile-inline-field .form-input { flex: 1 1 auto; min-width: 0; }
.profile-inline-field .btn { flex: none; min-height: 42px; white-space: nowrap; }
/* 只读字段（手机号）：压一档对比度，明确「这里不能直接改」 */
.profile-inline-field .form-input[readonly] {
  background: rgba(127, 127, 127, 0.08);
  color: var(--text-secondary);
  cursor: default;
}
.req-mark { color: var(--danger, #dc2626); font-weight: 600; }
.opt-mark {
  margin-left: 4px; padding: 0 5px; border-radius: 4px;
  font-size: 11px; font-weight: 500; color: var(--text-secondary);
  background: rgba(127, 127, 127, 0.14);
}
/* 图形码挪到验证码下方后，补一句填写顺序说明 */
.otp-order-hint { margin: -2px 0 12px; font-size: 12px; }

/* ===== 个人中心：顶部两卡并列 + 身份复核弹窗 ===== */
.profile-top-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 18px;
  align-items: stretch;
  margin-bottom: 18px;
}
.profile-top-grid .profile-card { margin-bottom: 0; }
.profile-card-stack { display: flex; flex-direction: column; }
/* 卡内内容少的一侧，操作按钮自动压到底部与另一卡对齐 */
.profile-card-stack .profile-card-actions { margin-top: auto; }
/* 卡片变窄后半宽，基本资料字段改回单列，避免输入框被挤到 120px */
.profile-top-grid .profile-form-grid { grid-template-columns: minmax(0, 1fr); margin-bottom: 12px; }

/* 复核状态条：常驻一行，复核动作在弹窗里完成 */
.profile-reauth-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; flex-wrap: wrap;
  margin-bottom: 18px; padding: 12px 16px;
  background: var(--surface, #fff);
  border: 1px solid var(--border);
  border-left: 3px solid var(--warning, #d97706);
  border-radius: var(--radius, 12px);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.04);
  font-size: 13.5px; line-height: 1.5; color: var(--text);
}
.profile-reauth-bar.is-ok { border-left-color: var(--success, #059669); }
.profile-reauth-bar-main { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; }
.profile-reauth-dot {
  flex: none; width: 8px; height: 8px; border-radius: 50%;
  background: var(--warning, #d97706);
}
.profile-reauth-bar.is-ok .profile-reauth-dot { background: var(--success, #059669); }
.profile-reauth-count {
  padding: 2px 8px; border-radius: 999px;
  font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums;
  color: var(--success, #059669); background: rgba(5, 150, 105, 0.12);
}

.profile-reauth-modal { max-width: 420px; width: 92vw; }
.profile-reauth-modal .modal-body { padding: 20px 24px 2px; }
.profile-reauth-modal .profile-mini-tabs { margin-bottom: 14px; }
.profile-reauth-modal .profile-msg { margin-top: 4px; }
body.modal-open { overflow: hidden; }

@media (max-width: 900px) {
  .profile-top-grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 520px) {
  .profile-reauth-bar { padding: 10px 12px; font-size: 13px; }
  .profile-reauth-bar .btn { width: 100%; }
  .profile-reauth-modal .modal-body { padding: 16px 16px 2px; }
  .profile-info-row { gap: 10px; }
}

/* ===== 登录页：图形码弹窗（点「获取验证码」时才出现，不占页面高度）===== */
.login-cap-modal { max-width: 384px; width: 92vw; }
.login-cap-modal .modal-body { padding: 18px 22px 20px; }
.login-cap-tip { margin: 0 0 14px; font-size: 13px; line-height: 1.6; color: var(--text-secondary); }
.login-cap-row { display: grid; grid-template-columns: minmax(0, 1fr) 124px; gap: 8px; align-items: stretch; }
.login-cap-row .form-input { width: 100%; min-width: 0; min-height: 46px; }
.login-cap-row .reg-captcha-img { width: 124px; height: 46px; object-fit: contain; }
.login-cap-msg { min-height: 20px; margin: 6px 0 0; font-size: 12px; line-height: 1.5; color: var(--danger, #dc2626); }
.login-cap-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }
.login-cap-actions .btn { min-width: 84px; }

@media (max-width: 420px) {
  .login-cap-modal .modal-body { padding: 16px 16px 18px; }
  .login-cap-row { grid-template-columns: minmax(0, 1fr) 104px; }
  .login-cap-row .reg-captcha-img { width: 104px; }
}

/* 图形码弹窗由公共脚本动态挂到 body 上：个人中心的身份复核窗自身也是 9999，
   这层要压在它上面，否则在复核窗里点「获取验证码」会看不见弹窗。 */
.kb-cap-overlay { z-index: 10050; }
/* 嵌套时下层遮罩调淡：两个 0.5 叠起来会黑成一片，看不出下面还有窗 */
body.kb-cap-open .modal-overlay:not(.kb-cap-overlay) { background: rgba(0, 0, 0, 0.16); }

/* ===== 验证码有效期倒计时（各页面共用，独占一行，不与提示行抢内容）===== */
.otp-expire {
  margin: -4px 0 10px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-secondary);
  /* 等宽数字，秒数跳动时不左右抖 */
  font-variant-numeric: tabular-nums;
}
.otp-expire:empty { display: none; }
.otp-expire.is-expired { color: var(--danger, #dc2626); }
/* 登录页表单间距更紧，上下各收一点 */
.login-page .otp-expire { margin: -6px 0 6px; }
.profile-card .otp-expire { margin: -2px 0 10px; }
/* 深色主题下 #dc2626 偏暗，跟其它错误提示一样提亮 */
.dark-theme .otp-expire.is-expired { color: #fca5a5; }

/* ===== 首页分组菜单：横向卡片 + 单开折叠（默认全部收起）=====
   结构：.kb-menu-hint → .kb-menu(按钮组) → .kb-expand(内含若干 .kb-panel)
   面板就地展开在菜单下方，同一时刻只开一个；折叠方式见下方「分组展开面板」段。
   禁用 JS 时由 dashboard.ejs 里的 <noscript> 把面板全部摊平。 */
.kb-menu {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 12px;
  margin: 0 0 4px;
  /* 左右不再留 8px：卡片左缘要和标题、面板对齐在同一条中轴上 */
  padding: 6px 0 14px;
}

/* 卡片式菜单（2026-11-05 由胶囊改版）：
   左侧 3px 主题色条 + 分组名 + 「N 个应用」，和下方玻璃卡同为圆角矩形，形状语言统一。
   选中态是「浅主色底 + 左色条变实色」，不再整块填深蓝，视觉重量比胶囊轻。
   2026-11-05 首页改版 A：改为等分撑满中轴那一列（5 个各约 213px），
   2026-11-06 中轴放宽到 1440 后各约 274px，字号同步加到 16px/600；
   不再按内容宽度自适应、也不横向滚动；分组少时靠 max-width 兜住，不会拉成一张巨型卡。 */
.kb-tab {
  position: relative;
  flex: 1 1 180px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  min-width: 0;
  /* 右侧留 34px 给「›」：提示这张卡片点开后有下一层 */
  padding: 12px 34px 13px 16px;
  border-radius: 12px;
  /* 强调色来自模板内联的 --kb-acc（研华品牌色板，按分组顺序循环）：
     淡底 / 选中底 / 深色版强调色都由 color-mix 现算，换一套配色不用再动 CSS。
     不支持 color-mix 的浏览器退回原来那套「白底 + 藏蓝左边」，布局不受影响。 */
  --kb-ink: var(--kb-acc, #004280);
  border: 1px solid rgba(0, 66, 128, 0.18);
  border-left: 4px solid var(--kb-acc, rgba(0, 106, 191, 0.55));
  background: rgba(255, 255, 255, 0.72);
  background: color-mix(in srgb, var(--kb-acc, #004280) 7%, rgba(255, 255, 255, 0.72));
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  color: var(--text-secondary);
  font-family: inherit;
  line-height: 1.25;
  white-space: nowrap;
  text-align: left;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.90), 0 1px 2px rgba(16, 24, 40, 0.05);
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease,
              box-shadow 0.18s ease, transform 0.18s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.kb-tab-name {
  max-width: 100%;
  /* 2026-11-06：14/500 → 17/600，分组名是这一屏的导航入口，之前和正文同重、压在彩色底上看不清 */
  font-size: 17px; font-weight: 600; letter-spacing: 0.01em; color: var(--text-primary);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kb-tab-sub { font-size: 13px; color: var(--text-muted); }

/* 右侧「›」：卡片是打开抽屉的入口，给一个次级箭头暗示还有下一层 */
.kb-tab-go {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 19px;
  line-height: 1;
  color: var(--kb-ink, var(--primary));
  opacity: 0.30;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.kb-tab:hover .kb-tab-go,
.kb-tab:focus-visible .kb-tab-go { opacity: 0.72; transform: translate(2px, -50%); }
.kb-tab.is-open .kb-tab-go { opacity: 0.9; transform: translateY(-50%) rotate(90deg); }

.kb-tab:hover {
  color: var(--kb-ink);
  border-color: rgba(0, 66, 128, 0.26);
  border-left-color: var(--kb-acc, rgba(0, 66, 128, 0.55));
  background: color-mix(in srgb, var(--kb-acc, #004280) 12%, rgba(255, 255, 255, 0.86));
  transform: translateY(-1px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.95), 0 8px 18px -12px rgba(16, 24, 40, 0.30);
}
.kb-tab:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.kb-tab.is-open {
  color: var(--kb-ink);
  border-color: color-mix(in srgb, var(--kb-acc, #004280) 34%, transparent);
  border-left-color: var(--kb-acc, var(--primary));
  background: rgba(0, 90, 170, 0.10);
  background: color-mix(in srgb, var(--kb-acc, #004280) 16%, rgba(255, 255, 255, 0.92));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.90), 0 10px 20px -16px rgba(0, 66, 128, 0.55);
}
.kb-tab.is-open .kb-tab-sub { color: var(--kb-ink); opacity: 0.9; }

/* 2026-11-05 首页改版 A：这行原来在菜单下方，12.5px 浅灰，是理解交互的唯一线索却像脚注；
   现在移到菜单上方，改成小节标题（「知识库分组 · 点击展开」），点开后被脚本改写成
   「已展开「X」· 再点一次收起」，位置正好是状态提示该在的地方。 */
.kb-menu-hint {
  margin: 2px 0 8px;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.4;
  color: var(--text-secondary);
}

/* ===== 分组展开面板（2026-11-05 五改：改回内联展开）=====
   浮层抽屉试了四版（右侧滑入 → 居中 → 从卡片长出 → iOS 冒烟），
   但它始终是「弹窗」：盖住页面、锁滚动、得按 ✕ 才回得去。
   这一版整个撤掉浮层，改成点菜单即在正下方长出一块面板 —— 和点开一个菜单一样。
   和最早那版的差别只在展开方式：
     · 高度用 grid-template-rows 0fr → 1fr 过渡：面板多高都不用预先量，
       也不会像 max-height 那样「撑到某个值之后空走」；
     · overflow:hidden 放在 .kb-panel-inner、间距放在 .kb-panel-body，
       收起时高度才能真正归零，卡片 hover 抬起的阴影也不会被裁掉；
     · 收起态是 visibility:hidden + 延迟 0.34s 生效，只压高度的话
       里面的链接仍然能被 Tab 到、被读屏念出来。 */
.kb-expand { display: block; }

.kb-panel {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  visibility: hidden;
  transition:
    grid-template-rows 0.34s cubic-bezier(0.2, 0.8, 0.3, 1),
    opacity 0.22s ease,
    visibility 0s linear 0.34s;
}
.kb-panel.is-open {
  grid-template-rows: 1fr;
  opacity: 1;
  visibility: visible;
  transition:
    grid-template-rows 0.34s cubic-bezier(0.2, 0.8, 0.3, 1),
    opacity 0.26s ease 0.05s,
    visibility 0s linear 0s;
}
.kb-panel-inner { min-height: 0; overflow: hidden; }
/* 上 2px 给卡片 hover 的浮起、下 22px 和下面的轮播拉开距离 */
.kb-panel-body { padding: 2px 0 22px; }
/* 中轴放宽到 1440 后，通用 220px 会把面板排成 6 列（每列只剩 223px，比原来 4 列还窄）。
   这里把列宽下限提到 245px：1440 下稳定 5 列（272px/列），1366 下 5 列（247px），
   卡片比改版前略宽，同时把多出来的 320px 横向空间用掉，而不是换成更多更小的卡。 */
.kb-panel-body .kb-grid { grid-template-columns: repeat(auto-fill, minmax(245px, 1fr)); }

@media (prefers-reduced-motion: reduce) {
  .kb-panel { transition: none; }
}

/* 深色主题：主色是浅蓝 #7fa9d6，选中态用「淡蓝底 + 左色条实色」，比整块浅蓝填充更稳 */
html.dark-theme .kb-tab {
  /* 深色底上品牌色会「沉」下去：强调色提亮一档、淡底按 20% 混进深灰 */
  --kb-ink: color-mix(in srgb, var(--kb-acc, #7fa9d6) 68%, #ffffff);
  border-color: rgba(255, 255, 255, 0.10);
  border-left-color: rgba(127, 169, 214, 0.62);
  border-left-color: color-mix(in srgb, var(--kb-acc, #7fa9d6) 62%, #ffffff);
  background: rgba(34, 40, 53, 0.62);
  background: color-mix(in srgb, var(--kb-acc, #7fa9d6) 16%, rgba(34, 40, 53, 0.62));
  color: #c2cad8;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 1px 2px rgba(0, 0, 0, 0.35);
}
html.dark-theme .kb-tab-sub { color: #8b94a6; }
html.dark-theme .kb-tab:hover {
  color: var(--kb-ink);
  border-color: rgba(127, 169, 214, 0.45);
  border-left-color: color-mix(in srgb, var(--kb-acc, #7fa9d6) 78%, #ffffff);
}
html.dark-theme .kb-tab:focus-visible { outline-color: #7fa9d6; }
html.dark-theme .kb-tab.is-open {
  color: var(--kb-ink);
  border-color: rgba(127, 169, 214, 0.55);
  border-left-color: color-mix(in srgb, var(--kb-acc, #7fa9d6) 82%, #ffffff);
  background: rgba(58, 96, 148, 0.34);
  background: color-mix(in srgb, var(--kb-acc, #7fa9d6) 30%, rgba(26, 31, 42, 0.92));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.10), 0 10px 22px -16px rgba(0, 0, 0, 0.60);
}
html.dark-theme .kb-tab.is-open .kb-tab-sub { color: var(--kb-ink); opacity: 0.92; }
html.dark-theme .kb-menu-hint { color: #8b94a6; }

@media (max-width: 600px) {
  /* 手机上一行放不下 3 个以上等分卡片，改回横向滑动（桌面端已改为等分撑满） */
  .kb-menu {
    flex-wrap: nowrap;
    gap: 8px;
    padding: 4px 8px 12px;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
    mask-image: linear-gradient(to right, transparent 0, #000 16px, #000 calc(100% - 16px), transparent 100%);
  }
  .kb-menu::-webkit-scrollbar { display: none; }
  .kb-tab { flex: 0 0 auto; min-width: 116px; max-width: none; padding: 8px 13px 9px 11px; }
  .kb-tab-name { font-size: 13px; }
  .kb-tab-sub { font-size: 11px; }
  .kb-menu-hint { margin-bottom: 8px; font-size: 12px; }
}
@media (prefers-reduced-motion: reduce) {
  /* 面板的过渡在「分组展开面板」那段里已经关过一次，这里只管菜单卡片 */
  .kb-tab { transition: none; }
  .kb-tab:hover { transform: none; }
  .kb-tab.is-open .kb-tab-go { transform: translateY(-50%) rotate(90deg); }
}

/* ===== 首页底部轮播（图片来自 public/img/carousel/）=====
   2026-11-05 二改：播放效果参考研华官网首页 hero（Swiper fade + 底部文案 tab +
   tab 内进度条 + 文案分层进场），但没引 Swiper —— 只有一组交叉淡入和一条进度条，
   手写比拖一个库进来更省，也更好和现有的 hover 暂停、键盘、触摸逻辑对接。
   为什么换成 fade：截图类素材左右平移会把相邻页面一起拽进来，视觉噪音大；
   交叉淡入任何时候只看得到一张，注意力集中。 */
.kb-carousel {
  /* 2026-11-06（V1.1.39）：取消「按视口高度反推宽度」的上限。
     原来 max-width 是 min(100%, calc((100vh - 330px) * 2.064))，为的是让 1366×768
     首屏装得下；代价是 861~1027px 高的窗口（1080p 屏去掉浏览器工具栏正好落这一段）
     轮播会被压到 1280 并居中，比分组菜单窄 160，左右各缩 80 —— 上下左边缘对不齐。
     现在一律撑满中轴、高度按 1600/775 走，首屏装不下就正常往下滚，不再裁图。 */
  width: 100%;
  max-width: 100%;
  margin: 14px auto 10px;
  outline: none;
}
.kbc-stage {
  position: relative;
  overflow: hidden;
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, 0.85);
  background: rgba(255, 255, 255, 0.50);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    0 1px 2px rgba(16, 24, 40, 0.05),
    0 20px 44px -26px rgba(16, 24, 40, 0.38);
  /* 01/04 裁掉顶部 51px 导航条后是 1600×742，其余是 1600×793/795。
     容器取中间值 1600/775，各图 object-fit: cover 均分上下裁剪，谁都不变形。 */
  aspect-ratio: 1600 / 775;
}
.kb-carousel:focus-visible .kbc-stage {
  box-shadow:
    0 0 0 3px rgba(0, 66, 128, 0.30),
    0 20px 44px -26px rgba(16, 24, 40, 0.38);
}

/* 轨道只当容器用，不再位移；五张图绝对定位叠在一起靠 opacity 交叉 */
.kbc-track { position: relative; height: 100%; }
.kbc-slide {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  /* 关掉的那张等淡出走完再隐藏，否则会出现「两张同时消失」的黑一下 */
  transition: opacity 0.7s ease, visibility 0s linear 0.7s;
}
.kbc-slide.is-on {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 0.7s ease, visibility 0s linear 0s;
}
.kbc-slide img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
  -webkit-user-select: none;
  user-select: none;
}

/* 文字可读底衬。截图满幅都是内容，没有天然留白，只能靠遮罩压出一块。
   只压「左下角那一块」，其余区域严格 0 覆盖：
     · 盒子不再是 inset:0，而是只占底部 38% 高的一条；
     · 横向渐变到 56% 就衰减为 0，纵向靠 mask 从底往上淡出；
     · 两层渐变的边界都落在透明处，所以没有可见的直角硬边。
   图片上半部分和右侧一个像素都不受影响。
   没用 filter: blur —— 全屏磨砂每帧重绘会把帧率打到个位数（抽屉那次踩过）。 */
.kbc-slide::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 38%;
  pointer-events: none;
  background-image:
    linear-gradient(to right,
      rgba(255, 255, 255, 0.96) 0%,
      rgba(255, 255, 255, 0.94) 26%,
      rgba(255, 255, 255, 0.84) 36%,
      rgba(255, 255, 255, 0.54) 45%,
      rgba(255, 255, 255, 0.18) 52%,
      rgba(255, 255, 255, 0) 60%),
    linear-gradient(to top,
      rgba(255, 255, 255, 0.70) 0px,
      rgba(255, 255, 255, 0.38) 40px,
      rgba(255, 255, 255, 0) 76px);
  background-repeat: no-repeat;
  background-size: 100% 100%, 100% 76px;
  background-position: left bottom, left bottom;
  -webkit-mask-image: linear-gradient(to top, #000 0 62%, transparent 100%);
  mask-image: linear-gradient(to top, #000 0 62%, transparent 100%);
}

/* 文字层：左下角。pointer-events: none —— 现在没有 CTA 按钮，
   别让它挡住图片上可能的点击；将来加按钮时改成 auto。 */
.kbc-copy {
  position: absolute;
  left: 26px;
  bottom: 84px;
  z-index: 2;
  width: min(46%, 430px);
  pointer-events: none;
}
.kbc-copy-title {
  margin: 0;
  font-size: 21px;
  line-height: 1.34;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: #0f2f55;
}
.kbc-copy-sub {
  margin: 7px 0 0;
  font-size: 12.5px;
  line-height: 1.62;
  color: rgba(15, 47, 85, 0.74);
}

/* 文案进场：图和字分开浮起来 —— 图先淡入，字比它晚 0.12s 从下方 10px 上浮。
   只在 .is-anim 时挂 animation，切走时摘掉，回来才能重播（由脚本双 rAF 控制）。 */
@keyframes kbc-copy-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
.kbc-slide.is-anim .kbc-copy-title {
  animation: kbc-copy-in 0.48s cubic-bezier(0.22, 0.8, 0.3, 1) 0.12s both;
}
.kbc-slide.is-anim .kbc-copy-sub {
  animation: kbc-copy-in 0.48s cubic-bezier(0.22, 0.8, 0.3, 1) 0.20s both;
}

.kbc-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 0 3px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.90);
  background: rgba(255, 255, 255, 0.84);
  color: var(--primary);
  font-size: 20px;
  line-height: 1;
  font-family: inherit;
  cursor: pointer;
  opacity: 0;
  box-shadow: 0 8px 18px -10px rgba(16, 24, 40, 0.55);
  transition: opacity 0.2s ease, background 0.2s ease, transform 0.2s ease;
}
.kbc-prev { left: 12px; }
.kbc-next { right: 12px; }
.kb-carousel:hover .kbc-nav,
.kb-carousel:focus-within .kbc-nav { opacity: 1; }
.kbc-nav:hover { background: #fff; }
.kbc-nav:active { transform: translateY(-50%) scale(0.94); }
/* 触屏没有 hover，按钮常驻 */
@media (hover: none) {
  .kbc-nav { opacity: 1; }
}

/* 底部文案 tab（替代原来的圆点）：每条 = 4px 进度条 + 一句短标题。
   进度条宽度由脚本按「已播时长 / 6000ms」逐帧写，走满即切下一张，
   和切换共用一个时钟，所以永远不会出现「条走完了还没换」的错位。 */
.kbc-steps {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 15px;
  z-index: 4;
  display: flex;
  gap: 18px;
  padding: 0 26px;
}
.kbc-step {
  flex: 1 1 0;
  min-width: 0;
  max-width: 260px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
  cursor: pointer;
  opacity: 0.66;
  transition: opacity 0.25s ease;
}
.kbc-step:hover { opacity: 0.9; }
.kbc-step.is-on { opacity: 1; }
.kbc-step:focus-visible {
  outline: 2px solid #004280;
  outline-offset: 3px;
  border-radius: 4px;
}
.kbc-step-bar {
  display: block;
  height: 5px;
  border-radius: 2.5px;
  background: rgba(15, 47, 85, 0.22);
  overflow: hidden;
}
.kbc-step-fill {
  display: block;
  width: 0;
  height: 100%;
  border-radius: 2px;
  background: linear-gradient(90deg, #4a90d9, #004280);
}
.kbc-step-label {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 12.5px;
  line-height: 1.42;
  font-weight: 600;
  color: #0f2f55;
}

html.dark-theme .kbc-stage {
  border-color: rgba(255, 255, 255, 0.12);
  background: rgba(20, 23, 31, 0.60);
}
html.dark-theme .kbc-nav {
  border-color: rgba(255, 255, 255, 0.16);
  background: rgba(38, 45, 58, 0.92);
  color: #cfe0f2;
}
html.dark-theme .kbc-nav:hover { background: rgba(38, 45, 58, 0.96); }

/* 深色底：站点深色主题，或这张图本身是深色海报（json 里 theme: "dark"）。
   两者都用深遮罩 + 反白文字。 */
html.dark-theme .kbc-slide::after,
.kbc-slide[data-theme="dark"]::after {
  background-image:
    linear-gradient(to right,
      rgba(12, 16, 24, 0.90) 0%,
      rgba(12, 16, 24, 0.88) 26%,
      rgba(12, 16, 24, 0.78) 36%,
      rgba(12, 16, 24, 0.48) 45%,
      rgba(12, 16, 24, 0.16) 52%,
      rgba(12, 16, 24, 0) 60%),
    linear-gradient(to top,
      rgba(12, 16, 24, 0.72) 0px,
      rgba(12, 16, 24, 0.40) 40px,
      rgba(12, 16, 24, 0) 76px);
}
html.dark-theme .kbc-copy-title,
.kbc-slide[data-theme="dark"] .kbc-copy-title { color: #e8eef7; }
html.dark-theme .kbc-copy-sub,
.kbc-slide[data-theme="dark"] .kbc-copy-sub { color: rgba(232, 238, 247, 0.76); }
/* 底部的 tab 条在 slide 之外（是整个轮播共用的），所以只跟站点主题走；
   slide 自身的 data-theme 只负责它自己的遮罩和文字反色。 */
html.dark-theme .kbc-step-bar { background: rgba(255, 255, 255, 0.18); }
html.dark-theme .kbc-step-fill { background: linear-gradient(90deg, #7fb3e8, #4a90d9); }
html.dark-theme .kbc-step-label { color: #e8eef7; }

/* 2026-11-06（V1.1.39）：这里原本有一条 @media (max-height: 860px) 的矮屏规则，
   把轮播改成「宽度整列 + 固定高度裁上下」。既然定稿是「图片一点不裁、页面可以滚」，
   这条规则连同它的裁切一起删掉；轮播在桌面端统一按 1600/775 的完整比例显示。 */

@media (max-width: 600px) {
  /* 手机：宽度本来就受限，按 vh 反推反而会随地址栏伸缩而跳动，直接用满宽。
     高度比桌面扁一些（16:10）—— 横向截图裁成方形会切掉太多内容。 */
  .kb-carousel { max-width: 100%; }
  .kbc-stage { aspect-ratio: 16 / 10; }
  .kbc-nav { width: 28px; height: 28px; font-size: 16px; }
  .kbc-prev { left: 8px; }
  .kbc-next { right: 8px; }
  .kbc-copy { left: 14px; bottom: 54px; width: calc(100% - 28px); }
  .kbc-copy-title { font-size: 16px; line-height: 1.32; }
  .kbc-copy-sub { margin-top: 5px; font-size: 11.5px; line-height: 1.5; }
  /* tab 条横向滚动：5 条 × 128px 放不进 390 宽，滚比压成两行好读 */
  .kbc-steps {
    gap: 12px;
    padding: 0 14px 2px;
    bottom: 10px;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .kbc-steps::-webkit-scrollbar { display: none; }
  .kbc-step { flex: 0 0 126px; max-width: none; gap: 6px; }
  .kbc-step-bar { height: 3px; }
  .kbc-step-label { font-size: 11.5px; white-space: nowrap; }
  /* 手机上文字几乎占满整宽，横向遮罩会把人切成「左白右图」；
     改成从底往上的整体渐隐，标题、副标、tab 都落在这层里。 */
  .kbc-slide::after {
    background-image: linear-gradient(to top,
      rgba(255, 255, 255, 0.97) 0%,
      rgba(255, 255, 255, 0.93) 30%,
      rgba(255, 255, 255, 0.55) 45%,
      rgba(255, 255, 255, 0) 60%);
  }
  html.dark-theme .kbc-slide::after,
  .kbc-slide[data-theme="dark"]::after {
    background-image: linear-gradient(to top,
      rgba(12, 16, 24, 0.96) 0%,
      rgba(12, 16, 24, 0.92) 30%,
      rgba(12, 16, 24, 0.54) 45%,
      rgba(12, 16, 24, 0) 60%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .kbc-slide,
  .kbc-slide.is-on { transition: none; }
  .kbc-slide.is-anim .kbc-copy-title,
  .kbc-slide.is-anim .kbc-copy-sub { animation: none; }
}


/* ===== 用户管理：快速查找（搜索 / 等级筛选 / 排序 / 分页） ===== */
.user-toolbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 14px;
}
.user-search {
  position: relative; display: flex; align-items: center;
  flex: 1 1 300px; max-width: 440px; min-width: 200px;
}
.user-search-icon {
  position: absolute; left: 11px; color: var(--text-muted); pointer-events: none;
}
.user-search-input {
  width: 100%; height: 38px; padding: 0 58px 0 34px;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--surface); color: var(--text);
  font-size: 13px; font-family: inherit; outline: none;
  -webkit-appearance: none; appearance: none;
  transition: border-color .18s ease, box-shadow .18s ease;
}
.user-search-input::placeholder { color: var(--text-muted); }
.user-search-input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-glow); }
.user-search-input::-webkit-search-cancel-button { display: none; }
.user-search-clear {
  position: absolute; right: 30px; width: 18px; height: 18px;
  display: none; align-items: center; justify-content: center;
  border: none; border-radius: 50%; background: rgba(128, 128, 128, .18);
  color: var(--text-secondary); font-size: 11px; line-height: 1; cursor: pointer;
}
.user-search-clear.is-visible { display: flex; }
.user-search-clear:hover { background: rgba(128, 128, 128, .32); }
.user-search-kbd {
  position: absolute; right: 9px; padding: 1px 6px;
  border: 1px solid var(--border); border-radius: 4px;
  background: var(--bg); color: var(--text-muted);
  font-size: 11px; font-family: inherit; pointer-events: none;
}
.user-toolbar-select { width: auto; min-width: 130px; height: 38px; padding: 0 10px; font-size: 13px; }
.user-toolbar-add {
  margin-left: auto; height: 38px;
  display: inline-flex; align-items: center; gap: 6px;
}

.users-list { transition: opacity .15s ease; }
.users-list.is-loading { opacity: .5; pointer-events: none; }
.users-list .data-table td, .users-list .data-table th { padding-top: 10px; padding-bottom: 10px; }

.u-hl {
  background: rgba(255, 193, 7, .38); color: inherit;
  padding: 0 1px; border-radius: 2px;
}
.dark-theme .u-hl { background: rgba(255, 193, 7, .24); color: #ffe9a8; }

.users-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-top: 12px;
  font-size: 12px; color: var(--text-muted);
}
.users-count strong { color: var(--text); font-weight: 600; }
.users-range { margin-left: 8px; padding-left: 8px; border-left: 1px solid var(--border); }
.users-pager { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.u-page {
  min-width: 30px; height: 30px; padding: 0 9px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: 6px;
  background: var(--surface); color: var(--text-secondary);
  font-size: 12px; text-decoration: none;
  transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.u-page:hover { border-color: var(--primary); color: var(--primary); background: var(--surface-hover); }
.u-page.is-current { background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600; }
.u-page.is-disabled { opacity: .4; cursor: default; }
.u-page.is-gap { border-color: transparent; background: transparent; }
.dark-theme .u-page.is-current { color: #0b1220; }

@media (max-width: 720px) {
  /* 窄屏用两列网格：搜索框整行 → 两个下拉各占一列 → 按钮整行，避免 flex 拉伸算不准 */
  .user-toolbar { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
  .user-search { grid-column: 1 / -1; max-width: none; }
  .user-toolbar-select { width: 100%; min-width: 0; }
  .user-toolbar-add { grid-column: 1 / -1; margin-left: 0; justify-content: center; }
}

/* 后台内容列允许收缩：宽表格在 .data-table-wrapper 内部横向滚动，
   否则 flex 子项按内容撑宽，整页出现横向溢出（窄屏时工具栏按钮会被推到屏幕外） */
.admin-content { min-width: 0; }

/* ===== 访问记录 · 趋势弹窗 ===== */
.kb-stats-modal { max-width: 880px; width: 92vw; }
.kb-stats-modal .modal-header { gap: 12px; }
.kb-stats-modal .modal-header h3 {
  font-size: 16px; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.kb-stats-modal-tools { display: flex; align-items: center; gap: 8px; flex: none; }
.kb-stats-modal .modal-body { padding: 18px 22px 22px; }

.kb-stats-summary { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
.kbs-chip {
  flex: 1 1 110px; min-width: 92px; padding: 8px 12px;
  border: 1px solid var(--border); border-radius: 8px; background: var(--bg);
}
.kbs-chip-label { font-size: 11px; color: var(--text-secondary); line-height: 1.4; }
.kbs-chip-value { font-size: 19px; font-weight: 600; color: var(--text); line-height: 1.3; }

.kb-stats-chart { height: 320px; }
/* 无数据时不留 320px 空画布，弹窗跟着收缩 */
.kb-stats-chart.is-empty { height: 170px; }
.kb-chart-empty {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-muted); font-size: 13px;
}
.kb-chart-error {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-muted); font-size: 13px; text-align: center; padding: 0 16px;
}

@media (max-width: 640px) {
  .kb-stats-modal { width: 96vw; }
  .kb-stats-modal .modal-header { padding: 14px 16px; flex-wrap: wrap; gap: 8px 12px; }
  .kb-stats-modal .modal-header h3 { flex: 1 1 100%; font-size: 14px; }
  .kb-stats-modal-tools { flex: 1 1 100%; justify-content: flex-end; }
  .kb-stats-modal .modal-body { padding: 14px 16px 18px; }
  .kb-stats-chart { height: 240px; }
  .kbs-chip { flex: 1 1 45%; padding: 7px 10px; }
  .kbs-chip-value { font-size: 17px; }
}

/* ===== 文档阅读器打印 ===== */
@media print {
  .navbar-glass,
  .pdfv-bar,
  .pdfv-meta,
  .pdfv-hint,
  .toast-container { display: none !important; }
  .main-content { padding: 0 !important; }
  .pdfv-page { height: auto !important; }
  .pdfv-stage { overflow: visible !important; background: #fff !important; padding: 0 !important; }
  .pdfv-sheet { box-shadow: none !important; margin: 0 auto 12px; }
}
