
/* ---------- 令牌 ---------- */
:root {
  --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
          "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", "Cascadia Mono",
          Consolas, "Liberation Mono", monospace;

  /* 圆角 */
  --r-xs: 4px;
  --r-sm: 6px;
  --r-md: 8px;
  --r-lg: 12px;
  --r-xl: 16px;
  --r-full: 999px;

  /* 主色（靛蓝紫） */
  --primary:        #5b5bd6;
  --primary-hover:  #4f46e5;
  --primary-active: #4338ca;
  --primary-soft:   #eef0ff;
  --primary-line:   #c9cbf7;
  --on-primary:     #ffffff;

  /* 语义色 */
  --success: #16a34a;  --success-soft: #e9f8ef;
  --warning: #f59e0b;  --warning-soft: #fef5e7;
  --danger:  #ef4444;  --danger-soft:  #feeceb;
  --info:    #3b82f6;  --info-soft:    #eaf2fe;
  --cyan:    #06b6d4;  --cyan-soft:    #e5f8fb;
  --pink:    #ec4899;  --pink-soft:    #fdebf4;

  /* 渐变（hero / 主按钮） */
  --grad: linear-gradient(135deg, #6366f1 0%, #8b5cf6 52%, #a855f7 100%);
  --grad-soft: linear-gradient(135deg, #eef0ff 0%, #f5eeff 100%);

  --t: 150ms cubic-bezier(.4, 0, .2, 1);
  --rail: 236px;
}

[data-theme="light"] {
  --bg:        #f6f7fb;
  --bg-2:      #eef0f6;
  --card:      #ffffff;
  --card-2:    #fafbfe;
  --card-3:    #f3f5fa;
  --border:    #e6e8f0;
  --border-2:  #eff1f7;
  --border-3:  #d9dce7;
  --text:      #1a1d27;
  --text-2:    #5a6274;
  --text-3:    #8a92a6;
  --text-4:    #aab1c0;
  --header-bg: rgba(255, 255, 255, .82);
  --code-bg:   #f7f8fc;
  --code-line: #e9ecf5;
  --veil:      rgba(26, 29, 39, .42);
  --hover:     #f3f5fa;
  --shadow-1:  0 1px 2px rgba(24, 28, 44, .04), 0 1px 3px rgba(24, 28, 44, .03);
  --shadow-2:  0 4px 12px rgba(24, 28, 44, .07), 0 1px 3px rgba(24, 28, 44, .04);
  --shadow-3:  0 14px 40px rgba(24, 28, 44, .14);
  --ring:      0 0 0 3px rgba(91, 91, 214, .16);
}

[data-theme="dark"] {
  --bg:        #0f1117;
  --bg-2:      #14171f;
  --card:      #171a22;
  --card-2:    #1c2029;
  --card-3:    #222732;
  --border:    #262a36;
  --border-2:  #20242e;
  --border-3:  #333846;
  --text:      #e8eaf0;
  --text-2:    #a3abbb;
  --text-3:    #767e90;
  --text-4:    #5b6376;
  --header-bg: rgba(15, 17, 23, .82);
  --code-bg:   #12141b;
  --code-line: #232733;
  --veil:      rgba(0, 0, 0, .66);
  --hover:     #1e222c;
  --shadow-1:  0 1px 2px rgba(0, 0, 0, .3);
  --shadow-2:  0 6px 18px rgba(0, 0, 0, .42);
  --shadow-3:  0 18px 48px rgba(0, 0, 0, .58);
  --ring:      0 0 0 3px rgba(129, 124, 246, .28);

  --primary:        #7c7cf0;
  --primary-hover:  #8f8ff5;
  --primary-active: #6d6de8;
  --primary-soft:   rgba(124, 124, 240, .15);
  --primary-line:   rgba(124, 124, 240, .38);
  --grad: linear-gradient(135deg, #6366f1 0%, #7c3aed 100%);

  --success: #3fce7c;  --success-soft: rgba(63, 206, 124, .14);
  --warning: #fbbf24;  --warning-soft: rgba(251, 191, 36, .14);
  --danger:  #f87171;  --danger-soft:  rgba(248, 113, 113, .14);
  --info:    #60a5fa;  --info-soft:    rgba(96, 165, 250, .14);
  --cyan:    #22d3ee;  --cyan-soft:    rgba(34, 211, 238, .14);
  --pink:    #f472b6;  --pink-soft:    rgba(244, 114, 182, .14);
  --grad-soft: linear-gradient(135deg, rgba(99,102,241,.16) 0%, rgba(168,85,247,.16) 100%);
}

/* ---------- 基础 ---------- */
* { box-sizing: border-box; margin: 0; padding: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  font-family: var(--sans);
  font-size: 14px; line-height: 1.6; color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
a { color: var(--primary); text-decoration: none; }
a:hover { color: var(--primary-hover); }
img { max-width: 100%; display: block; }
/* 图标默认走 inline-block + 垂直居中。
   原来写 display:block 会让内联流里的「图标 + 文字」错位（图标掉到文字下方或顶到上边），
   而 flex/grid 容器会自动把 inline-block 的 item 收成块级，行为与之前一致，所以这样改是安全的。 */
svg { display: inline-block; vertical-align: middle; }
button { font: inherit; }
h1, h2, h3, h4 { font-weight: 650; letter-spacing: -.01em; line-height: 1.35; }
::selection { background: var(--primary-soft); color: var(--text); }

* { scrollbar-width: thin; scrollbar-color: var(--border-3) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--border-3); border-radius: var(--r-full);
  border: 3px solid transparent; background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--text-4); background-clip: content-box; }
:focus-visible { outline: none; box-shadow: var(--ring); border-radius: var(--r-sm); }

/* ---------- 工具类 ---------- */
.row   { display: flex; align-items: center; gap: 10px; }
.row-t { display: flex; align-items: flex-start; gap: 10px; }
.between { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.wrap  { flex-wrap: wrap; }
.grow  { flex: 1; min-width: 0; }
.col   { display: flex; flex-direction: column; gap: 10px; }
.center { display: flex; align-items: center; justify-content: center; }
.mono  { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.num   { text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; white-space: nowrap; }
.muted { color: var(--text-3); }
.hint  { font-size: 12.5px; color: var(--text-3); line-height: 1.65; }
/* 行内「图标 + 文字」通用包裹。凡是把图标和文字拼在一个非 flex 元素里的地方都用它，
   否则图标会与文字错位（一高一低 / 掉行）。 */
.ico-txt { display: inline-flex; align-items: center; gap: 4px; }
.ellip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nowrap { white-space: nowrap; }
.tar { text-align: right; }
.tac { text-align: center; }
.hidden { display: none !important; }
.mt8 { margin-top: 8px } .mt12 { margin-top: 12px } .mt16 { margin-top: 16px }
.mt20 { margin-top: 20px } .mt24 { margin-top: 24px } .mt32 { margin-top: 32px }
.mb8 { margin-bottom: 8px } .mb12 { margin-bottom: 12px } .mb16 { margin-bottom: 16px }
.mb20 { margin-bottom: 20px } .mb24 { margin-bottom: 24px }

/* ---------- 容器 ---------- */
.container { width: 100%; max-width: 1200px; margin: 0 auto; padding: 0 24px; }
.page { width: 100%; max-width: 1440px; padding: 22px 26px 60px; }

/* ============================================================================
   控制台外壳：侧栏 + 主区
   ========================================================================== */
.shell { display: flex; min-height: 100vh; }

.sidebar {
  width: var(--rail); flex: 0 0 var(--rail);
  position: sticky; top: 0; height: 100vh; z-index: 40;
  display: flex; flex-direction: column;
  padding: 16px 12px;
  background: var(--card);
  border-right: 1px solid var(--border);
}
.sb-brand {
  display: flex; align-items: center; gap: 10px;
  padding: 4px 8px 16px; margin-bottom: 6px;
  border-bottom: 1px solid var(--border-2);
}
.sb-logo {
  width: 34px; height: 34px; flex: 0 0 34px; border-radius: var(--r-md);
  display: grid; place-items: center; overflow: hidden;
  background: var(--card-3); border: 1px solid var(--border-2);
}
.sb-logo img { width: 100%; height: 100%; object-fit: contain; }
.sb-name { min-width: 0; }
.sb-name b { display: block; font-size: 14.5px; font-weight: 650; letter-spacing: -.01em; }
.sb-name span { display: block; font-size: 11px; color: var(--text-3); margin-top: 1px; }

.sb-nav { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; padding: 4px 0; }
.sb-group {
  padding: 14px 10px 6px;
  font-size: 11px; font-weight: 600; letter-spacing: .04em;
  color: var(--text-4); text-transform: uppercase;
}
.sb-item {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border-radius: var(--r-md);
  font-size: 13.5px; font-weight: 500; color: var(--text-2);
  background: transparent; border: 0; cursor: pointer; text-align: left; width: 100%;
  transition: background var(--t), color var(--t);
}
.sb-item svg { width: 17px; height: 17px; flex: 0 0 17px; }
.sb-item:hover { background: var(--hover); color: var(--text); }
.sb-item.on { background: var(--primary-soft); color: var(--primary); font-weight: 600; }
.sb-item .sb-badge {
  margin-left: auto; padding: 1px 7px; border-radius: var(--r-full);
  font-family: var(--mono); font-size: 11px; font-weight: 600;
  color: var(--text-2); background: var(--card-3);
}
.sb-item.on .sb-badge { color: var(--primary); background: var(--card); }
.sb-foot { padding-top: 12px; border-top: 1px solid var(--border-2); display: flex; flex-direction: column; gap: 8px; }

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* 顶栏 */
.topbar {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 14px 26px;
  background: var(--header-bg);
  backdrop-filter: saturate(1.6) blur(12px);
  -webkit-backdrop-filter: saturate(1.6) blur(12px);
  border-bottom: 1px solid var(--border);
}
.tb-title { font-size: 18px; font-weight: 650; letter-spacing: -.015em; }
.tb-sub { margin-top: 2px; font-size: 12.5px; color: var(--text-3); }
.tb-left { min-width: 0; }
.tb-right { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-wrap: wrap; }
/* 顶栏按钮统一高度：按钮里若含头像/长文字，高度会被撑开，和旁边按钮形成高低差 */
.tb-right > .btn, .tb-right .menu-wrap > .btn {
  height: 34px; padding-top: 0; padding-bottom: 0;
}
.tb-right .btn > .avatar { margin-left: -2px; }
.tb-search {
  display: flex; align-items: center; gap: 7px;
  padding: 7px 12px; min-width: 180px;
  border-radius: var(--r-md); border: 1px solid var(--border);
  background: var(--card-2); color: var(--text-3); font-size: 13px;
}
.tb-search svg { width: 15px; height: 15px; }

/* ============================================================================
   卡片
   ========================================================================== */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  overflow: hidden;
  margin-bottom: 16px;
}
.card-h {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 15px 18px;
  border-bottom: 1px solid var(--border-2);
}
.card-h .sp { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.card-t { font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
.card-d { margin-top: 2px; font-size: 12.5px; color: var(--text-3); }
.card-hico {
  width: 32px; height: 32px; flex: 0 0 32px; border-radius: var(--r-md);
  display: grid; place-items: center;
}
.card-hico svg { width: 17px; height: 17px; }
.card-b { padding: 18px; }
.card-b.flush { padding: 0; }
.card-f { padding: 13px 18px; border-top: 1px solid var(--border-2); background: var(--card-2); }

/* 图标块配色 */
.c-brand   { background: var(--primary-soft);  color: var(--primary); }
.c-success { background: var(--success-soft);  color: var(--success); }
.c-warning { background: var(--warning-soft);  color: var(--warning); }
.c-danger  { background: var(--danger-soft);   color: var(--danger); }
.c-info    { background: var(--info-soft);     color: var(--info); }
.c-cyan    { background: var(--cyan-soft);     color: var(--cyan); }
.c-pink    { background: var(--pink-soft);     color: var(--pink); }
.c-muted   { background: var(--card-3);        color: var(--text-2); }

/* ============================================================================
   KPI 指标卡
   ========================================================================== */
.kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; margin-bottom: 16px; }
.kpis.g3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.kpis.g2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.kpis.g5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.kpi {
  position: relative; overflow: hidden;
  padding: 17px 18px;
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--shadow-1);
  transition: box-shadow var(--t), transform var(--t), border-color var(--t);
}
.kpi:hover { box-shadow: var(--shadow-2); border-color: var(--border-3); transform: translateY(-1px); }
.kpi-top { display: flex; align-items: center; gap: 10px; }
.kpi-ico { width: 34px; height: 34px; flex: 0 0 34px; border-radius: var(--r-md); display: grid; place-items: center; }
.kpi-ico svg { width: 18px; height: 18px; }
.kpi-label { font-size: 12.5px; color: var(--text-3); font-weight: 500; }
.kpi-val { margin-top: 12px; font-family: var(--mono); font-size: 25px; font-weight: 700; letter-spacing: -.03em; line-height: 1.15; }
.kpi-sub { margin-top: 5px; font-size: 12px; color: var(--text-3); }
.kpi-sub b { color: var(--text-2); font-weight: 600; }
.kpi.v-brand .kpi-val { color: var(--primary); }
.kpi.v-success .kpi-val { color: var(--success); }
.kpi.v-warning .kpi-val { color: var(--warning); }
.kpi.v-danger .kpi-val { color: var(--danger); }
.kpi.v-info .kpi-val { color: var(--info); }
.kpi.v-cyan .kpi-val { color: var(--cyan); }
.kpi.v-pink .kpi-val { color: var(--pink); }

/* 公开页数据条 */
.stats-row {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px;
}
.stat-item {
  padding: 18px 20px; text-align: center;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
}
.stat-item b { display: block; font-family: var(--mono); font-size: 28px; font-weight: 700; letter-spacing: -.03em; }
.stat-item span { display: block; margin-top: 4px; font-size: 12.5px; color: var(--text-3); }

/* ============================================================================
   按钮
   ========================================================================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 8px 15px; border-radius: var(--r-md);
  font-size: 13.5px; font-weight: 550; white-space: nowrap; cursor: pointer;
  color: var(--text-2); background: var(--card);
  border: 1px solid var(--border);
  transition: all var(--t);
}
.btn svg { width: 15px; height: 15px; flex: 0 0 15px; }
.btn:hover { color: var(--text); border-color: var(--border-3); background: var(--hover); }
.btn:active { transform: translateY(.5px); }
.btn-primary {
  color: var(--on-primary); border-color: transparent;
  background: var(--primary); box-shadow: 0 1px 2px rgba(91, 91, 214, .3);
}
.btn-primary:hover { color: var(--on-primary); background: var(--primary-hover); border-color: transparent; box-shadow: 0 3px 10px rgba(91, 91, 214, .32); }
.btn-grad { color: #fff; border-color: transparent; background: var(--grad); }
.btn-grad:hover { color: #fff; filter: brightness(1.06); border-color: transparent; }
.btn-ghost { background: transparent; border-color: transparent; color: var(--text-2); }
.btn-ghost:hover { background: var(--hover); border-color: transparent; }
.btn-soft { color: var(--primary); background: var(--primary-soft); border-color: transparent; }
.btn-soft:hover { color: var(--primary-hover); background: var(--primary-soft); border-color: var(--primary-line); }
.btn-danger { color: var(--danger); background: var(--danger-soft); border-color: transparent; }
.btn-danger:hover { color: #fff; background: var(--danger); border-color: transparent; }
.btn-sm { padding: 6px 11px; font-size: 12.5px; border-radius: var(--r-sm); }
.btn-sm svg { width: 14px; height: 14px; flex: 0 0 14px; }
.btn-lg { padding: 11px 22px; font-size: 14.5px; border-radius: var(--r-md); }
.btn-icon { padding: 8px; }
.btn-icon.btn-sm { padding: 6px; }
.btn-block { width: 100%; }
.btn[disabled], .btn.disabled { opacity: .45; pointer-events: none; }

/* ============================================================================
   表单
   ========================================================================== */
.field { display: flex; flex-direction: column; gap: 7px; }
.field > label, .field > span {
  font-size: 12.5px; font-weight: 550; color: var(--text-2);
}
/* 蜜罐：真人看不到也点不到，但自动填表脚本会把它当普通字段填上。
   故意不用 display:none / visibility:hidden —— 部分脚本会主动跳过被隐藏的元素。 */
.hp-field {
  position: absolute; left: -9999px; top: auto;
  width: 1px; height: 1px; overflow: hidden; opacity: 0;
  pointer-events: none;
}
input:not([type=checkbox]):not([type=radio]), select, textarea,
.input, .select, .textarea {
  width: 100%; padding: 8px 12px;
  font-family: inherit; font-size: 13.5px; color: var(--text);
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-md);
  transition: border-color var(--t), box-shadow var(--t), background var(--t);
}
input::placeholder, textarea::placeholder { color: var(--text-4); }
input:not([type=checkbox]):hover, select:hover, textarea:hover { border-color: var(--border-3); }
input:not([type=checkbox]):focus, select:focus, textarea:focus {
  outline: none; border-color: var(--primary); box-shadow: var(--ring);
}
input[type=number], input[type=date] { font-family: var(--mono); }
textarea { line-height: 1.7; resize: vertical; min-height: 84px; }
select {
  appearance: none; cursor: pointer; padding-right: 32px;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-3) 50%),
                    linear-gradient(135deg, var(--text-3) 50%, transparent 50%);
  background-position: calc(100% - 17px) 52%, calc(100% - 12px) 52%;
  background-size: 5px 5px, 5px 5px; background-repeat: no-repeat;
}
input[type=checkbox] { width: 16px; height: 16px; accent-color: var(--primary); cursor: pointer; border-radius: var(--r-xs); }
.form-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; }

/* 「输入框 + 操作按钮」同行：输入框自适应，按钮固定宽度不参与压缩 */
.code-row { display: flex; align-items: stretch; gap: 8px; }
.code-row > input { flex: 1; min-width: 0; font-family: var(--mono); letter-spacing: .12em; }
.code-row > .btn { flex: 0 0 auto; min-width: 112px; font-variant-numeric: tabular-nums; }
.code-row > .btn svg { width: 15px; height: 15px; }

/* 「图形验证码」行：输入框 + 可点击换图的图。
   图片必须固定占位 —— 换图时如果宽度跟着内容走，整行会横向跳一下。
   底色写死浅灰（与 SVG 自带底色一致），深色主题下也不例外：
   验证码图就应该是白底黑字，反色反而更难认。 */
.cap-row { display: flex; align-items: stretch; gap: 8px; }
.cap-row > input {
  flex: 1; min-width: 0;
  font-family: var(--mono); letter-spacing: .14em; text-transform: uppercase;
}
.cap-img {
  flex: 0 0 auto; width: 126px;
  display: grid; place-items: center; overflow: hidden;
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: #f4f5f9; color: #8a90a2; font-size: 12px;
  cursor: pointer; user-select: none;
  transition: border-color var(--t);
}
/* 后端下发的是 PNG 位图（早期是 SVG，但 SVG 里字符是明文，一条正则就能提取答案）。
   img 用 contain：保持比例居中，留白处正好和容器同色，看不出来。 */
.cap-img > svg, .cap-img > img {
  display: block; width: 100%; height: 100%; object-fit: contain;
  -webkit-user-drag: none;
}
.cap-img:hover { border-color: var(--border-3); }
.cap-img.loading { cursor: progress; }

.switch { display: inline-flex; align-items: center; gap: 9px; cursor: pointer; user-select: none; font-size: 13.5px; color: var(--text-2); }
.switch input { position: absolute; opacity: 0; pointer-events: none; }
.switch .track {
  position: relative; width: 38px; height: 21px; flex: 0 0 38px;
  background: var(--border-3); border-radius: var(--r-full);
  transition: background var(--t);
}
.switch .track::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 17px; height: 17px;
  background: #fff; border-radius: 50%; box-shadow: 0 1px 3px rgba(0, 0, 0, .22);
  transition: left var(--t);
}
.switch input:checked + .track { background: var(--primary); }
.switch input:checked + .track::after { left: 19px; }

/* 分段控件 / 标签页 */
.seg { display: inline-flex; padding: 3px; gap: 2px; background: var(--card-3); border-radius: var(--r-md); }
.seg > button {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-width: 88px;
  padding: 6px 14px; border: 0; border-radius: var(--r-sm); cursor: pointer;
  font-size: 13px; font-weight: 550; color: var(--text-2); background: transparent;
  transition: all var(--t); white-space: nowrap;
}
.seg > button:hover { color: var(--text); }
.seg > button.on { color: var(--text); background: var(--card); box-shadow: var(--shadow-1); font-weight: 600; }

.tabs { display: flex; gap: 22px; border-bottom: 1px solid var(--border); }
.tab {
  position: relative; padding: 10px 0; border: 0; background: transparent; cursor: pointer;
  font-size: 13.5px; font-weight: 550; color: var(--text-3); transition: color var(--t);
}
.tab:hover { color: var(--text); }
.tab.on { color: var(--primary); font-weight: 600; }
.tab.on::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: var(--primary); border-radius: var(--r-full);
}

/* ============================================================================
   标签 / 徽标
   ========================================================================== */
.tag {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px; border-radius: var(--r-full);
  font-size: 11.5px; font-weight: 550; white-space: nowrap;
  color: var(--text-2); background: var(--card-3);
}
.tag.ok   { color: var(--success); background: var(--success-soft); }
.tag.warn { color: var(--warning); background: var(--warning-soft); }
.tag.err  { color: var(--danger);  background: var(--danger-soft); }
.tag.info { color: var(--info);    background: var(--info-soft); }
.tag.brand{ color: var(--primary); background: var(--primary-soft); }
.tag.cyan { color: var(--cyan);    background: var(--cyan-soft); }
.tag.pink { color: var(--pink);    background: var(--pink-soft); }
.tag .dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }

.avatar {
  width: 34px; height: 34px; flex: 0 0 34px; border-radius: var(--r-full);
  display: grid; place-items: center;
  font-size: 13px; font-weight: 650; color: var(--primary); background: var(--primary-soft);
}
.avatar.sm { width: 26px; height: 26px; flex: 0 0 26px; font-size: 11px; }
.avatar.lg { width: 46px; height: 46px; flex: 0 0 46px; font-size: 17px; }
/* 按钮里的头像必须压到不高于按钮行高，否则会把按钮撑高，和相邻按钮高低不齐 */
.btn > .avatar { width: 20px; height: 20px; flex: 0 0 20px; font-size: 10.5px; }
.btn-lg > .avatar { width: 26px; height: 26px; flex: 0 0 26px; font-size: 12px; }

/* 复制框 */
.copy-box {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-radius: var(--r-md);
  background: var(--card-2); border: 1px solid var(--border);
  font-family: var(--mono); font-size: 13px; overflow: hidden;
}
.copy-box .v { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 代码块 */
.code {
  position: relative;
  padding: 14px 16px; border-radius: var(--r-md);
  background: var(--code-bg); border: 1px solid var(--code-line);
  font-family: var(--mono); font-size: 12.5px; line-height: 1.75; color: var(--text-2);
  white-space: pre; overflow-x: auto; tab-size: 2;
}
.code.wrap-code { white-space: pre-wrap; word-break: break-word; }
.code-tabs { display: flex; align-items: center; gap: 2px; margin-bottom: 10px; }

/* ============================================================================
   表格
   ========================================================================== */
.tbl-wrap { width: 100%; overflow-x: auto; }
table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13.5px; }
table th {
  padding: 11px 16px; text-align: left; white-space: nowrap;
  font-size: 12px; font-weight: 600; color: var(--text-3);
  background: var(--card-2); border-bottom: 1px solid var(--border);
}
table td { padding: 13px 16px; border-bottom: 1px solid var(--border-2); color: var(--text-2); }
table tbody tr { transition: background var(--t); }
table tbody tr:hover td { background: var(--card-2); }
table tbody tr:last-child td { border-bottom: 0; }
table td.k { color: var(--text); font-weight: 550; }
table th.num, table td.num { text-align: right; }
table.rowlink tbody tr { cursor: pointer; }

/* ============================================================================
   图表（纯 SVG）
   ========================================================================== */
.chart { width: 100%; }
.chart svg { width: 100%; height: auto; display: block; overflow: visible; }
.chart .gl { stroke: var(--border-2); stroke-width: 1; }
.chart .ax { stroke: var(--border); stroke-width: 1; }
.chart .lb { fill: var(--text-4); font-size: 10px; font-family: var(--mono); }
.chart .val { fill: var(--text); font-size: 10.5px; font-family: var(--mono); font-weight: 600; }
.chart-legend { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; font-size: 12.5px; color: var(--text-3); }
.chart-legend i { width: 9px; height: 9px; border-radius: 3px; display: inline-block; margin-right: 6px; vertical-align: -1px; }

/* 横向条形排行 */
.bar-list { display: flex; flex-direction: column; gap: 13px; }
.bar-item .bar-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 6px; }
.bar-item .bar-name { flex: 1; min-width: 0; font-size: 13px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-item .bar-meta { font-family: var(--mono); font-size: 12px; color: var(--text-3); white-space: nowrap; }
.bar-track { height: 6px; border-radius: var(--r-full); background: var(--card-3); overflow: hidden; }
.bar-fill { height: 100%; border-radius: var(--r-full); background: var(--primary); transition: width 400ms ease; }

/* 进度条 */
.progress { height: 6px; border-radius: var(--r-full); background: var(--card-3); overflow: hidden; }
.progress > i { display: block; height: 100%; border-radius: var(--r-full); background: var(--primary); transition: width 400ms ease; }
.progress.ok > i { background: var(--success); }
.progress.warn > i { background: var(--warning); }
.progress.danger > i { background: var(--danger); }

/* ============================================================================
   列表 / 键值对
   ========================================================================== */
.kv { display: flex; flex-direction: column; }
.kv > .kv-row {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 11px 0; border-bottom: 1px solid var(--border-2);
}
.kv > .kv-row:last-child { border-bottom: 0; }
.kv .k { font-size: 13.5px; color: var(--text-3); }
.kv .v { font-size: 13.5px; color: var(--text); font-weight: 550; }

.list-row {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 18px; border-bottom: 1px solid var(--border-2);
  transition: background var(--t);
}
.list-row:last-child { border-bottom: 0; }
.list-row:hover { background: var(--card-2); }
.list-row .lr-main { flex: 1; min-width: 0; }
.list-row .lr-t { font-size: 13.5px; font-weight: 550; color: var(--text); }
.list-row .lr-s { margin-top: 2px; font-size: 12px; color: var(--text-3); }

/* 令牌卡片 */
.key-card {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 15px 18px; border-bottom: 1px solid var(--border-2);
  transition: background var(--t);
}
.key-card:last-child { border-bottom: 0; }
.key-card:hover { background: var(--card-2); }
.key-card.off { opacity: .6; }
.key-ico { width: 38px; height: 38px; flex: 0 0 38px; border-radius: var(--r-md); display: grid; place-items: center; }
.key-ico svg { width: 19px; height: 19px; }
.key-main { flex: 1; min-width: 200px; }
.key-name { display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600; color: var(--text); }
.key-val {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 6px;
  padding: 4px 9px; border-radius: var(--r-sm);
  font-family: var(--mono); font-size: 12px; color: var(--text-2);
  background: var(--card-3); cursor: pointer;
}
.key-val:hover { color: var(--primary); }
.key-val svg { width: 13px; height: 13px; flex: 0 0 13px; }
/* 元信息行：图标与文字必须在同一基线盒里居中，否则会一高一低 */
.key-meta {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  margin-top: 8px; font-size: 12px; color: var(--text-3);
}
.key-meta > span { display: inline-flex; align-items: center; gap: 5px; }
.key-meta svg { width: 13px; height: 13px; flex: 0 0 13px; }
.key-acts { display: flex; align-items: center; gap: 6px; }

/* ============================================================================
   空态 / 加载
   ========================================================================== */
.empty { padding: 56px 20px; text-align: center; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.empty .e-ico {
  width: 62px; height: 62px; border-radius: var(--r-xl); display: grid; place-items: center;
  background: var(--card-3); color: var(--text-4);
}
.empty .e-ico svg { width: 30px; height: 30px; }
.empty .e-t { font-size: 14px; font-weight: 600; color: var(--text-2); }
.empty .e-d { font-size: 12.5px; color: var(--text-3); max-width: 340px; }

.spinner {
  width: 16px; height: 16px; border-radius: 50%;
  border: 2px solid var(--border-3); border-top-color: var(--primary);
  animation: spin .7s linear infinite;
}
.spinner.lg { width: 26px; height: 26px; border-width: 3px; }
@keyframes spin { to { transform: rotate(360deg); } }
.loading { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 56px 20px; font-size: 13.5px; color: var(--text-3); }

.skeleton {
  border-radius: var(--r-sm);
  background: linear-gradient(90deg, var(--card-3) 25%, var(--border-2) 37%, var(--card-3) 63%);
  background-size: 400% 100%; animation: shimmer 1.4s ease infinite;
}
@keyframes shimmer { from { background-position: 100% 0 } to { background-position: 0 0 } }

/* ============================================================================
   弹窗 / 抽屉 / Toast
   ========================================================================== */
.overlay {
  position: fixed; inset: 0; z-index: 90;
  display: grid; place-items: center; padding: 24px;
  background: var(--veil);
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  animation: fade .16s ease; overflow-y: auto;
}
@keyframes fade { from { opacity: 0 } to { opacity: 1 } }
.modal {
  width: 100%; max-width: 560px; max-height: 88vh; overflow-y: auto;
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r-xl); box-shadow: var(--shadow-3);
  animation: pop .18s cubic-bezier(.2,.9,.3,1.2);
}
@keyframes pop { from { opacity: 0; transform: translateY(8px) scale(.985) } to { opacity: 1; transform: none } }
.modal-h { padding: 20px 22px 0; }
.modal-h h3 { font-size: 17px; font-weight: 650; }
.modal-d { margin-top: 6px; font-size: 13px; color: var(--text-3); line-height: 1.65; }
.modal-b { padding: 20px 22px; display: flex; flex-direction: column; gap: 14px; }
.modal-f { padding: 15px 22px; display: flex; gap: 9px; justify-content: flex-end; flex-wrap: wrap; border-top: 1px solid var(--border-2); }
.modal.wide { max-width: 760px; }
.modal-x {
  position: absolute; top: 16px; right: 16px;
  width: 30px; height: 30px; border-radius: var(--r-sm); display: grid; place-items: center;
  border: 0; background: transparent; color: var(--text-3); cursor: pointer;
}
.modal-x:hover { background: var(--hover); color: var(--text); }
.modal-pos { position: relative; }

/* 侧滑抽屉 */
.drawer-mask {
  position: fixed; inset: 0; z-index: 95;
  background: var(--veil); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  animation: fade .16s ease;
}
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 96;
  width: min(560px, 100vw); display: flex; flex-direction: column;
  background: var(--card); border-left: 1px solid var(--border);
  box-shadow: var(--shadow-3); animation: slideIn .22s cubic-bezier(.2,.9,.3,1);
}
@keyframes slideIn { from { transform: translateX(24px); opacity: .4 } to { transform: none; opacity: 1 } }
.drawer-h { display: flex; align-items: center; gap: 10px; padding: 18px 20px; border-bottom: 1px solid var(--border); }
.drawer-b { flex: 1; overflow-y: auto; padding: 20px; }

.toasts { position: fixed; right: 22px; bottom: 22px; z-index: 120; display: flex; flex-direction: column; gap: 10px; pointer-events: none; }
.toast {
  display: flex; align-items: center; gap: 10px;
  max-width: 380px; padding: 12px 16px; border-radius: var(--r-md);
  font-size: 13.5px; color: var(--text);
  background: var(--card); border: 1px solid var(--border);
  box-shadow: var(--shadow-3);
  animation: toastIn .22s cubic-bezier(.2,.9,.3,1.2);
}
.toast svg { width: 17px; height: 17px; flex: 0 0 17px; }
.toast.ok svg { color: var(--success); }
.toast.err svg { color: var(--danger); }
.toast.warn svg { color: var(--warning); }
.toast.info svg { color: var(--info); }
@keyframes toastIn { from { opacity: 0; transform: translateX(20px) } to { opacity: 1; transform: none } }

/* 下拉菜单 */
.menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 80;
  min-width: 186px; padding: 5px;
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r-md); box-shadow: var(--shadow-3);
  animation: pop .14s ease;
}
.menu-item {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 8px 11px; border: 0; border-radius: var(--r-sm); background: transparent;
  font-size: 13.5px; color: var(--text-2); cursor: pointer; text-align: left;
}
.menu-item:hover { background: var(--hover); color: var(--text); }
.menu-item.danger { color: var(--danger); }
.menu-item.danger:hover { background: var(--danger-soft); }
.menu-sep { height: 1px; margin: 5px 0; background: var(--border-2); }
.menu-wrap { position: relative; }

/* 提示条 */
.notice {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 13px 15px; border-radius: var(--r-md);
  font-size: 13.5px; line-height: 1.65; color: var(--text-2);
  background: var(--primary-soft); border: 1px solid var(--primary-line);
}
.notice svg { width: 17px; height: 17px; flex: 0 0 17px; margin-top: 2px; color: var(--primary); }
.notice.warn { background: var(--warning-soft); border-color: transparent; }
.notice.warn svg { color: var(--warning); }
.notice.err { background: var(--danger-soft); border-color: transparent; }
.notice.err svg { color: var(--danger); }
.notice.ok { background: var(--success-soft); border-color: transparent; }
.notice.ok svg { color: var(--success); }

/* 分页 */
.pager { display: flex; align-items: center; justify-content: center; gap: 14px; padding: 15px 18px; border-top: 1px solid var(--border-2); }
.pager span { font-family: var(--mono); font-size: 12.5px; color: var(--text-3); }

/* ============================================================================
   公开站
   ========================================================================== */
.site { min-height: 100vh; display: flex; flex-direction: column; }
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--header-bg);
  backdrop-filter: saturate(1.6) blur(12px); -webkit-backdrop-filter: saturate(1.6) blur(12px);
  border-bottom: 1px solid var(--border);
}
.site-header .inner { display: flex; align-items: center; gap: 26px; height: 62px; }
.logo { display: flex; align-items: center; gap: 9px; cursor: pointer; }
.logo img { width: 30px; height: 30px; object-fit: contain; }
.logo b { font-size: 15.5px; font-weight: 700; letter-spacing: -.02em; color: var(--text); }
.nav-links { display: flex; align-items: center; gap: 4px; }
.nav-link {
  padding: 7px 13px; border-radius: var(--r-md); border: 0; background: transparent; cursor: pointer;
  font-size: 13.5px; font-weight: 500; color: var(--text-2); transition: all var(--t);
}
.nav-link:hover { color: var(--text); background: var(--hover); }
.nav-link.on { color: var(--primary); background: var(--primary-soft); font-weight: 600; }
.hd-right { display: flex; align-items: center; gap: 9px; margin-left: auto; }

.hero { position: relative; padding: 68px 0 56px; overflow: hidden; }
.hero::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: var(--grad-soft);
  mask-image: radial-gradient(90% 70% at 78% 12%, #000 0%, transparent 72%);
  -webkit-mask-image: radial-gradient(90% 70% at 78% 12%, #000 0%, transparent 72%);
}
.hero .container { position: relative; display: grid; grid-template-columns: 1.05fr .95fr; gap: 52px; align-items: center; }
.hero-badge {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 13px; border-radius: var(--r-full);
  font-size: 12.5px; font-weight: 550; color: var(--primary);
  background: var(--primary-soft); border: 1px solid var(--primary-line);
}
.hero-badge svg { width: 13px; height: 13px; }
.hero h1 { margin-top: 18px; font-size: 42px; font-weight: 750; letter-spacing: -.035em; line-height: 1.18; }
.hero h1 .hl { background: var(--grad); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.hero p.lead { margin-top: 18px; font-size: 15px; line-height: 1.85; color: var(--text-2); max-width: 520px; }
.hero-actions { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; margin-top: 28px; }
.hero-note { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-top: 20px; font-size: 12.5px; color: var(--text-3); }
.hero-note span { display: inline-flex; align-items: center; gap: 6px; }
.hero-note svg { width: 14px; height: 14px; color: var(--success); }

/* Hero 右侧：示例卡 */
.hero-card {
  border-radius: var(--r-xl); overflow: hidden;
  background: var(--card); border: 1px solid var(--border);
  box-shadow: var(--shadow-3);
}
.hero-card-h {
  display: flex; align-items: center; gap: 7px;
  padding: 11px 14px; background: var(--card-2); border-bottom: 1px solid var(--border);
}
.hero-card-h i { width: 10px; height: 10px; border-radius: 50%; display: block; }
.hero-card-b { padding: 14px; }
.hero-chat { display: flex; flex-direction: column; gap: 10px; }
.bubble {
  max-width: 86%; padding: 9px 13px; border-radius: var(--r-lg);
  font-size: 12.5px; line-height: 1.7;
}
.bubble.me { align-self: flex-end; color: #fff; background: var(--grad); border-bottom-right-radius: var(--r-xs); }
.bubble.ai { align-self: flex-start; color: var(--text-2); background: var(--card-2); border: 1px solid var(--border); border-bottom-left-radius: var(--r-xs); }

.section { padding: 60px 0; }
.section.alt { background: var(--card); border-top: 1px solid var(--border); border-bottom: 1px solid var(--border); }
.sec-head { text-align: center; margin-bottom: 34px; }
.sec-head h2 { font-size: 28px; font-weight: 700; letter-spacing: -.028em; }
.sec-head p { margin-top: 10px; font-size: 14px; color: var(--text-3); }

.features { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
.feature {
  padding: 22px; border-radius: var(--r-lg);
  background: var(--card); border: 1px solid var(--border);
  box-shadow: var(--shadow-1); transition: all var(--t);
}
.feature:hover { box-shadow: var(--shadow-2); border-color: var(--border-3); transform: translateY(-2px); }
.feature-ico { width: 40px; height: 40px; border-radius: var(--r-md); display: grid; place-items: center; margin-bottom: 14px; }
.feature-ico svg { width: 20px; height: 20px; }
.feature h3 { font-size: 15px; font-weight: 650; }
.feature p { margin-top: 7px; font-size: 13px; line-height: 1.75; color: var(--text-3); }

.faq { max-width: 820px; margin: 0 auto; display: flex; flex-direction: column; gap: 10px; }
.faq-item { border-radius: var(--r-lg); background: var(--card); border: 1px solid var(--border); overflow: hidden; }
.faq-q {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 16px 18px; border: 0; background: transparent; cursor: pointer;
  font-size: 14px; font-weight: 600; color: var(--text); text-align: left;
}
.faq-q svg { width: 17px; height: 17px; margin-left: auto; color: var(--text-3); transition: transform var(--t); }
.faq-item.open .faq-q svg { transform: rotate(180deg); }
.faq-a { padding: 0 18px 16px; font-size: 13.5px; line-height: 1.8; color: var(--text-2); }

.cta {
  position: relative; overflow: hidden; text-align: center;
  padding: 52px 30px; border-radius: var(--r-xl);
  background: var(--grad); color: #fff; box-shadow: var(--shadow-2);
}
.cta h2 { font-size: 27px; font-weight: 700; letter-spacing: -.028em; }
.cta p { margin: 12px auto 24px; max-width: 460px; font-size: 14px; color: rgba(255, 255, 255, .88); }
.cta .btn { background: #fff; color: var(--primary); border-color: transparent; }
.cta .btn:hover { background: #fff; color: var(--primary-active); }
.cta .btn.ghost-w { background: rgba(255, 255, 255, .16); color: #fff; border-color: rgba(255, 255, 255, .34); }
.cta .btn.ghost-w:hover { background: rgba(255, 255, 255, .24); }

.site-footer { margin-top: auto; padding: 34px 0; border-top: 1px solid var(--border); background: var(--card); }
.site-footer .inner { display: flex; align-items: center; justify-content: space-between; gap: 18px; flex-wrap: wrap; font-size: 13px; color: var(--text-3); }
.site-footer a { color: var(--text-3); margin-left: 18px; }
.site-footer a:hover { color: var(--primary); }

/* 登录 / 注册 */
/* ---- 登录 / 注册 ---------------------------------------------------------- */
.auth {
  min-height: 100vh;
  display: grid; grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
  background: var(--bg);
}

/* 左栏：品牌展示。内容是「上 logo / 中卖点 / 下数据条」的三段结构，
   中间那段用 flex:1 + 居中把大片空白吃掉 —— 纯渐变铺满而没有内容，
   是之前最大的观感问题。 */
.auth-brand {
  position: relative; overflow: hidden;
  padding: 40px 56px;
  display: flex; color: #fff;
  background: var(--grad);
}
/* 细网格纹理 + 右上光晕，让渐变有层次而不是一块死色 */
.auth-brand::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(255, 255, 255, .075) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .075) 1px, transparent 1px);
  background-size: 46px 46px;
  -webkit-mask-image: radial-gradient(ellipse 80% 64% at 26% 32%, #000 18%, transparent 74%);
  mask-image: radial-gradient(ellipse 80% 64% at 26% 32%, #000 18%, transparent 74%);
}
.auth-brand::after {
  content: ''; position: absolute; right: -200px; top: -190px;
  width: 420px; height: 420px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, rgba(255, 255, 255, .16), transparent 62%);
}
.ab-inner {
  position: relative; z-index: 1; flex: 1;
  display: flex; flex-direction: column; gap: 30px;
}
.ab-logo { display: flex; align-items: center; gap: 10px; }
.ab-logo img {
  width: 34px; height: 34px; border-radius: var(--r-md); padding: 3px;
  background: rgba(255, 255, 255, .18); box-shadow: 0 1px 0 rgba(255, 255, 255, .2) inset;
}
.ab-logo b { font-size: 16px; font-weight: 650; letter-spacing: -.01em; }

.ab-main { flex: 1; display: flex; flex-direction: column; justify-content: center; max-width: 452px; }
.ab-badge {
  display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
  padding: 5px 12px; border-radius: var(--r-full); font-size: 12px; font-weight: 500;
  background: rgba(255, 255, 255, .15); border: 1px solid rgba(255, 255, 255, .22);
}
.ab-badge svg { width: 13px; height: 13px; }
.ab-title { margin-top: 18px; font-size: 33px; font-weight: 700; letter-spacing: -.035em; line-height: 1.26; }
.ab-title .hl {
  background: linear-gradient(96deg, #fff 10%, #ffe6a6 92%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.ab-lead { margin-top: 14px; font-size: 13.8px; line-height: 1.85; color: rgba(255, 255, 255, .82); }
.ab-lead code {
  padding: 1px 5px; border-radius: var(--r-xs); font-family: var(--mono); font-size: 12.5px;
  background: rgba(255, 255, 255, .15);
}
.ab-points { margin-top: 24px; display: flex; flex-direction: column; gap: 11px; list-style: none; }
.ab-points li { display: flex; align-items: center; gap: 11px; font-size: 13.5px; color: rgba(255, 255, 255, .94); }
.ab-points .pi {
  width: 26px; height: 26px; flex: 0 0 26px; border-radius: var(--r-sm);
  display: grid; place-items: center;
  background: rgba(255, 255, 255, .17); border: 1px solid rgba(255, 255, 255, .2);
}
.ab-points .pi svg { width: 14px; height: 14px; }

/* 底部实时数据条：把原本空着的地方变成有用的信息 */
.ab-stats {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px;
  background: rgba(255, 255, 255, .18);
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: var(--r-lg); overflow: hidden;
}
.ab-stat { padding: 14px 16px; background: rgba(255, 255, 255, .07); }
.ab-stat b {
  display: block; font-family: var(--mono);
  font-size: 19px; font-weight: 650; letter-spacing: -.02em;
}
.ab-stat span { display: block; margin-top: 3px; font-size: 11.5px; color: rgba(255, 255, 255, .72); }
.ab-copy { font-size: 12px; color: rgba(255, 255, 255, .58); }

/* 宽屏下左栏钉在视口里：注册表单较高时页面要滚动，
   品牌区跟着滚会在底部露出发白的一截。 */
@media (min-width: 1001px) {
  .auth-brand { position: sticky; top: 0; height: 100vh; align-self: start; }
}

/* 右栏：表单卡片 */
.auth-panel { display: grid; place-items: center; padding: 40px 24px; }
.auth-card {
  width: 100%; max-width: 430px;
  padding: 30px 32px 26px;
  background: var(--card);
  border: 1px solid var(--border); border-radius: var(--r-xl);
  box-shadow: var(--shadow-2);
}
/* logo 只在窄屏显示（宽屏时左栏已经有了，重复出现反而多余） */
.ac-logo { display: none; }
.ac-head { text-align: center; }
.ac-head h1 { font-size: 22px; font-weight: 700; letter-spacing: -.025em; }
.ac-head p { margin-top: 7px; font-size: 13px; color: var(--text-3); }

/* 登录 / 注册切换：同页切换，不再跳来跳去 */
.ac-tabs {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 3px; padding: 3px; margin: 20px 0 20px;
  background: var(--card-3); border-radius: var(--r-md);
}
.ac-tab {
  padding: 9px; border: 0; border-radius: var(--r-sm); cursor: pointer;
  font-family: inherit; font-size: 13.5px; font-weight: 550;
  color: var(--text-3); background: transparent;
  transition: color var(--t), background var(--t), box-shadow var(--t);
}
.ac-tab:hover { color: var(--text); }
.ac-tab.on { color: var(--primary); background: var(--card); box-shadow: var(--shadow-1); }

/* 表单项：标签在上，输入框带左图标 */
.afield { display: block; margin-bottom: 14px; }
.afield > .lb {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-bottom: 7px; font-size: 12.5px; font-weight: 550; color: var(--text-2);
}
.afield > .lb .opt { font-weight: 400; color: var(--text-4); }
.afield .ibox { position: relative; display: flex; align-items: center; }
.afield .ibox > .ic {
  position: absolute; left: 13px; display: grid; place-items: center;
  color: var(--text-4); pointer-events: none;
  transition: color var(--t);
}
.afield .ibox:focus-within > .ic { color: var(--primary); }
/* 左内边距要明显大于「图标起点 + 图标宽」：图标与占位文字同为浅灰，
   间距不够时两者会糊成一团，看着像文字被图标压住。
   注意选择器必须带上 .auth-card / .rst-modal —— 768 断点里有一条同权重的
   `input:not(...) { padding: 10px 12px }`（iOS 防缩放），它在文件更后面，不加前缀会被它覆盖。
   ⚠️ .rst-modal 这条不能省：忘记密码弹窗是 append 到 <body> 上的，
   不在 .auth-card 里面，漏掉它输入框就拿不到 padding-left，
   绝对定位的邮件图标会直接盖在「你注册时填写的邮箱」这行字上。 */
.auth-card .afield .ibox > input,
.rst-modal .afield .ibox > input { height: 42px; padding-left: 42px; font-size: 14px; }
.afield .ibox.has-tail > input { padding-right: 42px; }
.afield .ibox > .tail {
  position: absolute; right: 6px; width: 30px; height: 30px;
  display: grid; place-items: center;
  border: 0; border-radius: var(--r-sm); background: transparent;
  color: var(--text-4); cursor: pointer;
  transition: color var(--t), background var(--t);
}
.afield .ibox > .tail:hover { color: var(--text-2); background: var(--hover); }
.afield .hint { margin-top: 6px; }
/* 验证码行内的输入框跟随 .afield 的高度节奏 */
.afield .cap-row > input,
.afield .code-row > input { height: 42px; font-size: 14px; }
.afield .cap-img { border-radius: var(--r-md); }

.ac-submit {
  width: 100%; height: 45px; margin-top: 20px;
  border: 0; border-radius: var(--r-md); cursor: pointer;
  font-family: inherit; font-size: 14.5px; font-weight: 600; color: var(--on-primary);
  background: var(--grad);
  box-shadow: 0 6px 18px rgba(91, 91, 214, .26);
  transition: transform var(--t), box-shadow var(--t), opacity var(--t);
}
.ac-submit:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 9px 24px rgba(91, 91, 214, .34); }
.ac-submit:active:not(:disabled) { transform: translateY(0); box-shadow: 0 4px 12px rgba(91, 91, 214, .24); }
.ac-submit:disabled { opacity: .62; cursor: not-allowed; box-shadow: none; }

.ac-foot { margin-top: 18px; text-align: center; font-size: 13px; color: var(--text-3); }
.ac-foot a { color: var(--primary); font-weight: 500; cursor: pointer; }
.ac-foot a:hover { text-decoration: underline; }
.ac-legal {
  margin-top: 18px; padding-top: 15px; border-top: 1px solid var(--border-2);
  text-align: center; font-size: 11.5px; line-height: 1.75; color: var(--text-4);
}
.ac-legal b { font-weight: 550; color: var(--text-3); }

/* ============================================================================
   在线对话台 Playground
   ========================================================================== */
.pg { display: grid; grid-template-columns: 264px minmax(0, 1fr); gap: 16px; align-items: start; }
.pg-settings { position: sticky; top: 84px; }
.pg-model {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 11px 13px; border-radius: var(--r-md); cursor: pointer;
  border: 1px solid var(--border); background: var(--card-2);
}
.pg-item { padding: 8px 0; }
.pg-item > label { display: block; margin-bottom: 7px; font-size: 12.5px; font-weight: 550; color: var(--text-2); }
.pg-item .val { font-family: var(--mono); font-size: 12px; color: var(--primary); float: right; }

/* 高级参数折叠：桌面端永远展开（隐藏 summary 后点击无意义，内容始终显示）；
   移动端才变成可折叠，默认收起。 */
.pg-fold > summary { display: none; list-style: none; }
.pg-fold > summary::-webkit-details-marker { display: none; }
.pg-fold > .pg-fold-body { display: block; }
input[type=range] { width: 100%; accent-color: var(--primary); height: 20px; }

.pg-chat { display: flex; flex-direction: column; min-height: 620px; }
.pg-body {
  flex: 1; overflow-y: auto; padding: 20px;
  display: flex; flex-direction: column; gap: 18px;
  background: var(--card-2); min-height: 420px; max-height: calc(100vh - 320px);
}
.msg { display: flex; gap: 11px; }
.msg.me { flex-direction: row-reverse; }
.msg-av { width: 30px; height: 30px; flex: 0 0 30px; border-radius: var(--r-md); display: grid; place-items: center; }
.msg-av svg { width: 16px; height: 16px; }
.msg-wrap { min-width: 0; max-width: 78%; }
.msg-body {
  padding: 12px 15px; border-radius: var(--r-lg);
  font-size: 13.5px; line-height: 1.8; color: var(--text-2);
  background: var(--card); border: 1px solid var(--border);
  white-space: pre-wrap; word-break: break-word;
}
.msg.me .msg-body { color: #fff; background: var(--grad); border-color: transparent; }
.msg-meta { margin-top: 6px; font-size: 11.5px; color: var(--text-4); font-family: var(--mono); }
.msg.me .msg-meta { text-align: right; }
.thinking {
  margin-bottom: 10px; padding: 10px 13px; border-radius: var(--r-md);
  background: var(--card-3); border: 1px dashed var(--border-3);
  font-size: 12.5px; line-height: 1.75; color: var(--text-3);
}
.thinking b { display: block; margin-bottom: 5px; font-size: 11.5px; color: var(--text-2); }
.cursor-blink { display: inline-block; width: 7px; height: 14px; background: var(--primary); vertical-align: -2px; animation: blink 1s steps(2) infinite; }
@keyframes blink { 50% { opacity: 0 } }

.pg-input { padding: 14px 18px; border-top: 1px solid var(--border); background: var(--card); }
.pg-input textarea { min-height: 52px; max-height: 190px; border: 0; background: transparent; padding: 4px 0; font-size: 13.5px; }
.pg-input textarea:focus { box-shadow: none; }
.pg-tip { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 8px; font-size: 12px; color: var(--text-4); }
/* 每个提示项内部可能带图标，用 inline-flex 保证图标与文字同轴 */
.pg-tip > span { display: inline-flex; align-items: center; gap: 5px; }
.pg-tip svg { width: 13px; height: 13px; flex: 0 0 13px; }
.pg-tip kbd {
  padding: 1px 6px; border-radius: var(--r-xs);
  font-family: var(--mono); font-size: 11px; color: var(--text-2);
  background: var(--card-3); border: 1px solid var(--border);
}

/* ============================================================================
   HTTP 状态 / 服务状态点
   ========================================================================== */
.dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--text-4); vertical-align: 1px; }
.dot.on { background: var(--success); box-shadow: 0 0 0 3px var(--success-soft); }
.dot.off { background: var(--danger); box-shadow: 0 0 0 3px var(--danger-soft); }
.dot.warn { background: var(--warning); box-shadow: 0 0 0 3px var(--warning-soft); }

/* 服务状态灯 */
.uptime-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(9px, 1fr)); gap: 3px; }
.uptime-cell { height: 26px; border-radius: 3px; background: var(--success); opacity: .85; }
.uptime-cell.warn { background: var(--warning); }
.uptime-cell.down { background: var(--danger); }
.uptime-cell.idle { background: var(--card-3); }

/* 价格卡片 */
.price-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(288px, 1fr)); gap: 14px; }
.price-card {
  padding: 16px; border-radius: var(--r-lg); cursor: pointer;
  background: var(--card); border: 1px solid var(--border);
  transition: all var(--t);
}
.price-card:hover { border-color: var(--primary-line); box-shadow: var(--shadow-2); transform: translateY(-2px); }
.price-card-h { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 14px; }
.price-card-t { flex: 1; min-width: 0; }
.price-card-id { font-family: var(--mono); font-size: 12.5px; font-weight: 600; color: var(--text); word-break: break-all; }
.price-card-nm { margin-top: 3px; font-size: 12px; color: var(--text-3); }
.price-rows { display: flex; flex-direction: column; gap: 9px; }
.price-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.price-row .pl { font-size: 12.5px; color: var(--text-3); }
.price-row .pv { font-family: var(--mono); font-size: 13.5px; font-weight: 600; color: var(--text); }
.price-row.hl .pv { color: var(--primary); }

/* 筛选侧栏 */
.filter-side { display: flex; flex-direction: column; gap: 18px; }
.filter-block > .fb-t { margin-bottom: 9px; font-size: 12.5px; font-weight: 600; color: var(--text-2); }
.filter-opts { display: flex; flex-wrap: wrap; gap: 6px; }
.opt {
  padding: 5px 11px; border-radius: var(--r-full); cursor: pointer;
  font-size: 12.5px; color: var(--text-2); background: var(--card-3); border: 1px solid transparent;
  transition: all var(--t);
}
.opt:hover { color: var(--primary); }
.opt.on { color: var(--primary); background: var(--primary-soft); border-color: var(--primary-line); font-weight: 550; }

/* ============================================================================
   发信防轰炸面板（后台 · 系统设置）
   ---------------------------------------------------------------------------
   这是一块「安全控制台」，视觉上要和普通设置项区分开：默认带一层暖色底，
   数字用等宽字体对齐，出问题时整块转成警示色。
   ========================================================================== */
.mail-guard {
  margin-top: 16px; padding: 16px;
  border: 1px solid var(--border-3); border-radius: var(--r-md);
  background: var(--warning-soft);
}
.mg-head { display: flex; align-items: flex-start; gap: 10px; }
.mg-ico {
  width: 30px; height: 30px; flex: 0 0 30px; border-radius: var(--r-sm);
  display: grid; place-items: center;
  background: var(--warning-soft); color: var(--warning);
  border: 1px solid var(--border-3);
}
.mg-head b { font-size: 13.5px; color: var(--text); }
.mg-head .hint { margin-top: 4px; }
.mg-head .hint strong { color: var(--danger); font-weight: 600; }

.mg-stats {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px; margin-top: 14px;
  background: var(--border-3); border: 1px solid var(--border-3);
  border-radius: var(--r-sm); overflow: hidden;
}
.mg-stat { background: var(--card); padding: 10px 12px; }
.mg-stat .k { font-size: 11.5px; color: var(--text-3); }
.mg-stat .v {
  margin-top: 4px; font-family: var(--mono);
  font-size: 17px; font-weight: 600; color: var(--text);
}
.mg-stat .v .u { font-size: 11.5px; font-weight: 400; color: var(--text-4); }
.mg-stat .v.t-ok { color: var(--success); }
.mg-stat .v.t-warn { color: var(--warning); }
.mg-stat .v.t-err { color: var(--danger); }

.mg-bar { height: 4px; margin-top: 8px; border-radius: var(--r-full); background: var(--border-3); overflow: hidden; }
.mg-bar > i { display: block; height: 100%; border-radius: var(--r-full); transition: width .3s; }
.mg-bar > i.b-ok { background: var(--success); }
.mg-bar > i.b-warn { background: var(--warning); }
.mg-bar > i.b-err { background: var(--danger); }

.mg-alert {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 12px; padding: 10px 12px; border-radius: var(--r-sm);
  font-size: 12.5px; line-height: 1.7;
  background: var(--danger-soft); color: var(--danger);
  border: 1px solid var(--border-3);
}
.mg-alert svg { flex: 0 0 auto; }
.mg-alert > span { flex: 1 1 240px; }
.mg-alert.danger { font-weight: 500; }

.mg-kill {
  margin-top: 14px; padding: 11px 12px;
  background: var(--card); border: 1px solid var(--border-3); border-radius: var(--r-sm);
}

.mg-adv { margin-top: 12px; }
.mg-adv > summary {
  cursor: pointer; font-size: 12.5px; font-weight: 550; color: var(--text-2);
  padding: 6px 0; list-style: none;
}
.mg-adv > summary::-webkit-details-marker { display: none; }
.mg-adv > summary::before { content: '▸ '; color: var(--text-4); }
.mg-adv[open] > summary::before { content: '▾ '; }

/* ============================================================================
   响应式
   ========================================================================== */
@media (max-width: 1240px) {
  .kpis, .kpis.g5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hero .container { grid-template-columns: 1fr; gap: 36px; }
  .features { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 1080px) {
  .pg { grid-template-columns: 1fr; }
  .pg-settings { position: static; }
  /* 登录页在 1080 仍是两栏，只是收窄左栏；到 1000 才转单栏 */
  .auth { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .auth-brand { padding: 34px 36px; }
  .ab-title { font-size: 28px; }
  .ab-lead { font-size: 13px; }
}
@media (max-width: 1000px) {
  :root { --rail: 68px; }
  /* 登录页转单栏：品牌区整块收起，logo 移到卡片里（否则窄屏上
     一条只有 logo 的渐变头既占高度又没内容） */
  .auth { grid-template-columns: 1fr; }
  .auth-brand { display: none; }
  .ac-logo {
    display: flex; align-items: center; justify-content: center; gap: 9px;
    margin-bottom: 18px;
  }
  .ac-logo img { width: 32px; height: 32px; }
  .ac-logo b { font-size: 15.5px; font-weight: 650; }
  .auth-panel { place-items: start center; padding: 28px 16px 44px; }
  .auth-card { padding: 24px 20px 22px; max-width: 440px; }
  /* 手机上 16px 字号更大，内边距同步放大，避免糊在一起。
     带 .auth-card / .rst-modal 才压得住上面的主规则（两者同权重，靠文件顺序决胜负不可靠）。 */
  .auth-card .afield .ibox > input,
  .rst-modal .afield .ibox > input { height: 46px; font-size: 16px; padding-left: 45px; }
  .afield .cap-row > input,
  .afield .code-row > input { height: 46px; font-size: 16px; }
  .ac-submit { height: 48px; }
  .sidebar { padding: 14px 9px; }
  .sb-brand { justify-content: center; padding: 4px 0 14px; }
  .sb-name, .sb-group { display: none; }
  .sb-item { justify-content: center; padding: 10px 0; }
  .sb-item > span:not(.sb-badge) { display: none; }
  .sb-item .sb-badge { position: absolute; top: 2px; right: 4px; margin: 0; padding: 0 4px; font-size: 9px; }
  .page { padding: 18px 16px 50px; }
  .topbar { padding: 12px 16px; }
}
@media (max-width: 860px) {
  .site-header .inner { height: 56px; gap: 14px; }
  .nav-links { display: none; }
  .hero { padding: 40px 0 34px; }
  .hero h1 { font-size: 30px; }
  .hero p.lead { font-size: 14px; }
  .section { padding: 40px 0; }
  .sec-head h2 { font-size: 22px; }
  .features { grid-template-columns: 1fr; }
  .stats-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .container { padding: 0 16px; }
  .kpis, .kpis.g3, .kpis.g5 { grid-template-columns: 1fr; }
  .msg-wrap { max-width: 100%; }
  .toasts { right: 12px; left: 12px; bottom: 12px; }
  .toast { max-width: none; }
}
/* ============================================================================
   移动端（<=768px）
   设计原则：
   1. 导航必须始终可达 —— 之前把 .nav-links 整个 display:none 且没有替代入口，
      手机上根本进不去「模型价格 / 接入文档 / 常见问题」。现在改为汉堡 + 抽屉，
      控制台则用底部 tab bar + 抽屉。
   2. 输入框字号必须 >=16px —— 低于 16px 时 iOS 聚焦输入框会自动放大整个页面，
      是「手机上很难用」的主要来源之一。
   3. 触控目标 >=42px，留白按手机节奏重排，不再沿用桌面的 60px section。
   4. 表格改为卡片：靠渲染后自动补的 data-label 把表头显示成行标签。
   ========================================================================== */

/* 默认隐藏所有「仅移动端」元素，桌面端不受任何影响 */
.hd-menu-btn,
.m-drawer,
.tabbar { display: none; }

@media (max-width: 768px) {
  :root { --tabbar: 58px; }

  /* ---------- 基础：字号、触控、滚动 ---------- */
  html { -webkit-text-size-adjust: 100%; }
  body { overscroll-behavior-y: none; }

  input:not([type=checkbox]):not([type=radio]), select, textarea {
    font-size: 16px;            /* 关键：<16px 会触发 iOS 聚焦自动缩放 */
    padding: 10px 12px;
  }
  .btn { min-height: 42px; }
  .btn-sm { min-height: 36px; }
  .btn-lg { min-height: 48px; font-size: 15px; }

  /* 横向滚动容器加上惯性滚动 */
  .tbl-wrap, .code-tabs, .filter-opts { -webkit-overflow-scrolling: touch; }

  /* 发信防轰炸面板：4 格统计在手机上排两行 */
  .mg-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mail-guard { padding: 13px; }
  .mg-alert { align-items: flex-start; }
  .mg-alert > .btn { width: 100%; }

  /* ==========================================================================
     公开站：顶栏汉堡 + 纵向抽屉
     ========================================================================== */
  .site-header .inner { height: 58px; padding: 0 16px; gap: 10px; }
  .site-header .logo b { font-size: 15.5px; }
  .nav-links { display: none; }
  .hd-right { gap: 8px; }

  /* 顶栏右侧在手机上只留最重要的：主要动作 + 汉堡。
     次要动作（如「深色」切换）收进抽屉，避免顶栏挤成一团。 */
  .hd-right .btn-ghost { display: none; }
  .hd-hide-sm { display: none !important; }
  .hd-menu-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; flex: 0 0 40px;
    border: 1px solid var(--border); border-radius: var(--r-md);
    background: var(--card); color: var(--text);
  }
  .hd-menu-btn svg { width: 19px; height: 19px; }

  /* 抽屉 */
  .m-drawer {
    display: block; position: fixed; inset: 0; z-index: 90;
  }
  .m-drawer[hidden] { display: none; }
  .m-drawer-mask {
    position: absolute; inset: 0;
    background: rgba(12, 16, 28, .45);
    animation: mFade .18s ease;
  }
  .m-drawer-panel {
    position: absolute; top: 0; right: 0; bottom: 0;
    width: min(84vw, 340px);
    display: flex; flex-direction: column;
    background: var(--card); box-shadow: -8px 0 32px rgba(12, 16, 28, .18);
    animation: mSlide .22s cubic-bezier(.32, .72, .32, 1);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  @keyframes mFade { from { opacity: 0 } to { opacity: 1 } }
  @keyframes mSlide { from { transform: translateX(100%) } to { transform: translateX(0) } }

  .m-drawer-head {
    display: flex; align-items: center; gap: 10px;
    padding: 16px; border-bottom: 1px solid var(--border-2);
  }
  .m-drawer-head img { width: 30px; height: 30px; object-fit: contain; }
  .m-drawer-head b { font-size: 15px; font-weight: 650; }
  .m-drawer-head .x {
    margin-left: auto; width: 38px; height: 38px; flex: 0 0 38px;
    display: grid; place-items: center; border: 0; border-radius: var(--r-md);
    background: var(--card-3); color: var(--text-2); cursor: pointer;
  }
  .m-drawer-head .x svg { width: 18px; height: 18px; }
  .m-drawer-body { flex: 1; overflow-y: auto; padding: 10px 12px 16px; }
  .m-drawer-sec {
    padding: 14px 8px 6px; font-size: 11px; font-weight: 600;
    letter-spacing: .05em; color: var(--text-4); text-transform: uppercase;
  }
  .m-item {
    display: flex; align-items: center; gap: 12px; width: 100%;
    padding: 13px 12px; border: 0; border-radius: var(--r-md);
    background: transparent; color: var(--text); text-align: left;
    font-size: 15px; font-weight: 500; cursor: pointer;
  }
  .m-item svg { width: 19px; height: 19px; flex: 0 0 19px; color: var(--text-3); }
  .m-item.on { background: var(--primary-soft); color: var(--primary); font-weight: 600; }
  .m-item.on svg { color: var(--primary); }
  .m-item .arw { margin-left: auto; color: var(--text-4); }
  .m-item .arw svg { width: 16px; height: 16px; }
  .m-drawer-foot {
    padding: 12px 12px calc(14px + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--border-2); display: flex; flex-direction: column; gap: 8px;
  }
  .m-drawer-foot .btn { width: 100%; }

  /* ==========================================================================
     公开站：首屏与各区块
     ========================================================================== */
  .hero { padding: 30px 0 30px; }
  .hero h1 { font-size: 26px; margin-top: 14px; letter-spacing: -.02em; }
  .hero p.lead { font-size: 14px; line-height: 1.8; margin-top: 12px; }
  .hero-badge { font-size: 11.5px; padding: 4px 11px; }

  /* 按钮组：手机上改为一列全宽。
     之前是 flex-wrap，三个按钮排成 2+1，第二行只有一个且宽度不齐 —— 看着"脏"。 */
  .hero-actions { flex-direction: column; align-items: stretch; gap: 9px; margin-top: 22px; }
  .hero-actions .btn { width: 100%; justify-content: center; }

  /* 三个卖点：竖排成清单，而不是 wrap 成 2+1 行的歪块 */
  .hero-note { flex-direction: column; align-items: flex-start; gap: 9px; margin-top: 18px; font-size: 12.5px; }

  .hero-card-b { padding: 12px; }
  .bubble { max-width: 92%; font-size: 12.5px; padding: 8px 11px; }

  .section { padding: 36px 0; }
  .sec-head h2 { font-size: 21px; }
  .sec-head p { font-size: 13.5px; }
  .container { padding: 0 16px; }

  .stats-row { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .stat-item { padding: 14px 10px; }
  .stat-item b { font-size: 21px; }
  .stat-item span { font-size: 11.5px; }

  /* 价格 / 特点 / CTA */
  .price-grid { grid-template-columns: 1fr; gap: 10px; }
  .features { grid-template-columns: 1fr; gap: 12px; }
  .feat { padding: 14px; }
  .cta { padding: 34px 20px; }
  .cta h2 { font-size: 21px; }
  .cta .btn { width: 100%; }
  .faq-q { padding: 14px 0; font-size: 14px; }
  .faq-a { font-size: 13.5px; padding-bottom: 14px; }
  .site-footer { padding: 26px 0; font-size: 12.5px; }

  /* 登录 / 注册：卡片贴边、内边距收紧 */
  .auth-panel { padding: 20px 14px 40px; }
  .auth-card { padding: 22px 18px 20px; }
  .ac-head h1 { font-size: 20px; }
  .ac-tabs { margin: 18px 0; }
  .code-row { gap: 7px; }
  .code-row > .btn { min-width: 104px; }
  /* 窄屏下给输入框留够宽度：4 个等宽字符 + 字距至少需要 ~90px */
  .cap-row { gap: 7px; }
  .cap-img { width: 108px; }

  /* ==========================================================================
     控制台：隐藏侧栏，改底部 tab bar + 抽屉
     ========================================================================== */
  .shell { display: block; }
  .sidebar { display: none; }

  .main { display: block; }
  .topbar {
    padding: 10px 14px; gap: 10px;
    position: sticky; top: 0;
  }
  .tb-title { font-size: 16px; }
  .tb-sub { font-size: 11.5px; }
  /* 顶栏里的次要按钮（站点首页 / 管理后台）收进抽屉，只留头像菜单 */
  .tb-right > .btn:not(.m-keep) { display: none; }

  .page {
    padding: 14px 14px calc(var(--tabbar) + 22px + env(safe-area-inset-bottom, 0px));
  }

  /* 底部 tab bar */
  .tabbar {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    padding-bottom: env(safe-area-inset-bottom, 0px);
    background: color-mix(in srgb, var(--card) 92%, transparent);
    backdrop-filter: saturate(1.6) blur(14px);
    -webkit-backdrop-filter: saturate(1.6) blur(14px);
    border-top: 1px solid var(--border);
  }
  .tabbar-item {
    flex: 1; min-width: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
    height: var(--tabbar); padding: 0 2px;
    border: 0; background: transparent; cursor: pointer;
    color: var(--text-3); font-size: 10.5px; font-weight: 550;
  }
  .tabbar-item svg { width: 21px; height: 21px; }
  .tabbar-item.on { color: var(--primary); }
  .tabbar-item[disabled] { opacity: .4; }

  /* ==========================================================================
     控制台内容：卡片、KPI、表单、表格
     ========================================================================== */
  .kpis, .kpis.g3, .kpis.g2, .kpis.g5 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .kpi { padding: 13px; }
  /* 卡片里的操作按钮组：手机上两列均分；奇数个时最后一个跨两列。
     之前是 flex-wrap，3 个按钮会排成 2+1 且两行宽度不一致，看着很乱。 */
  .act-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .act-row > .btn { width: 100%; }
  .act-row > .btn:last-child:nth-child(odd) { grid-column: 1 / -1; }

  /* 「头像/信息 + 右侧按钮」这种横排头，手机上必须竖排 ——
     否则中间那段文字会被两侧挤成极窄的一条，逐字换行（个人中心资料头就是这么崩的）。 */
  .m-stack { flex-direction: column; align-items: flex-start; gap: 12px; }
  .m-stack > .grow { width: 100%; }
  .m-stack > .row { width: 100%; }
  .m-stack > .row > .btn { flex: 1; }
  .kpi-ico { width: 30px; height: 30px; flex: 0 0 30px; }
  .kpi-ico svg { width: 16px; height: 16px; }
  .kpi-val { font-size: 18px; margin-top: 9px; overflow-wrap: anywhere; }
  .kpi-label { font-size: 11.5px; }

  .card { border-radius: var(--r-md); }
  .card-b { padding: 14px; }
  .card-h { padding: 13px 14px; gap: 9px; }
  .card-t { font-size: 14.5px; }
  .card-d { font-size: 12px; }
  .card-hico { width: 28px; height: 28px; flex: 0 0 28px; }
  .card-hico svg { width: 15px; height: 15px; }
  /* 卡片头右侧的操作区在手机上整行铺开，宽度一致才不显乱 */
  .card-h { flex-wrap: wrap; }
  .card-h .sp { width: 100%; margin-left: 0; flex-direction: column; align-items: stretch; }
  .card-h .sp > input, .card-h .sp > select { width: 100% !important; flex: none; min-width: 0; }
  .card-h .sp > .btn { width: 100%; }
  /* 分段控件（卡片/表格、消费/Token）撑满一行，两个选项各占一半 */
  .card-h .sp > .seg { width: 100%; }
  .card-h .sp > .seg > button { flex: 1; }

  /* 表单：单列 + 按钮撑满 */
  .form-grid { grid-template-columns: 1fr; gap: 12px; }
  .row-t { flex-direction: column; }
  .row-t > .card { flex: 1 1 auto !important; min-width: 0 !important; width: 100%; }

  /* 公开站「模型与价格」页的筛选侧栏。桌面上它在左列 sticky，手机上必须解除，
     否则两个问题叠在一起：
       ① .row-t 变 column 后，行内写的 flex:0 0 216px 语义从「宽度」变成「高度基线」，
          侧栏凭空占掉 216px 高；
       ② position:sticky;top:84px 让它一直贴在顶栏下面，滚动时把模型卡整片盖住
          —— 用户看到的「滑到底下被卡住/挡住」就是它。
     改法：脱离 sticky、宽度撑满、高度自适应；厂商 chips 十几个，改成横向滚动一行。 */
  .filter-side {
    position: static !important; flex: none !important;
    width: 100% !important; height: auto !important;
    gap: 11px !important;
    padding: 12px 13px;
    border: 1px solid var(--border); border-radius: var(--r-md);
    background: var(--card-3);
  }
  .filter-side .filter-opts {
    flex-wrap: nowrap; overflow-x: auto; padding-bottom: 2px;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
  }
  .filter-side .filter-opts::-webkit-scrollbar { display: none; }
  .filter-side .filter-opts > .opt { flex: 0 0 auto; }
  .filter-side #fPriceQ { width: 100%; }

  /* 日志/流水页的筛选条：固定宽度在手机上会挤成参差的几行。
     改成两列网格：搜索框与状态下拉各占整行，日期区间并排。 */
  .filter-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .filter-row > input, .filter-row > select { width: 100% !important; min-width: 0; }
  .filter-row > input:first-child,
  .filter-row > select { grid-column: 1 / -1; }
  .filter-row > .muted { display: none; }   /* 「至」在竖排下没有意义 */
  .filter-row > .btn { width: 100%; }

  /* 表格 → 卡片（data-label 由脚本按表头自动补上） */
  .tbl-wrap { overflow: visible; }
  .tbl-wrap table, .tbl-wrap thead, .tbl-wrap tbody, .tbl-wrap tr, .tbl-wrap td { display: block; }
  .tbl-wrap thead { display: none; }
  .tbl-wrap table { border-spacing: 0; }
  .tbl-wrap tbody tr {
    margin-bottom: 10px; padding: 4px 0;
    border: 1px solid var(--border); border-radius: var(--r-md);
    background: var(--card);
  }
  .tbl-wrap tbody tr:last-child { margin-bottom: 0; }
  .tbl-wrap tbody td {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    padding: 8px 13px; border: 0; text-align: right;
    white-space: normal; word-break: break-word;
  }
  .tbl-wrap tbody td::before {
    content: attr(data-label);
    flex: 0 0 auto; font-size: 12px; font-weight: 550;
    color: var(--text-3); text-align: left;
  }
  .tbl-wrap tbody td:not([data-label])::before { content: none; }
  /* 第一列当标题：单独一行、左对齐、加一条分隔 */
  .tbl-wrap tbody td[data-label]:first-child {
    justify-content: flex-start; padding-bottom: 10px;
    border-bottom: 1px solid var(--border-2);
    font-size: 14.5px; font-weight: 600;
  }
  .tbl-wrap tbody td[data-label]:first-child::before { content: none; }
  .tbl-wrap tbody td .mono { font-size: 12px; }

  /* 令牌卡：操作按钮铺满一行 */
  .key-card { gap: 11px; padding: 13px 14px; }
  .key-acts { width: 100%; }
  .key-acts .btn { flex: 1; }

  /* 分页、抽屉、弹窗 */
  .pager { gap: 10px; padding: 12px 14px; }
  .pager .btn { min-width: 82px; }
  .drawer { width: 100vw; }
  .modal { max-width: 100%; margin: 0 12px; max-height: 84vh; }
  .modal-foot { flex-direction: column-reverse; }
  .modal-foot .btn { width: 100%; }

  /* 图表在手机上变矮，避免占满整屏 */
  .chart svg { height: 150px !important; }

  /* ==========================================================================
     AI 工作台：手机上先给对话，参数收进折叠
     ========================================================================== */
  .pg { display: flex; flex-direction: column; }
  .pg-chat { order: 1; min-height: auto; }
  .pg-settings { order: 2; position: static; }

  .pg-fold { margin-top: 12px; border-top: 1px solid var(--border-2); }
  .pg-fold > summary {
    display: flex; align-items: center; gap: 8px;
    padding: 13px 0; cursor: pointer; list-style: none;
    font-size: 13.5px; font-weight: 600; color: var(--text);
  }
  .pg-fold > summary::after {
    content: ""; margin-left: auto; width: 7px; height: 7px;
    border-right: 2px solid var(--text-3); border-bottom: 2px solid var(--text-3);
    transform: rotate(45deg); transition: transform var(--t);
  }
  .pg-fold[open] > summary::after { transform: rotate(-135deg); }
  .pg-fold:not([open]) > .pg-fold-body { display: none; }
  .pg-fold[open] > .pg-fold-body { display: block; padding-bottom: 6px; }

  .pg-body { min-height: 300px; max-height: 54vh; padding: 14px; gap: 14px; }
  .msg-wrap { max-width: 88%; }
  .msg-body { font-size: 13px; padding: 10px 13px; }
  .pg-input { padding: 12px 14px; }
  .pg-input textarea, .pg-input input { font-size: 16px; }   /* 防 iOS 聚焦缩放 */
  .pg-input .row.between { gap: 10px; }
  .pg-input .row > .row { width: 100%; }
  .pg-input .row > .row .btn { flex: 1; }
  /* 手机上没有物理 Enter/Shift，前两条键盘提示没意义，只留计费说明 */
  .pg-tip > span:nth-child(-n+2) { display: none; }

  /* 代码块横向滚动而不是撑破 */
  .code, .code-block { font-size: 12px; }
  .code-block { padding: 12px; }

  .toasts { right: 12px; left: 12px; bottom: calc(var(--tabbar) + 12px + env(safe-area-inset-bottom, 0px)); }
  .toast { max-width: none; }
}



/* ============================================================ AI 工作台 ============================================================ */
.ag { display: grid; grid-template-columns: 300px minmax(0, 1fr); gap: 16px; align-items: start; }
.ag-side { position: sticky; top: 84px; display: flex; flex-direction: column; gap: 16px; }

/* 侧栏：隔离便签 / 上传区 / 文件列表 */
.ag-note {
  margin-top: 12px; padding: 9px 12px; border-radius: var(--r-md);
  background: var(--grad-soft); border: 1px solid var(--primary-line);
  font-size: 12px; line-height: 1.65; color: var(--primary);
}
.ag-upzone .btn {
  width: 100%; justify-content: center;
  border: 1.5px dashed var(--primary-line); background: var(--primary-soft); color: var(--primary);
}
.ag-upzone .btn:hover { background: var(--primary-line); }
.ag-files { max-height: 320px; overflow-y: auto; }
.ag-file { display: block; padding: 8px 10px; border-radius: var(--r-md); transition: background var(--t); }
.ag-file:hover { background: var(--hover); }
.ag-file-name { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text); }
.ag-file-dot { width: 8px; height: 8px; border-radius: 3px; background: var(--primary); flex: none; opacity: .9; }
.ag-file-dot.bin { background: var(--warning); }
.ag-file-name .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ag-file-meta { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; margin: 6px 0 0 16px; }
.ag-file-meta .sz { font-size: 11.5px; color: var(--text-4); margin-right: auto; }
.ag-file-meta .btn { padding: 2px 8px; font-size: 11.5px; line-height: 1.5; }

/* 聊天画布 */
.ag-chat { display: flex; flex-direction: column; min-height: 560px; overflow: hidden; transition: box-shadow var(--t); }
.ag-chat.drag { box-shadow: var(--ring); }
.ag-body {
  flex: 1; overflow-y: auto; padding: 20px 20px 14px;
  display: flex; flex-direction: column; gap: 14px;
  background:
    radial-gradient(900px 320px at 88% -60px, rgba(139, 92, 246, .06), transparent 60%),
    var(--card-2);
  min-height: 380px; max-height: calc(100vh - 336px);
  scrollbar-width: thin;
}

.ag-body > * { flex: none; } /* 禁止收缩：内容超高时滚动，别把折叠块压扁（曾缩到 2px） *//* 消息行：头像 + 气泡 */
.ag-row { display: flex; gap: 10px; align-items: flex-end; }
.ag-row.me { justify-content: flex-end; }
.ag-ava {
  width: 30px; height: 30px; border-radius: 10px; flex: none;
  background: var(--grad); color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 10px rgba(124, 92, 246, .32);
}
.msg-wrap { min-width: 0; max-width: 82%; }
.msg-bubble { padding: 10px 14px; font-size: 13.5px; line-height: 1.7; word-break: break-word; }
.ag-assistant {
  background: var(--card); border: 1px solid var(--border);
  border-radius: 4px 14px 14px 14px; box-shadow: var(--shadow-1);
}
.ag-user {
  background: var(--grad); color: #fff;
  border-radius: 14px 4px 14px 14px; box-shadow: 0 6px 16px rgba(124, 92, 246, .28);
}
.ag-user a { color: #fff; text-decoration: underline; }
.ag-err { border-color: var(--danger); background: var(--danger-soft); }

/* 打字中 */
.ag-typing { display: inline-flex; align-items: center; gap: 9px; color: var(--text-3); }
.dots { display: inline-flex; gap: 3.5px; }
.dots i { width: 5px; height: 5px; border-radius: 50%; background: var(--primary); opacity: .35; animation: agdot 1.2s infinite; }
.dots i:nth-child(2) { animation-delay: .18s; }
.dots i:nth-child(3) { animation-delay: .36s; }
@keyframes agdot { 0%, 60%, 100% { transform: none; opacity: .35; } 30% { transform: translateY(-4px); opacity: 1; } }

/* 代码面板：深色，浅色主题下同样成立 */
.ag-code, .ag-out {
  margin: 8px 0 2px; padding: 11px 13px; border-radius: 10px;
  background: #141826; color: #d6ddfb; border: 1px solid rgba(255, 255, 255, .07);
  font-family: var(--mono); font-size: 12px; line-height: 1.7;
  overflow-x: auto; white-space: pre-wrap; word-break: break-word;
}
.ag-out { color: #a9e5c4; }

/* 行内元素（粗体/行内码/列表/标题/引用） */
.ag-inline { background: var(--primary-soft); color: var(--primary); border-radius: 6px; padding: 1.5px 6px; font-size: .9em; font-family: var(--mono); }
.ag-li { display: block; padding-left: 15px; position: relative; }
.ag-li::before { content: ''; position: absolute; left: 3px; top: .66em; width: 5px; height: 5px; border-radius: 50%; background: var(--primary); }
.ag-li.ag-olin { padding-left: 2px; }
.ag-li.ag-olin::before { display: none; }
.ag-h { display: block; font-size: 14px; font-weight: 650; margin: 10px 0 2px; color: var(--text); }
.ag-quote {
  display: block; margin: 6px 0; padding: 7px 12px;
  border-left: 3px solid var(--primary); background: var(--primary-soft);
  border-radius: 0 8px 8px 0; color: var(--text-2);
}

/* 思考块 / 工具块 */
.ag-think, .ag-tool {
  margin-left: 40px; border: 1px solid var(--border); border-radius: 12px;
  background: var(--card); font-size: 12.5px; overflow: hidden;
}
.ag-think { background: linear-gradient(135deg, rgba(139, 92, 246, .06), rgba(99, 102, 241, .05)); }
.ag-think summary, .ag-tool summary {
  cursor: pointer; padding: 9px 12px; display: flex; align-items: center; gap: 8px;
  color: var(--text-2); user-select: none; list-style: none; font-weight: 550;
}
.ag-think summary::-webkit-details-marker, .ag-tool summary::-webkit-details-marker { display: none; }
.ag-think[open] summary, .ag-tool[open] summary { border-bottom: 1px solid var(--border-2); }
.ag-think-body {
  margin: 0; padding: 11px 14px; max-height: 240px; overflow-y: auto;
  color: var(--text-3); font-size: 12px; line-height: 1.75;
  white-space: pre-wrap; word-break: break-word;
}
.ag-tico {
  width: 22px; height: 22px; border-radius: 7px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--cyan-soft); color: var(--cyan);
}
.ag-tico.vio { background: rgba(139, 92, 246, .15); color: #8b5cf6; }
.ag-tname { font-size: 12px; color: var(--text); }
.ag-tstat {
  margin-left: auto; font-size: 11px; color: var(--text-4);
  background: var(--card-2); border: 1px solid var(--border-2);
  padding: 1.5px 9px; border-radius: var(--r-full);
}
.ag-tool.err .ag-tstat { color: var(--danger); background: var(--danger-soft); border-color: transparent; }
.ag-tool.err .ag-tico { background: var(--danger-soft); color: var(--danger); }
.ag-tlabel { padding: 9px 12px 0; font-size: 10.5px; letter-spacing: .1em; color: var(--text-4); }
.ag-tsec .ag-code, .ag-tsec .ag-out { margin: 6px 10px 10px; }

/* 轮次小标签 */
.ag-meta {
  align-self: center; font-size: 11px; color: var(--text-4);
  background: var(--card); border: 1px solid var(--border-2);
  padding: 3px 12px; border-radius: var(--r-full);
}

/* 空状态 */
.ag-empty { text-align: center; padding: 46px 20px 40px; }
.ag-empty-ico {
  width: 58px; height: 58px; margin: 0 auto 16px; border-radius: 18px;
  background: var(--grad); color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 10px 26px rgba(124, 92, 246, .35);
}
.ag-empty h3 { margin: 0 0 6px; font-size: 16.5px; color: var(--text); }
.ag-empty p { margin: 0 0 18px; font-size: 13px; color: var(--text-3); }
.ag-chips { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.ag-chips .btn {
  background: var(--card); border: 1px solid var(--border); color: var(--text-2);
  border-radius: var(--r-full); padding: 7px 14px; font-size: 12.5px; transition: all var(--t);
}
.ag-chips .btn:hover { border-color: var(--primary-line); color: var(--primary); background: var(--primary-soft); transform: translateY(-1px); }

/* 输入区 */
.ag-input { padding: 12px 14px 14px; border-top: 1px solid var(--border-2); background: var(--card); }
.ag-input textarea {
  width: 100%; border: 1px solid var(--border); background: var(--card-2);
  border-radius: 12px; padding: 10px 12px; font-size: 13.5px; line-height: 1.6;
  resize: none; transition: border-color var(--t), box-shadow var(--t);
}
.ag-input textarea:focus { outline: none; border-color: var(--primary); box-shadow: var(--ring); }
.ag-tip { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-4); }
.ag-tip svg { width: 13px; height: 13px; flex: 0 0 13px; }
.ag-send {
  background: var(--grad); border: 0; color: #fff; border-radius: 12px; padding: 9px 18px;
  box-shadow: 0 6px 16px rgba(124, 92, 246, .28);
}
.ag-send:hover { filter: brightness(1.07); }

@media (max-width: 1080px) {
  .ag { grid-template-columns: 1fr; }
  .ag-side { position: static; }
  .ag-body { max-height: 55vh; }
  .ag-think, .ag-tool { margin-left: auto; margin-right: auto; }
  .msg-wrap { max-width: 90%; }
}
/* ============================================================ 全屏工作台外壳 ============================================================ */
.wx { display: grid; grid-template-columns: 264px minmax(0, 1fr); height: 100vh; height: 100dvh; overflow: hidden; }

/* 左栏 */
.wx-rail {
  display: flex; flex-direction: column; min-height: 0;
  background: var(--card); border-right: 1px solid var(--border);
}
.wx-brand {
  display: flex; align-items: center; gap: 9px;
  padding: 15px 16px 12px; font-size: 14.5px; color: var(--text);
}
.wx-logo {
  width: 26px; height: 26px; border-radius: 8px; flex: none;
  background: var(--grad); color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 3px 8px rgba(124, 92, 246, .3);
}
.wx-new {
  margin: 2px 12px 10px; padding: 9px 12px;
  display: flex; align-items: center; gap: 8px; justify-content: center;
  border: 1.5px dashed var(--primary-line); border-radius: var(--r-md);
  background: var(--primary-soft); color: var(--primary);
  font-size: 13px; font-weight: 550; cursor: pointer; transition: all var(--t);
}
.wx-new:hover { background: var(--primary-line); }
.wx-tabs {
  display: flex; gap: 4px; margin: 0 12px 10px; padding: 3px;
  background: var(--bg-2); border-radius: var(--r-full);
}
.wx-tabs button {
  flex: 1; padding: 6px 0; border: 0; border-radius: var(--r-full);
  background: transparent; color: var(--text-3); font-size: 12.5px; cursor: pointer; transition: all var(--t);
}
.wx-tabs button.on { background: var(--card); color: var(--primary); font-weight: 550; box-shadow: var(--shadow-1); }
.wx-list { flex: 1; overflow-y: auto; padding: 2px 8px 10px; scrollbar-width: thin; }
.wx-empty { padding: 30px 14px; text-align: center; font-size: 12.5px; color: var(--text-3); line-height: 1.8; }
.wx-empty span { font-size: 11.5px; color: var(--text-4); }

.wx-sess {
  display: flex; align-items: center; gap: 6px;
  padding: 8px 10px; border-radius: var(--r-md); cursor: pointer;
  transition: background var(--t); position: relative;
}
.wx-sess:hover { background: var(--hover); }
.wx-sess.on { background: var(--primary-soft); }
.wx-sess-m { min-width: 0; flex: 1; }
.wx-sess-t { display: block; font-size: 12.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wx-sess.on .wx-sess-t { color: var(--primary); font-weight: 550; }
.wx-sess-time { display: block; font-size: 10.5px; color: var(--text-4); margin-top: 1px; }
.wx-sess-x {
  flex: none; width: 22px; height: 22px; border: 0; border-radius: 6px;
  background: transparent; color: var(--text-4); cursor: pointer;
  display: flex; align-items: center; justify-content: center; opacity: 0; transition: all var(--t);
}
.wx-sess:hover .wx-sess-x { opacity: 1; }
.wx-sess-x:hover { background: var(--danger-soft); color: var(--danger); }

.wx-file {
  display: flex; align-items: center; gap: 7px;
  padding: 7px 8px; border-radius: var(--r-md); font-size: 12px; transition: background var(--t);
}
.wx-file:hover { background: var(--hover); }
.wx-dot { width: 7px; height: 7px; border-radius: 2.5px; background: var(--primary); flex: none; opacity: .9; }
.wx-dot.dir { background: var(--cyan); }
.wx-dot.bin { background: var(--warning); }
.wx-file .nm { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
.wx-file .sz { flex: none; font-size: 10.5px; color: var(--text-4); }
.wx-file .ops { flex: none; display: flex; gap: 2px; opacity: 0; transition: opacity var(--t); }
.wx-file:hover .ops { opacity: 1; }
.wx-file .ops button {
  width: 22px; height: 22px; border: 0; border-radius: 6px;
  background: transparent; color: var(--text-3); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.wx-file .ops button:hover { background: var(--primary-soft); color: var(--primary); }
.wx-file .ops button.danger:hover { background: var(--danger-soft); color: var(--danger); }

.wx-foot {
  display: flex; gap: 4px; padding: 10px 12px;
  border-top: 1px solid var(--border-2);
}
.wx-foot button {
  flex: 1; padding: 7px 0; border: 0; border-radius: var(--r-md);
  background: transparent; color: var(--text-3); font-size: 12.5px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 6px; transition: all var(--t);
}
.wx-foot button:hover { background: var(--hover); color: var(--text); }

/* 主区 */
.wx-main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }
.wx-top {
  display: flex; align-items: center; gap: 12px;
  padding: 0 18px; height: 54px; flex: none;
  border-bottom: 1px solid var(--border-2); background: var(--card);
}
.wx-burger { display: none; border: 0; background: transparent; color: var(--text-2); cursor: pointer; padding: 6px; }
.wx-tt { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 10px; }
.wx-tt b { font-size: 14.5px; color: var(--text); }
.wx-tt span { font-size: 11.5px; color: var(--text-4); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wx-gear {
  border: 1px solid var(--border); background: var(--card); color: var(--text-2);
  width: 34px; height: 34px; border-radius: var(--r-md); cursor: pointer;
  display: flex; align-items: center; justify-content: center; transition: all var(--t);
}
.wx-gear:hover { color: var(--primary); border-color: var(--primary-line); background: var(--primary-soft); }

/* 消息画布 */
.wx-body {
  flex: 1; overflow-y: auto; padding: 22px 20px 14px;
  display: flex; flex-direction: column; gap: 14px;
  background:
    radial-gradient(900px 320px at 88% -60px, rgba(139, 92, 246, .06), transparent 60%),
    var(--card-2);
  scrollbar-width: thin;
}
.wx-body > * { flex: none; width: 100%; max-width: 860px; margin-left: auto; margin-right: auto; }

/* 输入区 */
.wx-compose {
  flex: none; padding: 10px 20px 14px;
  border-top: 1px solid var(--border-2); background: var(--card);
  display: flex; flex-direction: column; gap: 8px;
}
.wx-att { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.wx-attchip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 8px; border-radius: var(--r-full);
  background: var(--primary-soft); color: var(--primary); font-size: 11.5px; max-width: 240px;
}
.wx-attchip i { font-style: normal; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wx-attchip button {
  border: 0; background: transparent; color: inherit; cursor: pointer;
  display: flex; align-items: center; padding: 1px; border-radius: 50%;
}
.wx-attchip button:hover { background: rgba(0, 0, 0, .08); }
.wx-atttip { font-size: 11px; color: var(--text-4); }
.wx-bar {
  display: flex; align-items: flex-end; gap: 8px;
  max-width: 880px; width: 100%; margin: 0 auto;
  padding: 8px 10px; border: 1.5px solid var(--border); border-radius: 16px;
  background: var(--card-2); transition: border-color var(--t), box-shadow var(--t);
}
.wx-bar:focus-within { border-color: var(--primary); box-shadow: var(--ring); }
.wx-clip {
  flex: none; width: 34px; height: 34px; border: 0; border-radius: 10px;
  background: transparent; color: var(--text-3); cursor: pointer;
  display: flex; align-items: center; justify-content: center; transition: all var(--t);
}
.wx-clip:hover { background: var(--primary-soft); color: var(--primary); }
.wx-bar textarea {
  flex: 1; min-width: 0; border: 0; background: transparent; resize: none;
  font-size: 13.5px; line-height: 1.6; color: var(--text); padding: 6px 0; max-height: 160px;
}
.wx-bar textarea:focus { outline: none; }
.wx-send {
  flex: none; width: 36px; height: 36px; border: 0; border-radius: 11px;
  background: var(--grad); color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 5px 14px rgba(124, 92, 246, .3); transition: all var(--t);
}
.wx-send:hover { filter: brightness(1.07); }
.wx-under {
  display: flex; align-items: center; gap: 10px;
  max-width: 880px; width: 100%; margin: 0 auto;
}
.wx-model {
  max-width: 260px; padding: 4px 8px; font-size: 12px;
  border: 1px solid var(--border-2); border-radius: var(--r-full);
  background: var(--card-2); color: var(--text-2); cursor: pointer;
}
.wx-model:focus { outline: none; border-color: var(--primary-line); }
.wx-hint { font-size: 11px; color: var(--text-4); }

/* 气泡内附件 */
.wx-attchips { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 6px; }
.wx-attchips .wx-attchip { background: rgba(255, 255, 255, .18); color: #fff; }

.wx-mask { display: none; }

@media (max-width: 900px) {
  .wx { grid-template-columns: 1fr; }
  .wx-rail {
    position: fixed; z-index: 60; top: 0; left: 0; bottom: 0; width: 272px;
    transform: translateX(-102%); transition: transform var(--t);
    box-shadow: var(--shadow-3);
  }
  .wx.open .wx-rail { transform: none; }
  .wx.open .wx-mask {
    display: block; position: fixed; z-index: 50; inset: 0;
    background: var(--veil);
  }
  .wx-burger { display: flex; }
  .wx-tt span { display: none; }
  .wx-body { padding: 16px 14px 10px; }
  .wx-compose { padding: 8px 12px 12px; }
  .msg-wrap { max-width: 90%; }
  .ag-think, .ag-tool { margin-left: auto; margin-right: auto; }
  .wx-model { max-width: 180px; }
}
/* ============================================================ 工作台视觉打磨 v5 ============================================================ */
/* 头像顶对齐（之前 flex-end 导致头像沉到消息底部） */
.ag-row { align-items: flex-start; }

/* AI 头像 = 平台 logo */
img.ag-ava {
  width: 30px; height: 30px; border-radius: 9px;
  background: #fff; border: 1px solid var(--border);
  object-fit: cover; box-shadow: var(--shadow-1);
}
img.wx-logo {
  width: 27px; height: 27px; border-radius: 8px;
  background: #fff; border: 1px solid var(--border);
  object-fit: cover; flex: none;
}

/* 助手回复改为通栏正文（Claude 式），不再套卡片 */
.ag-assistant {
  background: transparent; border: 0; border-radius: 0;
  box-shadow: none; padding: 3px 2px 1px;
}
.ag-assistant.ag-err {
  background: var(--danger-soft); border: 1px solid transparent;
  border-radius: 10px; padding: 9px 13px; color: var(--danger);
}
.ag-user { border-radius: 16px 16px 4px 16px; }

/* 思考块：缩成一行小字标签（Claude 式） */
.ag-think, .ag-tool { margin-left: 42px; }
.ag-think {
  border: 0; background: transparent; border-radius: 0; overflow: visible;
}
.ag-think summary {
  display: inline-flex; padding: 2px 0; gap: 6px;
  color: var(--text-3); font-size: 12px; font-weight: 500;
}
.ag-think[open] summary { border-bottom: 0; margin-bottom: 4px; }
.ag-think summary .ag-tico.vio {
  background: transparent; width: 16px; height: 16px; border-radius: 0; color: #8b5cf6;
}
.ag-think summary .ag-tstat {
  background: transparent; border: 0; padding: 0;
  color: var(--text-4); font-weight: 400; margin-left: 0;
}
.ag-think summary::after {
  content: ''; width: 6px; height: 6px; flex: none; margin-top: 2px;
  border: solid var(--text-4); border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg); transition: transform var(--t);
}
.ag-think[open] summary::after { transform: rotate(135deg); }
.ag-think-body {
  margin: 2px 0 0; padding: 8px 12px; max-height: 220px;
  border-left: 2px solid var(--primary-line);
  background: var(--card); border-radius: 0 10px 10px 10px;
}

/* 工具块更轻 */
.ag-tool { border-color: var(--border-2); border-radius: 10px; font-size: 12px; }
.ag-tool summary { padding: 6px 10px; gap: 7px; }
.ag-tico { width: 20px; height: 20px; border-radius: 6px; }
.ag-tool[open] summary { border-bottom: 1px solid var(--border-2); }

/* 等待中：一行小字 */
.ag-typing {
  background: transparent; border: 0; box-shadow: none; padding: 3px 2px;
  border-radius: 0; font-size: 12.5px;
}

/* 轮次标签更小 */
.ag-meta { font-size: 10.5px; padding: 2px 10px; }
/* ============================================================ 工作台 v6 ============================================================ */
/* AI 侧全部顶到左线（思考/工具与头像同一条左线），用户靠右 */
.ag-think, .ag-tool { margin-left: auto; margin-right: auto; }

/* 助手回答恢复气泡卡片（中性色，不鲜艳） */
.ag-assistant {
  background: var(--card); border: 1px solid var(--border);
  border-radius: 4px 14px 14px 14px;
  box-shadow: var(--shadow-1); padding: 10px 14px;
}
.ag-assistant.ag-err {
  background: var(--danger-soft); border-color: transparent;
  border-radius: 10px; color: var(--danger); padding: 9px 13px;
}

/* 用户气泡：中性深色（随主题反转，不再使用鲜艳渐变） */
.ag-user {
  background: var(--text); color: var(--bg);
  border-radius: 14px 14px 4px 14px;
  box-shadow: var(--shadow-1);
}
.ag-user a { color: inherit; text-decoration: underline; }
.wx-attchips .wx-attchip { background: rgba(127, 127, 127, .18); color: inherit; }

/* 发送按钮：扁平主色，去渐变去光晕 */
.wx-send { background: var(--primary); box-shadow: none; border-radius: 10px; }
.wx-send:hover { background: var(--primary-hover); filter: none; }

/* 附件 chips 与输入同处一个容器（在输入框内部上方） */
.wx-bar { flex-wrap: wrap; row-gap: 4px; }
.wx-att {
  width: 100%; display: flex; flex-wrap: wrap; gap: 6px; align-items: center;
  padding: 0 2px 7px; border-bottom: 1px dashed var(--border-2);
}
.wx-att[hidden] { display: none; }
.wx-bar-row { display: flex; align-items: flex-end; gap: 8px; width: 100%; }
/* 助手卡片占满列宽 */
.ag-row:not(.me) .msg-wrap { flex: 1 1 auto; max-width: 100%; }

/* ============================================================ 工作台 v7：全宽 + 禁横向滚动 ============================================================ */
/* 消息贴边：AI 最左、用户最右，不再居中 */
.wx-body > * { max-width: none; margin-left: 0; margin-right: 0; }
.wx-bar, .wx-under { max-width: none; }
.wx-body { padding: 16px 18px 12px; }
.wx-compose { padding: 10px 18px 14px; }

/* 严禁横向滑动：代码一律换行 */
.ag-code, .ag-out, .wx-body pre { overflow-x: hidden; word-break: break-all; white-space: pre-wrap; }
.wx-body img { max-width: 100%; }

/* 工具运行中 */
.ag-tool.running .ag-tstat { color: var(--warning); background: var(--warning-soft); border-color: transparent; }

/* ============================================================ 工作台 v8：零横滑 + 输入栏重做 ============================================================ */
/* 全局禁横向滑动（仅工作台范围） */
.wx, .wx-main, .wx-body { max-width: 100vw; overflow-x: hidden; }
.wx-body *, .m-b pre { overflow-wrap: anywhere; }
.wx-body pre, .m-b pre { white-space: pre-wrap; }
.wx-body img { max-width: 100%; height: auto; }

/* 输入栏重做：移动端 + 桌面端统一 */
.wx-compose {
  padding: 10px 18px calc(12px + env(safe-area-inset-bottom));
  background: var(--card); border-top: 1px solid var(--border-2);
}
.wx-bar {
  border: 1.5px solid var(--border); border-radius: 20px;
  background: var(--card-2); padding: 8px 10px 8px;
  transition: border-color var(--t), box-shadow var(--t);
}
.wx-bar:focus-within { border-color: var(--primary); box-shadow: var(--ring); }
.wx-bar-row { display: flex; align-items: flex-end; gap: 6px; width: 100%; }
.wx-clip {
  flex: none; width: 38px; height: 38px; border: 0; border-radius: 13px;
  background: var(--bg-2); color: var(--text-2); cursor: pointer;
  display: flex; align-items: center; justify-content: center; transition: all var(--t);
}
.wx-clip:hover { background: var(--primary-soft); color: var(--primary); }
.wx-bar textarea {
  flex: 1; min-width: 0; border: 0; background: transparent; resize: none;
  font-size: 14px; line-height: 1.55; color: var(--text);
  padding: 8px 2px; min-height: 24px; max-height: 150px;
}
.wx-bar textarea:focus { outline: none; }
.wx-send {
  flex: none; width: 40px; height: 40px; border: 0; border-radius: 14px;
  background: var(--primary); color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center; transition: all var(--t);
}
.wx-send:hover { background: var(--primary-hover); }
.wx-send.off { opacity: .4; pointer-events: none; }
.wx-under { margin-top: 7px; display: flex; align-items: center; gap: 10px; }
.wx-model {
  max-width: 240px; padding: 4px 10px; font-size: 12px;
  border: 1px solid var(--border-2); border-radius: var(--r-full);
  background: var(--card-2); color: var(--text-2); cursor: pointer;
}
.wx-model:focus { outline: none; border-color: var(--primary-line); }
.wx-hint { font-size: 11px; color: var(--text-4); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 900px) {
  .wx-compose { padding: 8px 10px calc(10px + env(safe-area-inset-bottom)); }
  .wx-bar { border-radius: 16px; padding: 6px 8px; }
  .wx-clip { width: 34px; height: 34px; border-radius: 11px; }
  .wx-send { width: 36px; height: 36px; border-radius: 12px; }
  .wx-body { padding: 14px 12px 10px; }
}
/* 移动端隐藏输入框占位文字（“描述你想做的事…”太长会挤压输入框） */
@media (max-width: 900px) {
  .wx-bar textarea::placeholder { color: transparent; }
  .wx-bar textarea::-webkit-input-placeholder { color: transparent; }
}
/* v10：AI 气泡防溢出（长 token / 长行一律折行，绝不冲出气泡） */
.msg-bubble, .ag-assistant, .ag-think-body, .ag-code, .ag-out {
  min-width: 0;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.ag-assistant { overflow-x: hidden; }
.ag-code, .ag-out { word-break: break-all; }


/* v15：AI 回复中的 markdown 表格自动渲染 */
.ag-table {
  width: 100%; border-collapse: collapse; margin: 8px 0 2px;
  table-layout: fixed; font-size: 12.5px; background: var(--card);
}
.ag-table th, .ag-table td {
  border: 1px solid var(--border-2); padding: 6px 8px;
  text-align: left; vertical-align: top;
  overflow-wrap: anywhere; word-break: break-word;
}
.ag-table th { background: var(--bg-2); font-weight: 600; }
.ag-table tbody tr:nth-child(even) { background: var(--bg-2); }


/* v17：窄屏（手机）排版细调 */
@media (max-width: 900px) {
  .wx-body { padding: 12px 10px 8px; }
  .ag-assistant, .ag-user { font-size: 13.5px; line-height: 1.62; }
  .ag-assistant { padding: 9px 11px; }
  .ag-user { max-width: 88%; }
  .ag-think-body { font-size: 12px; line-height: 1.6; padding: 7px 9px; }
  .ag-table { font-size: 11.5px; }
  .ag-table th, .ag-table td { padding: 4px 6px; }
  .ag-inline { font-size: 11.5px; }
  .ag-tool { font-size: 11.5px; }
  .ag-code, .ag-out { font-size: 11.5px; }
  .ag-h { font-size: 14px; }
}

.ag-li.ag-olin { white-space: normal; text-align: left; overflow-wrap: anywhere; }

/* DSH（DeepSeek Harness）入口 */
.dsh-page { height: 100vh; height: 100dvh; display: flex; flex-direction: column;
  background: var(--bg); padding: 10px 12px 12px; gap: 10px; }
.dsh-bar { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.dsh-bar .dsh-title { flex: 1; text-align: center; font-size: 14px; }
.dsh-shell { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; }
.dsh-frame { width: 100%; height: 100%; border: 0; display: block;
  border-radius: 14px; background: var(--card); }
.dsh-boot { text-align: center; max-width: 460px; padding: 0 16px; }
.dsh-boot-ico { width: 56px; height: 56px; margin: 0 auto 14px; border-radius: 16px;
  background: var(--primary-soft); color: var(--primary);
  display: flex; align-items: center; justify-content: center; }
.dsh-boot b { font-size: 16px; }
.dsh-boot p { color: var(--text-3); font-size: 13px; line-height: 1.7; margin: 8px 0 0; }
.dsh-boot .dsh-tip { font-size: 12px; margin-top: 14px; }
.dsh-boot-bar { width: 220px; height: 4px; border-radius: 2px; background: var(--bg-2);
  margin: 18px auto 0; overflow: hidden; }
.dsh-boot-bar i { display: block; width: 38%; height: 100%; border-radius: 2px;
  background: var(--primary); animation: dshSlide 1.1s ease-in-out infinite; }
@keyframes dshSlide { 0% { transform: translateX(-100%); } 100% { transform: translateX(360%); } }
@media (max-width: 900px) { .dsh-bar .dsh-title { font-size: 13px; } }


/* ------------------------------------------------- AI 工作台入口（两选一） --- */
.wbsel { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.wbsel-card {
  display: flex; flex-direction: column;
  padding: 18px;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: var(--shadow-1);
  transition: box-shadow var(--t), transform var(--t);
}
.wbsel-card:hover { box-shadow: var(--shadow-2); transform: translateY(-1px); }
.wbsel-top { display: flex; align-items: center; gap: 10px; }
.wbsel-name { font-size: 16px; font-weight: 680; letter-spacing: -.01em; }
.wbsel-desc { margin: 12px 0 0; font-size: 13px; line-height: 1.65; color: var(--text-2); }
.wbsel-pts { margin: 12px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 7px; }
.wbsel-pts li { display: flex; align-items: flex-start; gap: 7px; font-size: 12.5px; color: var(--text-3); }
.wbsel-pts svg { flex: 0 0 auto; margin-top: 2px; color: var(--primary); }
.wbsel-btn { margin-top: auto; padding-top: 16px; width: 100%; justify-content: center; }
.wbsel-btn svg { margin-left: 2px; }
@media (max-width: 760px) { .wbsel { grid-template-columns: 1fr; } }


/* ============================================================================
   UI v6 — 按 sub2api（Wei-Shaw/sub2api）的设计系统重做用户端
   ----------------------------------------------------------------------------
   来源：该仓库 frontend/tailwind.config.js 与 src/style.css 的真实取值
     · 主色 = Teal 青绿（primary-500 #14b8a6 → 600 #0d9488）
     · 中性色 = Tailwind gray 阶；深色 = slate（dark-900 #0f172a / 950 #020617）
     · 卡片 rounded-2xl + border-gray-100 + shadow-card，悬停 -translate-y-0.5 + shadow-card-hover
     · 主按钮 = 青绿渐变 + 同色投影；输入框 rounded-xl + 聚焦 ring
     · 侧栏 fixed w-64 白底 border-r；选中态 primary-50 浅底 + primary-600 字
     · 全局 mesh-gradient 光斑背景（径向青绿/青色）
   本层为唯一视觉层（旧的 v2/v3/v5/v5.1 已全部移除），并补齐 JS 用到的自定义类。
   ========================================================================== */

/* ---------- 1. 设计令牌 ---------- */
:root {
  --primary-50: #f0fdfa;
  --primary-100: #ccfbf1;
  --primary-200: #99f6e4;
  --primary-300: #5eead4;
  --primary-400: #2dd4bf;
  --primary-500: #14b8a6;
  --primary-600: #0d9488;
  --primary-700: #0f766e;

  --primary: #14b8a6;
  --primary-hover: #0d9488;
  --primary-active: #0f766e;
  --primary-soft: #f0fdfa;
  --primary-line: #99f6e4;
  --on-primary: #ffffff;

  --success: #059669;  --success-soft: #d1fae5;
  --warning: #d97706;  --warning-soft: #fef3c7;
  --danger:  #dc2626;  --danger-soft:  #fee2e2;
  --info:    #0891b2;  --info-soft:    #cffafe;
  --cyan:    #06b6d4;  --cyan-soft:    #cffafe;
  --pink:    #db2777;  --pink-soft:    #fce7f3;

  --grad: linear-gradient(135deg, #14b8a6 0%, #0d9488 100%);
  --grad-soft: linear-gradient(135deg, #f0fdfa 0%, #ecfeff 100%);

  --r-xs: 6px;  --r-sm: 8px;  --r-md: 12px;  --r-lg: 16px;  --r-xl: 16px;  --r-full: 999px;
  --t: 200ms cubic-bezier(.4, 0, .2, 1);
  --rail: 256px;
}
[data-theme="light"] {
  --bg:        #f9fafb;
  --bg-2:      #f3f4f6;
  --card:      #ffffff;
  --card-2:    #f9fafb;
  --card-3:    #f3f4f6;
  --border:    #e5e7eb;
  --border-2:  #f3f4f6;
  --border-3:  #d1d5db;
  --text:      #111827;
  --text-2:    #4b5563;
  --text-3:    #6b7280;
  --text-4:    #9ca3af;
  --hover:     #f3f4f6;
  --header-bg: rgba(255, 255, 255, .8);
  --code-bg:   #f9fafb;
  --code-line: #e5e7eb;
  --veil:      rgba(0, 0, 0, .5);
  --shadow-1:  0 1px 3px rgba(0, 0, 0, .04), 0 1px 2px rgba(0, 0, 0, .06);
  --shadow-2:  0 10px 40px rgba(0, 0, 0, .08);
  --shadow-3:  0 25px 50px -12px rgba(0, 0, 0, .25);
  --ring:      0 0 0 3px rgba(20, 184, 166, .25);
}
[data-theme="dark"] {
  --bg:        #020617;
  --bg-2:      #0f172a;
  --card:      #0f172a;
  --card-2:    #1e293b;
  --card-3:    #1e293b;
  --border:    #1e293b;
  --border-2:  #1e293b;
  --border-3:  #334155;
  --text:      #f1f5f9;
  --text-2:    #cbd5e1;
  --text-3:    #94a3b8;
  --text-4:    #64748b;
  --hover:     #1e293b;
  --header-bg: rgba(15, 23, 42, .8);
  --code-bg:   #0f172a;
  --code-line: #1e293b;
  --veil:      rgba(0, 0, 0, .65);
  --shadow-1:  0 1px 3px rgba(0, 0, 0, .4), 0 1px 2px rgba(0, 0, 0, .3);
  --shadow-2:  0 10px 40px rgba(0, 0, 0, .5);
  --shadow-3:  0 25px 50px -12px rgba(0, 0, 0, .7);
  --ring:      0 0 0 3px rgba(20, 184, 166, .3);
}

/* ---------- 2. 基础 + 全屏光斑背景 ---------- */
body {
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
}
/* sub2api 的 bg-mesh-gradient：三处径向青绿光斑铺满视口 */
body::before {
  content: ''; position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(at 40% 20%, rgba(20, 184, 166, .12) 0px, transparent 50%),
    radial-gradient(at 80% 0%, rgba(6, 182, 212, .08) 0px, transparent 50%),
    radial-gradient(at 0% 50%, rgba(20, 184, 166, .08) 0px, transparent 50%);
}
[data-theme="dark"] body::before { opacity: .55; }
.shell, .main, .page, .auth, .dsh-page { position: relative; z-index: 1; }
::selection { background: rgba(20, 184, 166, .2); color: var(--primary-700); }
.mono, .num, .kpi-val, .tile .t-v, .stat-item b { font-variant-numeric: tabular-nums; }

/* ---------- 3. 侧栏：白底 w-64，选中态青绿浅底 ---------- */
.sidebar {
  width: 256px; flex: 0 0 256px;
  background: var(--card);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
}
.sb-brand {
  height: 64px; padding: 0 24px; gap: 12px;
  display: flex; align-items: center;
  border-bottom: 1px solid var(--border-2);
}
.sb-logo {
  width: 36px; height: 36px; flex: 0 0 36px; border-radius: 12px;
  background: var(--grad);
  box-shadow: 0 0 20px rgba(20, 184, 166, .25);
  display: grid; place-items: center; overflow: hidden;
}
.sb-logo img { width: 22px; height: 22px; object-fit: contain; }
.sb-name b { font-size: 17px; font-weight: 700; color: var(--text); letter-spacing: -.02em; }
.sb-name span { font-size: 11.5px; color: var(--text-3); }
.sb-nav { flex: 1; overflow-y: auto; padding: 16px 12px; }
.sb-group {
  margin: 20px 0 8px; padding: 0 12px;
  font-size: 11px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-4);
}
.sb-group:first-child { margin-top: 0; }
.sb-item {
  display: flex; align-items: center; gap: 12px;
  width: 100%; height: auto; margin-bottom: 4px;
  padding: 10px 14px 10px 17px;
  border: none; border-radius: 12px; background: transparent;
  font-size: 14px; font-weight: 500; color: var(--text-2); text-align: left;
  cursor: pointer; transition: background var(--t), color var(--t);
}
.sb-item svg { width: 20px; height: 20px; flex: 0 0 20px; opacity: .9; }
.sb-item:hover { background: var(--hover); color: var(--text); }
.sb-item.on { background: var(--primary-soft); color: var(--primary-600); font-weight: 600; }
.sb-item.on:hover { background: var(--primary-100); }
.sb-item.on::before { display: none; }
.sb-item.on svg { color: var(--primary-600); opacity: 1; }
.sb-badge {
  margin-left: auto; padding: 1px 8px; border-radius: 999px;
  background: var(--primary); color: #fff; font-size: 11px; font-weight: 600;
}
.sb-foot { padding: 12px; border-top: 1px solid var(--border-2); }
.sb-foot .copy-box { background: var(--card-3); border: none; border-radius: 12px; }
.sb-foot .btn-ghost { color: var(--text-2); }

/* ---------- 4. 顶栏（内容区内）与页面 ---------- */
.topbar {
  height: 64px; padding: 0 28px;
  background: var(--header-bg);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border-2);
}
.topbar h1, .topbar .tb-title { font-size: 16px; font-weight: 700; letter-spacing: -.02em; }
.page { padding: 24px 28px 64px; max-width: 1560px; }
.page > * + * { margin-top: 16px; }
.page-title { font-size: 24px; font-weight: 700; letter-spacing: -.025em; }
.page-description { margin-top: 4px; font-size: 14px; color: var(--text-3); }

/* ---------- 5. 卡片 ---------- */
.card {
  background: var(--card);
  border: 1px solid var(--border-2);
  border-radius: 16px;
  box-shadow: var(--shadow-1);
  transition: box-shadow var(--t), transform var(--t), border-color var(--t);
  overflow: hidden;
}
.card + .card { margin-top: 16px; }
.card-h { padding: 16px 24px; border-bottom: 1px solid var(--border-2); gap: 12px; }
.card-hico { width: 36px; height: 36px; flex: 0 0 36px; border-radius: 12px; }
.card-hico svg { width: 18px; height: 18px; }
.card-t { font-size: 15px; font-weight: 650; letter-spacing: -.015em; }
.card-d { margin-top: 2px; font-size: 12.5px; color: var(--text-3); }
.card-b { padding: 20px 24px; }
.card-b.flush { padding: 0; }
.card-f { padding: 14px 24px; border-top: 1px solid var(--border-2); background: var(--card-2); }
.card-title { font-size: 15px; font-weight: 650; }

/* 指标块（KPI） */
.kpis { gap: 16px; margin-bottom: 16px; }
.kpi {
  padding: 20px; border-radius: 16px;
  border: 1px solid var(--border-2);
  box-shadow: var(--shadow-1);
  transition: box-shadow var(--t), transform var(--t);
}
.kpi:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); }
.kpi::before { display: none !important; }
.kpi-ico { width: 48px; height: 48px; border-radius: 12px; }
.kpi-ico svg { width: 22px; height: 22px; }
.kpi-label { font-size: 14px; color: var(--text-3); font-weight: 500; }
.kpi-val { margin-top: 10px; font-size: 24px; font-weight: 700; letter-spacing: -.02em; }
.kpi-sub { margin-top: 4px; font-size: 12.5px; color: var(--text-4); }

/* 指标条 / 指标小卡（JS 的 tile()） */
.strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 16px; }
.tile {
  background: var(--card); border: 1px solid var(--border-2); border-radius: 16px;
  box-shadow: var(--shadow-1); padding: 18px 20px;
  transition: box-shadow var(--t), transform var(--t);
}
.tile:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); }
.tile .t-top { display: flex; align-items: center; gap: 10px; }
.tile .t-ico {
  width: 36px; height: 36px; flex: 0 0 36px; border-radius: 12px;
  display: grid; place-items: center;
  background: var(--card-3); color: var(--text-3);
}
.tile .t-ico svg { width: 18px; height: 18px; }
.tile .t-l { font-size: 13.5px; font-weight: 500; color: var(--text-3); }
.tile .t-v { margin-top: 12px; font-size: 24px; font-weight: 700; letter-spacing: -.02em; }
.tile .t-s { margin-top: 4px; font-size: 12px; color: var(--text-4); }
.tile.brand .t-ico { background: var(--primary-100); color: var(--primary-600); }
.tile.brand .t-v { color: var(--primary-600); }
.tile.ok .t-ico { background: var(--success-soft); color: var(--success); }
.tile.ok .t-v { color: var(--success); }
.tile.warn .t-ico { background: var(--warning-soft); color: var(--warning); }
.tile.warn .t-v { color: var(--warning); }
.tile.danger .t-ico { background: var(--danger-soft); color: var(--danger); }
.tile.danger .t-v { color: var(--danger); }

/* 小面板 / 信息行 / 提示格 / 工具条 / 栅格 */
.panel { background: var(--card); border: 1px solid var(--border-2); border-radius: 16px; box-shadow: var(--shadow-1); overflow: hidden; }
.panel-h { padding: 15px 20px; border-bottom: 1px solid var(--border-2); font-size: 14px; font-weight: 650; display: flex; align-items: center; gap: 9px; }
.panel-h svg { width: 16px; height: 16px; color: var(--text-3); }
.panel-b { padding: 18px 20px; }
.rows .r { display: flex; align-items: center; gap: 12px; padding: 11px 0; border-bottom: 1px solid var(--border-2); font-size: 13.5px; }
.rows .r:last-child { border-bottom: none; }
.rows .r > .k { color: var(--text-3); }
.rows .r > .v { margin-left: auto; text-align: right; color: var(--text); }
.tips { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
.tip {
  display: flex; gap: 11px; padding: 14px;
  border: 1px solid var(--border-2); border-radius: 14px; background: var(--card-2);
}
.tip .ti {
  width: 32px; height: 32px; flex: 0 0 32px; border-radius: 10px;
  display: grid; place-items: center;
  background: var(--primary-100); color: var(--primary-600);
}
.tip .ti svg { width: 16px; height: 16px; }
.tip b { display: block; font-size: 13.5px; font-weight: 600; color: var(--text); }
.tip span { display: block; margin-top: 3px; font-size: 12.5px; color: var(--text-3); line-height: 1.6; }
.toolbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 14px 24px; border-bottom: 1px solid var(--border-2); background: var(--card-2);
}
.toolbar .sp { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }
.grid2, .g2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; align-items: start; }
.grid3, .g3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; align-items: start; }
.grid4, .g4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; align-items: start; }
@media (max-width: 1180px) { .grid4, .g4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 980px) { .grid3, .g3, .grid2, .g2 { grid-template-columns: 1fr; } }

/* ---------- 6. 按钮：青绿渐变主按钮 + 同色投影 ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: auto; padding: 10px 16px;
  border: 1px solid transparent; border-radius: 12px;
  background: transparent;
  font-size: 14px; font-weight: 500; line-height: 1.25;
  color: var(--text); box-shadow: none;
  transition: all var(--t);
}
.btn:active { transform: scale(.98); }
.btn:focus-visible { outline: none; box-shadow: var(--ring); }
.btn svg { width: 16px; height: 16px; }
.btn-primary {
  background: var(--grad);
  color: #fff;
  box-shadow: 0 4px 6px -1px rgba(20, 184, 166, .25), 0 2px 4px -2px rgba(20, 184, 166, .25);
}
.btn-primary:hover {
  background: linear-gradient(135deg, #0d9488 0%, #0f766e 100%);
  box-shadow: 0 10px 15px -3px rgba(20, 184, 166, .3), 0 4px 6px -4px rgba(20, 184, 166, .3);
}
.btn-secondary, .btn:not(.btn-primary):not(.btn-ghost):not(.btn-danger):not(.btn-success):not(.btn-warning) {
  background: var(--card);
  color: var(--text-2);
  border-color: var(--border);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
}
.btn-secondary:hover, .btn:not(.btn-primary):not(.btn-ghost):not(.btn-danger):not(.btn-success):not(.btn-warning):hover {
  background: var(--bg);
  border-color: var(--border-3);
  color: var(--text);
}
.btn-ghost { background: transparent; color: var(--text-2); }
.btn-ghost:hover { background: var(--hover); color: var(--text); }
.btn-danger { background: linear-gradient(135deg, #ef4444, #dc2626); color: #fff; box-shadow: 0 4px 6px -1px rgba(239, 68, 68, .25); }
.btn-success { background: linear-gradient(135deg, #10b981, #059669); color: #fff; box-shadow: 0 4px 6px -1px rgba(16, 185, 129, .25); }
.btn-warning { background: linear-gradient(135deg, #f59e0b, #d97706); color: #fff; box-shadow: 0 4px 6px -1px rgba(245, 158, 11, .25); }
.btn-sm { padding: 6px 12px; font-size: 12.5px; border-radius: 10px; }
.btn-sm svg { width: 14px; height: 14px; }
.btn-lg { padding: 12px 24px; font-size: 16px; border-radius: 16px; }
.btn[disabled] { opacity: .5; pointer-events: none; }
.icon-btn, .hd-btn {
  width: 38px; height: 38px; border-radius: 12px; display: inline-grid; place-items: center;
  color: var(--text-2); background: transparent; border: none; transition: background var(--t);
}
.icon-btn:hover, .hd-btn:hover { background: var(--hover); color: var(--text); }

/* ---------- 7. 输入框 / 分段 / 选项 ---------- */
input:not([type=checkbox]):not([type=radio]), select, textarea {
  width: 100%; height: auto; padding: 10px 16px;
  border-radius: 12px; border: 1px solid var(--border);
  background: var(--card); color: var(--text); font-size: 14px;
  transition: all var(--t);
}
input::placeholder, textarea::placeholder { color: var(--text-4); }
input:hover, select:hover, textarea:hover { border-color: var(--border-3); }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--primary-500); box-shadow: var(--ring);
}
.field > span, .field > label > span { font-size: 13px; font-weight: 500; color: var(--text-2); }
.seg { display: flex; gap: 4px; padding: 4px; border: none; border-radius: 12px; background: var(--card-3); }
.seg button {
  padding: 7px 16px; border: none; border-radius: 10px; background: transparent;
  font-size: 13.5px; font-weight: 500; color: var(--text-2); transition: all var(--t);
}
.seg button:hover { color: var(--text); }
.seg button.on { background: var(--card); color: var(--text); font-weight: 600; box-shadow: 0 1px 2px rgba(0, 0, 0, .06); }
.opt {
  padding: 6px 14px; border: 1px solid var(--border); border-radius: 999px;
  background: var(--card); font-size: 13px; color: var(--text-2); transition: all var(--t);
}
.opt:hover { border-color: var(--border-3); color: var(--text); }
.opt.on { background: var(--primary-100); border-color: var(--primary-300); color: var(--primary-700); font-weight: 600; }

/* ---------- 8. 表格 ---------- */
.tbl-wrap { overflow-x: auto; border-radius: 12px; }
table { width: 100%; font-size: 14px; }
thead th {
  padding: 12px 16px; text-align: left;
  background: var(--card-2); border-bottom: 1px solid var(--border);
  font-size: 13px; font-weight: 500; color: var(--text-3);
  white-space: nowrap;
}
tbody td { padding: 14px 16px; border-bottom: 1px solid var(--border-2); color: var(--text-2); }
tbody tr { transition: background 150ms ease; }
tbody tr:hover { background: var(--card-2); }
tbody tr:last-child td { border-bottom: none; }
td.k { color: var(--text); font-weight: 500; }

/* ---------- 9. 徽章 / 标签 ---------- */
.tag, .badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 10px; height: auto; border-radius: 999px;
  font-size: 12px; font-weight: 500;
}
.tag.ok, .tag.success { background: var(--success-soft); color: #047857; }
.tag.muted { background: var(--card-3); color: var(--text-3); }
.tag.warning { background: var(--warning-soft); color: #b45309; }
.tag.danger { background: var(--danger-soft); color: var(--danger); }
.tag.info { background: var(--info-soft); color: #0e7490; }
.tag.brand { background: var(--primary-100); color: var(--primary-700); }

/* ---------- 10. 提示 / 空态 / 加载 ---------- */
.hint { font-size: 13px; color: var(--text-3); }
.notice {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 13px 16px; border: 1px solid var(--border-2); border-radius: 12px;
  background: var(--card-2); font-size: 13px; color: var(--text-2);
}
.notice.warn { background: var(--warning-soft); border-color: transparent; color: #92400e; }
.empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px 16px; text-align: center; gap: 6px; }
.empty .e-ico {
  width: 64px; height: 64px; margin-bottom: 10px; border-radius: 16px;
  display: grid; place-items: center;
  background: var(--card-3); color: var(--text-4);
}
.empty .e-t { font-size: 17px; font-weight: 500; color: var(--text); }
.empty .e-d { font-size: 13.5px; color: var(--text-3); max-width: 26rem; }
.spinner, .loading i {
  width: 20px; height: 20px; border-radius: 50%;
  border: 2px solid currentColor; border-top-color: transparent;
  animation: v6spin .7s linear infinite;
}
@keyframes v6spin { to { transform: rotate(360deg); } }
.loading { display: flex; align-items: center; justify-content: center; gap: 10px; padding: 40px 0; color: var(--text-3); font-size: 14px; }
.skeleton { border-radius: 8px; background: var(--card-3); animation: v6pulse 1.6s ease-in-out infinite; }
@keyframes v6pulse { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }
.divider { height: 1px; background: var(--border-2); margin: 16px 0; }

/* ---------- 11. 弹层 / 提示条 ---------- */
.overlay { background: var(--veil); backdrop-filter: blur(4px); }
.modal {
  border: 1px solid var(--border); border-radius: 16px;
  box-shadow: var(--shadow-3); overflow: hidden; background: var(--card);
}
/* ⚠️ 上面这条 overflow:hidden 的坑：它是简写，会把基础样式里的
   `.modal{max-height:88vh; overflow-y:auto}` 的 overflow-y **一起改成 hidden**，
   于是超过 88vh 的内容被直接裁掉、连滚动条都没有 ——
   后台「点用户弹出的详情卡片」就是这样：下面的令牌/调用/充值/危险操作整片看不到。
   修法：保留 overflow:hidden 去裁圆角，改成弹性列布局，让 .modal-b 自己滚，
   头（.modal-h）和脚（.modal-f）固定可见 —— 脚上的按钮就不用翻到底才点得到。
   注意 .modal-b 必须写 min-height:0，否则弹性子项撑不到比内容矮、滚不起来。 */
.modal { display: flex; flex-direction: column; }
.modal-h { flex: 0 0 auto; }
.modal-b {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; overscroll-behavior: contain;
}
/* ⚠️ 必须禁掉内容区的"压缩"，否则内部那些 overflow:hidden 的卡片会被压成 0 高。
   原因：弹性项的**自动最小尺寸**（min-height:auto）在 overflow 非 visible 时
   会解析成 0 —— .modal-b 里的令牌列表容器为了裁圆角写了 overflow:hidden，
   于是内容一超高，它就吸收压缩量、塌成一条边框线，里面的令牌行被裁得看不见
   （实测：容器 2px、子行 65px）。滚动容器里的内容本来就不该被压缩，
   该滚的是外层 —— 所以直接让所有直接子项不许伸缩。 */
.modal-b > * { flex: 0 0 auto; }
.modal-f { flex: 0 0 auto; }
.modal-x { width: 36px; height: 36px; border-radius: 12px; color: var(--text-3); }
.modal-x:hover { background: var(--hover); color: var(--text); }
.toasts { gap: 10px; }
.toast {
  border: 1px solid var(--border); border-radius: 12px;
  background: var(--card); box-shadow: var(--shadow-2);
  font-size: 13.5px; color: var(--text);
}
.menu, .dropdown { border-radius: 12px; border: 1px solid var(--border); box-shadow: var(--shadow-2); background: var(--card); }
.menu-item { padding: 10px 12px; border-radius: 10px; font-size: 13.5px; }
.menu-item:hover { background: var(--hover); }

/* ---------- 12. 其余零件 ---------- */
.kv-row { padding: 11px 0; border-bottom: 1px solid var(--border-2); font-size: 13.5px; }
.kv-row .k { color: var(--text-3); }
.copy-box {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px; border: 1px solid var(--border-2); border-radius: 12px;
  background: var(--card-2);
}
.key-card { padding: 16px 20px; border-bottom: 1px solid var(--border-2); }
.key-card:last-child { border-bottom: none; }
.act-row { gap: 10px; }
.pager button, .pager .btn { padding: 7px 12px; }
.filter-block .fb-t { font-size: 12.5px; font-weight: 600; color: var(--text-3); }

/* ---------- 13. 登录 / 注册 ---------- */
.auth { display: grid; grid-template-columns: 1.05fr .95fr; min-height: 100vh; background: var(--card); }
.auth-side {
  position: relative; overflow: hidden; color: #fff;
  padding: 56px 52px; display: flex; flex-direction: column; justify-content: space-between;
  background: var(--grad);
}
.auth-side::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(120% 80% at 12% 8%, rgba(255, 255, 255, .22), transparent 60%);
}
.auth-side h2, .auth-title { font-size: 30px; line-height: 1.25; letter-spacing: -.03em; font-weight: 700; }
.auth-sub { margin-top: 14px; font-size: 14px; line-height: 1.75; color: rgba(255, 255, 255, .85); }
.auth-side ul { list-style: none; margin: 26px 0 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.auth-side li { display: flex; align-items: center; gap: 9px; font-size: 13.5px; color: rgba(255, 255, 255, .92); }
.auth-side li svg { width: 17px; height: 17px; flex: none; }
.auth-side .logo { display: flex; align-items: center; gap: 10px; font-size: 16px; }
.auth-side .logo img { width: 30px; height: 30px; border-radius: 9px; }
.auth-form-wrap { display: flex; align-items: center; justify-content: center; padding: 44px 28px; }
.auth-form { width: 100%; max-width: 380px; }
.auth-form > h2, .auth-form h2 { font-size: 22px; font-weight: 700; letter-spacing: -.025em; text-align: center; }
.auth-form > p, .auth-form .auth-tip { margin-top: 7px; font-size: 13.5px; color: var(--text-3); text-align: center; }
.auth-foot { margin-top: 18px; font-size: 13px; color: var(--text-4); text-align: center; line-height: 1.7; }
.auth .card { border: none; box-shadow: none; background: transparent; }
@media (max-width: 900px) {
  .auth { grid-template-columns: 1fr; }
  .auth-side { padding: 30px 24px 26px; justify-content: flex-start; gap: 18px; }
  .auth-side h2, .auth-title { font-size: 22px; }
  .auth-side ul { display: none; }
  .auth-form-wrap { padding: 26px 20px 44px; }
}

/* ---------- 14. 手机底部导航 / 抽屉 ---------- */
.tabbar {
  border-top: 1px solid var(--border);
  background: var(--header-bg); backdrop-filter: saturate(180%) blur(12px);
}
.tabbar .on, .tabbar a.on, .tabbar button.on { color: var(--primary-600); font-weight: 600; }
.m-drawer-panel { border-radius: 0 16px 16px 0; }
.m-drawer-head { border-bottom: 1px solid var(--border-2); }

/* ---------- 15. 工作台对话 ---------- */
.wx-body { gap: 10px; }
.wx-body > .ag-tool,
.wx-body > .ag-think {
  align-self: flex-start; width: auto;
  max-width: min(82%, 780px); margin-left: 37px;
}
.wx-body > .ag-meta { margin-left: 37px; }
.ag-row { gap: 10px; align-items: flex-start; }
.ag-ava, .msg-av { width: 32px; height: 32px; flex: 0 0 32px; border-radius: 12px; object-fit: cover; }
.msg-wrap { max-width: 76%; }
.msg-bubble {
  padding: 12px 16px; border-radius: 16px 16px 16px 6px;
  border: 1px solid var(--border-2); background: var(--card);
  font-size: 14px; line-height: 1.7;
}
.ag-user {
  background: var(--grad); color: #fff; border-color: transparent;
  border-radius: 16px 16px 6px 16px;
  box-shadow: 0 6px 16px -6px rgba(20, 184, 166, .5);
  white-space: pre-wrap;
}
.ag-assistant { background: var(--card); }
.ag-err { background: var(--danger-soft); border-color: transparent; color: var(--danger); }
.ag-meta { font-size: 12px; color: var(--text-4); }
.ag-tool {
  border: 1px solid var(--border-2); background: var(--card-2);
  border-radius: 12px; overflow: hidden;
}
.ag-tool > summary {
  display: flex; align-items: center; gap: 9px; padding: 8px 12px;
  cursor: pointer; list-style: none; font-size: 13px; transition: background var(--t);
}
.ag-tool > summary::-webkit-details-marker { display: none; }
.ag-tool > summary:hover { background: var(--hover); }
.ag-tool.running { border-color: var(--primary-300); }
.ag-tool.err { border-color: var(--danger); }
.ag-tico {
  width: 22px; height: 22px; flex: 0 0 22px; border-radius: 7px;
  display: grid; place-items: center;
  background: var(--card-3); color: var(--text-3);
}
.ag-tico svg { width: 13px; height: 13px; }
.ag-tico.vio { background: var(--primary-100); color: var(--primary-600); }
.ag-tname { font-weight: 600; color: var(--text); font-size: 13px; }
.ag-tstat {
  margin-left: auto; padding: 2px 9px; border-radius: 999px;
  font-size: 11.5px; color: var(--text-4); background: var(--card-3);
}
.ag-tool.running .ag-tstat { background: var(--primary-100); color: var(--primary-700); }
.ag-tool.err .ag-tstat { background: var(--danger-soft); color: var(--danger); }
.ag-tsec { padding: 0 12px 10px; }
.ag-tlabel { padding: 6px 0 4px; font-size: 11.5px; font-weight: 600; color: var(--text-4); letter-spacing: .03em; }
.ag-code, .ag-out {
  margin: 0; padding: 11px 13px; border-radius: 10px;
  background: var(--code-bg); border: 1px solid var(--code-line);
  font-size: 12.5px; line-height: 1.65;
  max-height: 340px; overflow: auto; white-space: pre-wrap; word-break: break-word;
}
.ag-think { border: 1px dashed var(--border); border-radius: 12px; background: transparent; }
.ag-think > summary {
  display: flex; align-items: center; gap: 9px; padding: 8px 12px;
  cursor: pointer; list-style: none; font-size: 12.5px; color: var(--text-3);
}
.ag-think > summary::-webkit-details-marker { display: none; }
.ag-think-body { padding: 4px 14px 12px; font-size: 13px; line-height: 1.75; color: var(--text-3); white-space: pre-wrap; }
.ag-empty { padding: 56px 24px; text-align: center; }
.ag-empty-ico {
  width: 56px; height: 56px; margin: 0 auto 14px; border-radius: 16px;
  display: grid; place-items: center;
  background: var(--primary-100); color: var(--primary-600);
}
.ag-empty h3 { font-size: 18px; font-weight: 650; letter-spacing: -.02em; }
.ag-empty p { margin-top: 7px; font-size: 13.5px; color: var(--text-3); }
.ag-chips { margin-top: 20px; display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.ag-chips .btn { border-radius: 999px; }
.wx-attchip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px; border-radius: 999px;
  background: rgba(255, 255, 255, .22); font-size: 11.5px;
}

/* ---------- 16. 工作台入口（两张选择卡） ---------- */
.wbsel { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.wbsel-card {
  display: flex; flex-direction: column; padding: 22px;
  background: var(--card); border: 1px solid var(--border-2); border-radius: 16px;
  box-shadow: var(--shadow-1);
  transition: box-shadow var(--t), transform var(--t);
}
.wbsel-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); }
.wbsel-top { display: flex; align-items: center; gap: 11px; }
.wbsel-name { font-size: 17px; font-weight: 700; letter-spacing: -.02em; }
.wbsel-desc { margin: 14px 0 0; font-size: 13.5px; line-height: 1.7; color: var(--text-2); }
.wbsel-pts { margin: 14px 0 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; }
.wbsel-pts li { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; color: var(--text-3); }
.wbsel-pts svg { flex: 0 0 auto; margin-top: 2px; color: var(--primary-600); }
.wbsel-btn { margin-top: auto; padding-top: 18px; width: 100%; }
@media (max-width: 760px) { .wbsel { grid-template-columns: 1fr; } }

/* ============================================================================
   UI v6.1 — 补齐 sub2api 的「布局结构」（不只是配色）
   ----------------------------------------------------------------------------
   上一轮只搬了配色/组件样式，没搬布局。这层补上它的结构特征：
     1. 侧栏可折叠 256px ↔ 72px（图标栏），宽度带过渡
     2. 顶栏玻璃吸顶（glass sticky top-0 z-30 + 底部细描边）
     3. 顶栏「余额下拉」（sub2api 头部的标志性元素：可用余额 + 明细）
     4. 页面垂直节奏 space-y-6（24px）
   ========================================================================== */

/* ---------- 1. 侧栏折叠态（72px 图标栏） ---------- */
.sidebar { transition: width 300ms cubic-bezier(.4, 0, .2, 1), flex-basis 300ms cubic-bezier(.4, 0, .2, 1); }
.sidebar.collapsed { width: 72px; flex: 0 0 72px; }
.sidebar.collapsed .sb-name,
.sidebar.collapsed .sb-group,
.sidebar.collapsed .sb-label,
.sidebar.collapsed .sb-badge,
.sidebar.collapsed .sb-foot .copy-box { display: none; }
.sidebar.collapsed .sb-brand { justify-content: center; padding: 0 12px; }
/* 底部「深色/退出」的文字也要一起收起（它们是 btn 里的裸 span，没有 sb-label 类） */
.sidebar.collapsed .sb-foot .row .btn > span { display: none; }
.sidebar.collapsed .sb-nav { padding: 16px 8px; }
.sidebar.collapsed .sb-item { justify-content: center; gap: 0; padding: 11px 0; }
.sidebar.collapsed .sb-item svg { width: 22px; height: 22px; }
.sidebar.collapsed .sb-foot { padding: 12px 8px; }
.sidebar.collapsed .sb-foot .row { flex-direction: column; gap: 6px; }
.sidebar.collapsed .sb-foot .row .btn { justify-content: center; }
.sb-toggle { color: var(--text-3); }
.sb-toggle:hover { color: var(--text); }

/* ---------- 2. 顶栏：玻璃吸顶（glass sticky top-0 z-30） ---------- */
.topbar {
  position: sticky; top: 0; z-index: 30;
  height: 64px;
  background: var(--header-bg);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border-2);
}
.tb-title { font-size: 17px; font-weight: 650; letter-spacing: -.02em; }
.tb-sub { font-size: 12px; color: var(--text-3); }

/* ---------- 3. 顶栏余额下拉 ---------- */
.tb-balance {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px; border-radius: 12px;
  border: 1px solid var(--border); background: var(--card);
  font-size: 13px; color: var(--text-2); cursor: pointer;
  transition: border-color var(--t), background var(--t), color var(--t);
}
.tb-balance:hover { border-color: var(--primary-300); background: var(--primary-50); color: var(--text); }
.tb-balance > svg:first-child { color: var(--primary-600); }
.tb-balance b { font-size: 13.5px; font-weight: 650; color: var(--primary-700); }
[data-theme="dark"] .tb-balance b { color: var(--primary-400); }
[data-theme="dark"] .tb-balance:hover { background: rgba(20, 184, 166, .1); }
@media (max-width: 720px) { .tb-balance .tbb-l { display: none; } }

.bal-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding: 12px 14px 10px; font-size: 12.5px; color: var(--text-3);
}
.bal-head b { font-size: 16px; font-weight: 700; color: var(--text); }
.bal-row {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 8px 14px; font-size: 12.5px; color: var(--text-3);
}
.bal-row b { color: var(--text-2); font-weight: 600; }

/* ---------- 4. 页面垂直节奏（space-y-6 = 24px） ---------- */
.page { padding: 24px 32px 72px; }
.page > * + * { margin-top: 24px; }
.card + .card { margin-top: 24px; }
.kpis { margin-bottom: 24px; }
@media (max-width: 900px) {
  .page { padding: 16px 16px 56px; }
  .page > * + * { margin-top: 16px; }
}

/* ============================================================================
   UI v6.2 — logo 白底 + 图标笔画对齐 Heroicons
   ----------------------------------------------------------------------------
   1. 侧栏 logo 的底衬改成白底（原来是青绿渐变方块），加极细描边
   2. 图标已整批换成 sub2api 用的 Heroicons 路径，笔画 1.5（它的默认值）
   ========================================================================== */

/* ---------- logo：白底 ---------- */
.sb-logo {
  background: #fff;
  border: 1px solid var(--border);
  box-shadow: 0 1px 2px rgba(16, 18, 27, .06);
}
[data-theme="dark"] .sb-logo {
  background: #fff;              /* 深色主题下也保持白底，logo 才看得清 */
  border-color: rgba(255, 255, 255, .14);
}
.sb-logo img { width: 24px; height: 24px; }
/* 折叠态下 logo 块同样白底、居中 */
.sidebar.collapsed .sb-logo { width: 40px; height: 40px; flex: 0 0 40px; }

/* ---------- 登录页/工作台等处的 logo 底衬一并统一成白底 ---------- */
.auth-side .logo img {
  background: #fff; border-radius: 10px; padding: 3px;
  width: 36px; height: 36px; object-fit: contain;
}

/* ---------- 图标：Heroicons 是 24 网格 / 1.5 笔画，略调细节更清晰 ---------- */
.sb-item svg { stroke-width: 1.5; }
.btn svg { stroke-width: 1.6; }

/* ============================================================================
   UI v6.3 — 修 KPI 图标块被压扁成长方形
   ----------------------------------------------------------------------------
   v6 里我把 .kpi-ico 重写成 48px 时漏了 flex: 0 0 48px，
   它作为 .kpi-top(display:flex) 的子项被横向压缩 → 背景变成长方形。
   ========================================================================== */
.kpi-ico {
  width: 48px; height: 48px; flex: 0 0 48px; aspect-ratio: 1 / 1;
  border-radius: 12px;
  display: grid; place-items: center;
}
.kpi-ico svg { width: 22px; height: 22px; }
.kpi-top { align-items: center; }
@media (max-width: 640px) {
  .kpi-ico { width: 40px; height: 40px; flex: 0 0 40px; }
  .kpi-ico svg { width: 19px; height: 19px; }
}
/* 其它「图标块」也统一锁方形，避免同类问题 */
.card-hico, .tile .t-ico, .tip .ti, .ag-tico { aspect-ratio: 1 / 1; }

/* ============================================================================
   UI v6.4 — 移动端修复
   ----------------------------------------------------------------------------
   1. 手机上必须隐藏 256px 侧栏：原 CSS 在 @media(max-width:768px) 里写了
      .sidebar{display:none}，但我的 v6 层在文件更后面又写了 .sidebar{display:flex}
      → 同优先级、后者生效，把移动端的隐藏规则覆盖掉了，侧栏直接挤进 375px 屏幕。
   2. 顺手加窄屏「不许横向溢出」的兜底（接入文档页有 7px 溢出）。
   ========================================================================== */

@media (max-width: 768px) {
  /* 手机上导航走抽屉（.m-drawer）+ 底部 tabbar，侧栏一律不显示 */
  .sidebar { display: none !important; }
  .main { width: 100%; min-width: 0; }
}

@media (max-width: 768px) {
  /* 窄屏兜底：长 URL / 等宽文本不许把容器撑破 */
  .field, .copy-box, .panel, .card, .tile,
  .field > label, .field > span { min-width: 0; max-width: 100%; }
  .field input, .field select, .field textarea { min-width: 0; width: 100%; }
  .copy-box { overflow: hidden; }
  .copy-box .v, .copy-box .mono, .kv-row .v, .rows .r > .v {
    overflow-wrap: anywhere; word-break: break-all; min-width: 0;
  }
  .page > * { min-width: 0; }
  .row.wrap, .tb-right { flex-wrap: wrap; }
  /* 顶栏在窄屏少放点东西，别挤成一团 */
  .topbar { padding: 0 14px; }
  .tb-sub { display: none; }
  .tb-right { gap: 6px; }
  .tb-right .btn { padding: 6px 10px; }
  /* 卡片与指标块的内边距收一档，窄屏更透气 */
  .card-b { padding: 16px; }
  .card-h { padding: 14px 16px; }
  .kpi { padding: 16px; }
  .tile { padding: 15px 16px; }
  /* 表格横向滚动而不是撑破页面 */
  .tbl-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

/* ---------- v6.5 补充：窄屏分段控件/卡片头换行，别把页面撑宽 ---------- */
@media (max-width: 768px) {
  .seg { flex-wrap: wrap; max-width: 100%; }
  .seg button { flex: 1 1 auto; }
  .card-h { flex-wrap: wrap; }
  .card-h .sp { margin-left: 0; width: 100%; }
  .filter-opts { flex-wrap: wrap; }
}
/* 窄屏：KPI 数字很长时别折成两行（余额等大数） */
@media (max-width: 768px) {
  .kpi-val { font-size: 20px; overflow-wrap: anywhere; }
  .tile .t-v { font-size: 20px; overflow-wrap: anywhere; }
  .stat-value, .stat-item b { font-size: 20px; }
}

/* ============================================================================
   UI v6.6 — 顶栏对齐修正 + 余额挪进用户下拉
   ----------------------------------------------------------------------------
   1. 原 .topbar 是 flex + flex-wrap:wrap + 固定高度：余额胶囊比按钮高，
      一旦换行内容就被挤到下面（用户看到的"余额和名字偏下"）。
      现在：桌面不允许换行、所有子项统一 34px 高并垂直居中。
   2. 按用户要求，余额从顶栏移出，改为放在用户下拉菜单顶部（可用/累计充值/累计消费）。
   ========================================================================== */

.topbar {
  display: flex; align-items: center; flex-wrap: nowrap; gap: 12px;
  height: 64px; padding: 0 28px;
}
.tb-left { min-width: 0; flex: 1 1 auto; }
.tb-right { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-wrap: nowrap; }
/* 顶栏右侧所有子项等高、垂直居中，避免高低差 */
.tb-right > .btn,
.tb-right > .menu-wrap,
.tb-right > a.btn {
  height: 34px; display: inline-flex; align-items: center;
}
.tb-right .menu-wrap > .btn { height: 34px; }
.tb-right .btn > .avatar { width: 22px; height: 22px; }

/* 用户下拉里的「头像 + 用户名 + 余额」区 */
.user-head {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 14px 12px;
}
.user-head .avatar { width: 34px; height: 34px; font-size: 14px; }
.uh-txt { min-width: 0; }
.uh-txt b { display: block; font-size: 13.5px; font-weight: 650; color: var(--text); }
.uh-txt span { display: block; margin-top: 1px; font-size: 11.5px; color: var(--text-4); }
.menu > .uh-bal {
  margin: 0 8px 6px; padding: 10px 12px;
  border-radius: 12px; background: var(--card-3);
}
.uh-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  font-size: 12.5px; color: var(--text-3);
}
.uh-row + .uh-row { margin-top: 6px; }
.uh-row b { font-size: 13px; font-weight: 650; color: var(--text); }
.uh-row:first-child b { color: var(--primary-600); }

/* 窄屏：允许换行、高度自适应（此时已没有余额胶囊，通常也不会换行了） */
@media (max-width: 768px) {
  .topbar { flex-wrap: wrap; height: auto; min-height: 56px; padding: 10px 14px; gap: 8px; }
  .tb-right { flex-wrap: wrap; }
}
/* 用户下拉里的余额行：菜单太窄会把「可用余额」挤成竖排，这里加宽并禁止换行 */
#userMenu { min-width: 272px; }
.uh-row { white-space: nowrap; }
.uh-row > span { flex: 0 0 auto; color: var(--text-3); }
.uh-row > b { flex: 0 1 auto; white-space: nowrap; font-size: 12.5px; }
.uh-txt b, .user-head .uh-txt span { white-space: nowrap; }

/* ============================================================================
   UI v7 — AI 工作台：代码块可读性 + 复制按钮 + 思考行不换行
   ----------------------------------------------------------------------------
   1. 代码块「看不见字」的根因：原样式是深色底(#141826)+浅色字(#d6ddfb)，
      我 v6 只覆盖了 background 为浅色、没覆盖 color → 浅字浅底 = 看不见。
      这里把背景与文字色成对写死，避免再被单边覆盖。
   2. 复制按钮：工具调用的「输入/输出」各一个 + AI 回复下方一个。
   3. 手机上「已深度思考」折成两行：加 nowrap 并收紧缩进/字号。
   ========================================================================== */

/* ---------- 1. 代码块：浅色底 + 深色字（配色成对，防止再被拆开） ---------- */
.ag-code, .ag-out, .wx-body pre {
  background: var(--card-3) !important;
  color: var(--text) !important;
  border: 1px solid var(--border) !important;
  border-radius: 10px;
  font-family: var(--mono);
  font-size: 12px; line-height: 1.7;
  padding: 11px 13px;
  white-space: pre-wrap; word-break: break-word; overflow-wrap: anywhere;
  max-height: 340px; overflow: auto;
}
.ag-out { color: var(--text-2) !important; }
[data-theme="dark"] .ag-code, [data-theme="dark"] .ag-out, [data-theme="dark"] .wx-body pre {
  background: #0b0f1a !important;
  color: #e5eaf7 !important;
  border-color: rgba(255, 255, 255, .1) !important;
}
[data-theme="dark"] .ag-out { color: #9fe0be !important; }

/* 「输入 / 输出」标签行：文字 + 右侧复制按钮 */
.ag-tlabel {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 2px 4px; font-size: 11px; font-weight: 600;
  color: var(--text-4); letter-spacing: .04em;
}
.ag-tsec { padding: 0 12px 10px; }
.ag-tsec .ag-code, .ag-tsec .ag-out { margin: 0 !important; }

/* ---------- 2. 复制按钮 ---------- */
/* 复制按钮：纯图标（文案只在 title 里）。
   原来是「图标 + 复制」两字的长胶囊，太占地方；现在做成 24×24 的方形图标按钮，
   触摸目标也够（手机上 24px 偏小，768 断点里再放大到 30px）。 */
.ag-cp {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
  width: 24px; height: 24px;
  margin-left: auto;
  padding: 0; border-radius: 7px;
  border: 1px solid var(--border); background: var(--card);
  color: var(--text-3); cursor: pointer; transition: all var(--t);
}
.ag-cp:hover { color: var(--primary-600); border-color: var(--primary-300); background: var(--primary-50); }
.ag-cp:active { transform: scale(.94); }
.ag-cp svg { width: 13px; height: 13px; }
/* AI 回复下方那一个稍微明显一点 */
.msg-acts { display: flex; margin-top: 6px; }
.msg-acts .ag-cp { margin-left: 0; }

/* ---------- 3. 思考行 / 工具行：始终一行 ---------- */
.ag-think > summary, .ag-tool > summary {
  white-space: nowrap; flex-wrap: nowrap; overflow: hidden;
}
.ag-think > summary > .ag-tstat,
.ag-tool > summary > .ag-tstat { flex: 0 0 auto; }

@media (max-width: 768px) {
  /* 手机上缩进收一档，给标签和状态留出空间，避免折行 */
  .wx-body > .ag-tool, .wx-body > .ag-think {
    margin-left: 20px; max-width: calc(100% - 24px);
  }
  .ag-think > summary, .ag-tool > summary { padding: 7px 10px; gap: 7px; font-size: 12px; }
  .ag-tstat { font-size: 10.5px; padding: 1px 7px; }
  .ag-tname { font-size: 12px; }
  .ag-tico { width: 20px; height: 20px; flex: 0 0 20px; }
  /* 纯图标的复制按钮在手机上放大到 30×30，手指才点得准 */
  .ag-cp { width: 30px; height: 30px; border-radius: 9px; }
  .ag-cp svg { width: 15px; height: 15px; }
}

/* ============================================================================
   UI v8 — 人机校验弹窗（点「获取验证码」弹出 → 打勾动画 → 丝滑收回）
   ----------------------------------------------------------------------------
   按站长要求：表单里不再内嵌验证码图，也不提供"点图片换一张"。
   ========================================================================== */

/* 人机校验弹窗是「从一个弹窗里再开出来的」第二层弹窗：
   注册流程里它直接盖在登录页上，但找回密码流程里它必须盖在
   #resetOverlay（class 就是 .overlay，z-index 90）之上，
   否则会被主弹窗压住 —— 用户看到的是「弹到外面去了、点不着」。
   所以这里必须大于 90；保持小于 .toasts(120)，让提示条始终在最上面。 */
.cap-overlay {
  display: grid; place-items: center; z-index: 100;
  animation: capFade .18s ease-out;
}
.cap-overlay.out { animation: capFadeOut .2s ease-in forwards; }
/* 通用弹窗的关闭动画：closePwdReset 会给 #resetOverlay 加上 .out 再延迟 200ms 移除，
   少了这条就只是「等 200ms 然后突然消失」，和上面人机校验弹窗的手感不一致。 */
.overlay.out { animation: capFadeOut .2s ease-in forwards; }

.cap-modal {
  position: relative;
  width: min(380px, calc(100vw - 32px));
  border-radius: 20px; box-shadow: var(--shadow-3);
  animation: capPop .24s cubic-bezier(.2, .9, .3, 1.15);
}
.cap-body { padding: 22px 22px 20px; text-align: center; }
.cap-body > * { transition: opacity .18s ease; }
.cap-body.done > *:not(.cap-success) { opacity: 0; }

.cap-head {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font-size: 15px; font-weight: 650; color: var(--text);
}
.cap-head svg { width: 18px; height: 18px; color: var(--primary-600); }
.cap-tip { margin: 9px 0 16px; font-size: 12.5px; color: var(--text-3); line-height: 1.6; }

/* 验证码图：不可点、不可选（去掉了「点一下换一张」） */
.cap-img-lg {
  display: grid; place-items: center;
  min-height: 64px; padding: 10px;
  border-radius: 14px; background: var(--card-3);
  overflow: hidden; user-select: none; cursor: default;
}
/* 弹窗里的验证码：后端下发的是 PNG 位图（早期是 SVG，但 SVG 里字符是明文，
   一条正则就能把答案提出来）。img 必须和 svg 共用同一套尺寸规则 ——
   少写这条的话 img 会按原始像素(245×75)铺开，窄屏上直接撑破弹窗。 */
.cap-img-lg svg, .cap-img-lg img {
  width: 100%; max-width: 224px; height: auto; display: block;
  -webkit-user-drag: none;
}
.cap-img-lg.loading { color: var(--text-4); font-size: 12.5px; }

.cap-input {
  margin-top: 14px; height: 46px;
  text-align: center; letter-spacing: .28em; text-transform: uppercase;
  font-family: var(--mono); font-size: 17px;
}
.cap-err { min-height: 17px; margin-top: 8px; font-size: 12px; color: var(--danger); }
.cap-btns { display: flex; gap: 10px; margin-top: 10px; }
.cap-btns .btn { flex: 1; height: 42px; }

/* ---------- 打勾动画：圆圈先描出来，接着对勾从起点画到终点 ---------- */
.cap-success {
  position: absolute; inset: 0;
  display: grid; place-items: center; align-content: center; gap: 10px;
  background: var(--card); border-radius: 20px;
  animation: capFade .2s ease-out;
}
.cap-success[hidden] { display: none; }
.cap-check { width: 76px; height: 76px; }
.cap-check circle {
  fill: none; stroke: var(--primary); stroke-width: 2.4;
  stroke-dasharray: 145; stroke-dashoffset: 145;
  animation: capDraw .5s ease-out forwards;
}
.cap-check path {
  fill: none; stroke: var(--primary); stroke-width: 3;
  stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 42; stroke-dashoffset: 42;
  animation: capDraw .36s .48s ease-out forwards;
}
.cap-success-t {
  font-size: 13.5px; font-weight: 600; color: var(--primary-600);
  opacity: 0; animation: capFade .32s .72s ease-out forwards;
}

@keyframes capDraw { to { stroke-dashoffset: 0; } }
@keyframes capFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes capFadeOut { from { opacity: 1; } to { opacity: 0; } }
@keyframes capPop {
  from { opacity: 0; transform: translateY(8px) scale(.97); }
  to { opacity: 1; transform: none; }
}

@media (max-width: 480px) {
  /* 不能写 calc(100vw - 24px)：.overlay 自己有 24px padding，
     .modal 在 768 断点又加了 12px 外边距，减 24 仍然会顶出屏幕。
     宽度交给文件末尾那条统一的移动端规则（.cap-modal { width: 100% }）。 */
  .cap-modal { border-radius: 18px; }
  .cap-body { padding: 20px 18px 18px; }
  .cap-input { height: 44px; font-size: 16px; }
}

/* ============================================================================
   UI v9 — 站内通知铃铛 + 工单
   ========================================================================== */

/* 铃铛按钮与未读红点 */
.bell { position: relative; }
.bell-dot {
  position: absolute; top: 5px; right: 4px;
  min-width: 16px; height: 16px; padding: 0 4px;
  display: grid; place-items: center;
  border-radius: 999px; background: var(--danger); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 1;
  box-shadow: 0 0 0 2px var(--card);
}

/* 通知面板 */
.notice-menu { width: 340px; max-width: calc(100vw - 24px); padding: 0; overflow: hidden; }
.nm-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 14px; border-bottom: 1px solid var(--border-2);
  font-size: 13.5px; font-weight: 650;
}
.nm-all {
  border: none; background: transparent; color: var(--primary-600);
  font-size: 12px; font-weight: 600; cursor: pointer; padding: 2px 6px; border-radius: 6px;
}
.nm-all:hover { background: var(--primary-50); }
.nm-list { max-height: 380px; overflow-y: auto; }
.nm-item { padding: 11px 14px; border-bottom: 1px solid var(--border-2); cursor: pointer; transition: background var(--t); }
.nm-item:last-child { border-bottom: none; }
.nm-item:hover { background: var(--card-2); }
.nm-item.unread { background: var(--primary-50); }
.nm-item.unread:hover { background: var(--primary-100); }
.nm-title { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; color: var(--text); }
.nm-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--danger); flex: 0 0 6px; }
.nm-body { margin-top: 4px; font-size: 12.5px; color: var(--text-3); line-height: 1.6; }
.nm-time { margin-top: 5px; font-size: 11.5px; color: var(--text-4); }
.nm-empty { padding: 36px 16px; text-align: center; color: var(--text-4); font-size: 12.5px; }
.nm-empty svg { display: block; margin: 0 auto 8px; opacity: .5; }
.notice-text { font-size: 13.5px; line-height: 1.8; color: var(--text-2); max-height: 60vh; overflow: auto; }

/* 工单对话 */
.tk-meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.tk-thread { display: flex; flex-direction: column; gap: 10px; max-height: 46vh; overflow-y: auto; padding-right: 4px; }
.tk-msg { max-width: 86%; padding: 10px 13px; border-radius: 14px 14px 14px 5px; background: var(--card-3); }
.tk-msg.admin { align-self: flex-end; border-radius: 14px 14px 5px 14px; background: var(--primary-50); }
.tk-msg-h { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.tk-msg-h b { font-size: 12.5px; font-weight: 650; color: var(--text); }
.tk-msg-h span { font-size: 11px; color: var(--text-4); }
.tk-msg-b { font-size: 13px; line-height: 1.75; color: var(--text-2); word-break: break-word; }

@media (max-width: 768px) {
  /* 铃铛面板：原样式虽然写了 width:100vw-20px，但 .menu 仍是 absolute + right:0，
     锚点是「铃铛图标」而不是屏幕右边——铃铛在 tb-right 里不靠最右，
     于是面板左边被挤出屏幕，标题「充值满 100 送 20」被裁成「值满 100 送 20」。
     手机上改成贴着视口左右边缘的浮层，并避开吸顶顶栏的高度。 */
  .notice-menu {
    position: fixed;
    left: 10px; right: 10px; top: 60px;
    width: auto; max-width: none;
    max-height: calc(100vh - 90px);
  }
  .nm-list { max-height: calc(100vh - 152px); }
  .tk-msg { max-width: 94%; }
}

/* ============================================================================
   忘记密码 / 重置密码（v9）
   ----------------------------------------------------------------------------
   三步弹窗复用 .cap-modal 的视觉语言（同一个 overlay、同一套按钮），
   额外需要的只有：步骤条、用户名提示条、成功页。

   注意 .cap-body.done 那条规则是把「除成功动画以外的子元素全部淡出」，
   所以成功页不能直接塞进 cap-success 里，而是独立一块 .rst-done-*。
   ========================================================================== */
/* 宽度用 min() 兜底：桌面 420px，窄屏自动收到可用宽度内。
   注意外层 .overlay 有 24px padding，所以这里的 100vw - 32px 是安全余量。 */
.rst-modal { width: min(420px, calc(100vw - 32px)); }
.rst-modal .cap-body { text-align: left; }
.rst-modal .cap-head { justify-content: flex-start; }

/* ---- 步骤条 ---- */
.rst-steps {
  display: flex; align-items: center; gap: 6px;
  margin: 2px 0 18px; font-size: 12px; color: var(--muted);
}
.rst-step { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.rst-step i {
  width: 20px; height: 20px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-style: normal; font-size: 11.5px; font-weight: 700;
  background: var(--surface-2, #f1f2f6); color: var(--muted);
  border: 1px solid var(--line);
  transition: background .2s ease, color .2s ease, transform .2s ease;
}
.rst-step.on { color: var(--text); font-weight: 600; }
.rst-step.on i { background: var(--brand, #5b5bd6); color: #fff; border-color: transparent; }
.rst-step.done { color: var(--muted); }
.rst-step.done i { background: #e8f6ee; color: #1f7a45; border-color: #cfe8d7; }
.rst-line { flex: 1; height: 1px; background: var(--line); min-width: 10px; }

/* ---- 第③步：验证码行 + 倒计时按钮 ---- */
.rst-modal .code-row > input { height: 44px; }
.rst-modal .code-row > .btn { min-width: 108px; height: 44px; }

/* ---- 校验通过后显示的用户名条 ---- */
.rst-name {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin-top: 12px; padding: 11px 13px;
  background: #f2f3fd; border: 1px solid #dcdcf8; border-radius: 10px;
  font-size: 13px; color: var(--text);
  animation: rstIn .22s ease;
}
.rst-name[hidden] { display: none; }
.rst-name svg { color: var(--brand, #5b5bd6); flex: 0 0 auto; }
.rst-name b { font-size: 14px; }
.rst-name-tip { display: block; width: 100%; margin-top: 2px; font-size: 11.5px; color: var(--muted); }
@keyframes rstIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

/* ---- 弹窗底部说明 ---- */
.rst-foot {
  margin-top: 14px; font-size: 11.5px; line-height: 1.75; color: var(--muted);
}
.rst-foot b { color: var(--text); }

/* ---- 成功页 ---- */
.rst-modal .cap-body.done { text-align: center; }
/* 关键：.cap-body.done > *:not(.cap-success) { opacity: 0 } 是为了「打勾动画期间
   把表单淡出」，但那条规则的落点靠的是「内容都塞在 .cap-success 里」。
   找回密码的成功页是直接铺在 .cap-body.done 上的（没套 .cap-success 这层
   绝对定位覆盖层），所以会被整片淡成透明 —— 页面看起来就是一片空白。
   这里逐项把透明度收回来。 */
.rst-modal .cap-body.done > .cap-check,
.rst-modal .cap-body.done > .rst-done-t,
.rst-modal .cap-body.done > .rst-done-sub,
.rst-modal .cap-body.done > .rst-done-mail,
.rst-modal .cap-body.done > .rst-foot,
.rst-modal .cap-body.done > .cap-btns { opacity: 1; }
.rst-check {
  margin: 6px auto 12px;
  animation: rstPop .3s cubic-bezier(.2, .9, .3, 1.3);
}
@keyframes rstPop { from { opacity: 0; transform: scale(.82); } to { opacity: 1; transform: none; } }
.rst-done-t { font-size: 17px; font-weight: 700; color: var(--text); }
.rst-done-sub { margin-top: 8px; font-size: 13px; color: var(--muted); }
.rst-done-sub b { color: var(--text); }
.rst-done-mail {
  margin-top: 10px; padding: 10px 12px;
  background: #eef7f0; border: 1px solid #cfe8d7; border-radius: 10px;
  font-family: var(--mono); font-size: 13.5px; color: #1f7a45;
  word-break: break-all;
}

@media (max-width: 768px) {
  /* 外层 .overlay 自带 24px padding，.modal 在这个断点又被加了 12px 左右外边距。
     这里若再写 calc(100vw - 24px) 就会「视口宽 - 24」再被 padding/margin 顶出去，
     实测 390px 视口下右边界会跑到 402px 造成横向滚动。所以移动端一律用
     width:100% 吃满 overlay 的可用宽度，由 overlay 的 padding 负责两侧留白。

     ⚠️ .cap-modal 这条不能漏：人机校验弹窗用的是裸 .cap-modal，
     它在 ≤480 还有一条 `width: calc(100vw - 24px)`，两条一叠加同样顶出去。
     .rst-modal（忘记密码）只是继承 .cap-modal，所以两个都要写。 */
  .cap-modal,
  .rst-modal { width: 100%; max-width: 100%; margin-left: 0; margin-right: 0; }
  .rst-modal .code-row > input { height: 46px; font-size: 16px; }
  .rst-modal .code-row > .btn { min-width: 100px; height: 46px; }
  .rst-steps { font-size: 11px; gap: 4px; }
  .rst-step i { width: 18px; height: 18px; font-size: 10.5px; }
}
