/* views.css — 六个视图 + 生成中占位 + 弹层
   [local patch 2026-09-21] 视图模块早就写好了，但 HTML 没容器、CSS 没样式、main.js
   没接线，所以「今日」「设置」永远显示"视图正在建设中"。这里补齐视图侧样式，
   沿用 tokens.css 的令牌与四语义色（青/品红/绿/红），不加装饰色、不用渐变。 */

/* ── 视图容器：同一时刻只显示一个 ───────────────────────────── */
.view {
  display: none;
  flex: 1;
  min-height: 0;
  flex-direction: column;
  animation: viewEnter var(--dur-slow) var(--ease-out);
}
.view.active {
  display: flex;
}
@keyframes viewEnter {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* 非对话视图自己滚动 */
#view-today, #view-settings, #view-coding, #view-office, #view-skills {
  overflow-y: auto;
  padding: var(--sp-4);
  scroll-behavior: smooth;
}
/* ★ 技能页原来**漏在这条规则外面**（2026-10-22 用户报「卡片和两侧侧栏
 *   挤在一起」）：没有 padding → 卡片左边缘正好贴着左侧栏右边缘，
 *   右边也顶到右侧信息栏。真机实测 gapLeft=0 / gridGapLeft=0，
 *   而办公页两边都是 16px（--sp-4）。同一份规则里补上它即可，
 *   间距就跟办公页一模一样了。 */

/* ── 生成中占位气泡 ─────────────────────────────────────────── */
.item-agent.generating {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-3) 0;
}
.gen-text {
  color: var(--text-dim);
  font-size: var(--text-sm);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.dots { display: inline-flex; gap: 3px; }
.dots i {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--user);
  animation: dotPulse 1.4s ease-in-out infinite;
}
.dots i:nth-child(2) { animation-delay: .16s; }
.dots i:nth-child(3) { animation-delay: .32s; }
@keyframes dotPulse {
  0%, 80%, 100% { opacity: .3; transform: scale(0.8); }
  40% { opacity: 1; transform: scale(1); }
}

/* Skeleton loading lines for generating state */
.gen-skeleton {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin-top: var(--sp-2);
}
.gen-skeleton-line {
  height: 14px;
  background: var(--skeleton-base);
  border-radius: var(--r-sm);
  position: relative;
  overflow: hidden;
}
.gen-skeleton-line::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, var(--skeleton-shine), transparent);
  animation: skeleton-shimmer 1.5s ease-in-out infinite;
}
.gen-skeleton-line:nth-child(1) { width: 85%; }
.gen-skeleton-line:nth-child(2) { width: 70%; }
.gen-skeleton-line:nth-child(3) { width: 60%; }

.btn:disabled { opacity: .45; cursor: not-allowed; }

/* ── 兜底占位 ───────────────────────────────────────────────── */
.placeholder { color: var(--text-faint); padding: var(--sp-5); }
.placeholder b { display: block; color: var(--text-dim); margin-bottom: var(--sp-2); }
.placeholder p { margin: 0; }

/* ── 轻提示 ─────────────────────────────────────────────────── */
.toast {
  position: fixed; left: 50%; bottom: 28px;
  transform: translateX(-50%) translateY(20px);
  background: var(--surface-2); color: var(--text);
  border: var(--bw) solid var(--border);
  border-radius: var(--r-lg);
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--text-sm);
  opacity: 0; pointer-events: none;
  transition: opacity var(--dur-slow) var(--ease),
              transform var(--dur-slow) var(--ease-spring);
  z-index: 50;
  box-shadow: var(--shadow-lg);
  max-width: 90vw;
  text-align: center;
}
.toast.show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* ── 今日视图 ───────────────────────────────────────────────── */
.dashboard { max-width: 760px; }
.dash-hello {
  font-size: var(--text-lg); color: var(--text);
  margin-bottom: var(--sp-5);
}
.dash-card {
  background: transparent;
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: var(--bw) solid var(--glass-border);
  border-left: 3px solid var(--user);
  border-radius: var(--r-lg);
  padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-2);
  box-shadow: var(--glass-shadow), var(--glass-inner-glow);
  transition: border-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              transform var(--dur) var(--ease),
              background var(--dur) var(--ease);
}
.dash-card:hover {
  background: var(--glass-bg-hover);
  box-shadow: var(--shadow-md);
  border-color: var(--glass-border-strong);
  transform: translateY(-2px);
}
.dash-card.done {
  border-left-color: var(--success);
  opacity: .6;
}
.dash-card.done:hover {
  opacity: .8;
}
.dash-card.overdue {
  border-left-color: var(--danger);
}
.dash-todo-list { display: flex; flex-direction: column; }
.todo-item {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--text-base); color: var(--text);
}
.todo-item .ic { color: var(--text-faint); }
.todo-item .num {
  font-family: var(--font-mono); font-size: var(--text-xs);
  color: var(--text-faint);
}
.todo-item .meta { margin-left: auto; font-size: var(--text-xs); color: var(--text-faint); }
.dash-suggestions { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-4); }
.dash-chip {
  background: var(--surface-2); color: var(--text-dim);
  border: var(--bw) solid var(--border); border-radius: var(--r-full);
  padding: var(--sp-1) var(--sp-3);
  font-size: var(--text-sm); cursor: pointer;
  font-family: inherit;
}
.dash-chip:hover { border-color: var(--user); color: var(--user); }

/* ── 今日视图（待办/日程，重设计稿 §1.1） ─────────────────── */
.dash-overview { color: var(--text-dim); font-size: var(--text-sm); margin-bottom: var(--sp-3); }
.dash-card-title {
  font-size: var(--text-base); color: var(--text);
  margin-bottom: var(--sp-2); font-weight: 600;
}
.dash-loading { color: var(--text-faint); font-size: var(--text-sm); padding: var(--sp-3) 0; }
.affair-list { margin-bottom: var(--sp-2); }
.affair-row {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-1) 0; font-size: var(--text-base);
}
.affair-row.is-done .affair-text { color: var(--text-faint); text-decoration: line-through; }
.affair-check {
  border: none; background: transparent; cursor: pointer;
  width: 22px; text-align: center; font-size: var(--text-base);
  color: var(--text-faint); font-family: inherit; padding: 0;
}
.affair-row.is-done .affair-check { color: var(--success); }
.affair-check:hover { color: var(--user); }
.affair-text { flex: 1; color: var(--text); word-break: break-all; }
.affair-when { color: var(--text-faint); font-size: var(--text-sm); font-family: var(--font-mono); }
.affair-del {
  border: none; background: transparent; cursor: pointer;
  color: var(--text-faint); font-size: var(--text-sm);
  font-family: inherit; padding: 0 var(--sp-1); visibility: hidden;
}
.affair-row:hover .affair-del { visibility: visible; }
.affair-del:hover { color: var(--danger); }
.affair-empty { color: var(--text-faint); font-size: var(--text-sm); padding: var(--sp-2) 0; }
.affair-add { display: flex; gap: var(--sp-2); margin-top: var(--sp-2); }
.affair-input {
  flex: 1; background: var(--bg); border: var(--bw) solid var(--border);
  border-radius: var(--r-md); color: var(--text);
  padding: var(--sp-1) var(--sp-3); font-family: inherit; font-size: var(--text-base);
  outline: none;
}
.affair-input:focus { border-color: var(--user); }
.affair-time { flex: none; color-scheme: dark; }
.affair-add-btn { padding: var(--sp-1) var(--sp-4); }

/* ── 项目视图：新建项目 / 指定文件夹 ────────────────────────── */
/* [2026-09-28] 用户反馈「项目里没有新建项目和指定文件夹的按钮入口」，补两个真入口。
   .affair-add / .affair-input / .dash-chip 直接复用「今日」那套，保持一致。 */
.proj-actions { display: flex; gap: var(--sp-2); margin: var(--sp-3) 0 var(--sp-1); }

/* 「路径怎么拿」那句说明要**独占一整行**（2026-10-01）。
   `.affair-add` 是横向 flex、且没开换行：说明塞进去就成了第 4 个控件，
   把输入框和两个按钮挤成窄条 —— 实测输入框只剩一个「例」字可见、
   「浏览…」「加进来」被压成竖排两行。判据全绿，是**截图**才看出来的。
   只改这一处而不动 `.affair-add`：那个类是「今日」页共用的，
   全局加 flex-wrap 会连带改到那页的布局。 */
#proj-add-form { flex-wrap: wrap; }
#proj-add-form .set-note { flex: 1 0 100%; }
.dash-chip.is-on { border-color: var(--user); color: var(--user); }

/* ── 设置视图 — 毛玻璃面板 ──────────────────────────────────── */
.sec {
  background: transparent;
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: var(--bw) solid var(--glass-border);
  border-radius: var(--r-md);
  padding: var(--sp-4);
  margin-bottom: var(--sp-3);
  max-width: 760px;
  box-shadow: var(--glass-shadow), var(--glass-inner-glow);
}
/* 七行设置（重设计稿 §4.6）：label + 状态 */
.set-row {
  display: flex; align-items: baseline; gap: var(--sp-3);
  padding: var(--sp-2) 0; border-top: var(--bw) solid var(--border);
}
.set-row:first-of-type { border-top: none; }
.set-label { flex: none; width: 110px; color: var(--text-dim); font-size: var(--text-base); }
.set-status { flex: 1; color: var(--text); font-size: var(--text-base); line-height: 1.6; }
.set-status label { margin-right: var(--sp-3); cursor: pointer; }
.set-note { color: var(--text-faint); font-size: var(--text-sm); }
.set-details { padding: var(--sp-1) 0 var(--sp-2) 123px; }
.set-details summary {
  color: var(--text-faint); font-size: var(--text-sm); cursor: pointer;
  margin-bottom: var(--sp-2);
}
/* 记忆管理页 */
.mem-head { display: flex; align-items: baseline; gap: var(--sp-3); margin-bottom: var(--sp-3); }
.mem-back { font-size: var(--text-sm); }
.mem-search { max-width: 360px; margin-bottom: var(--sp-3); }
.mem-group {
  background: var(--surface); border: var(--bw) solid var(--border);
  border-radius: var(--r-md); padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-3); max-width: 760px;
}
.mem-loc {
  flex: none; color: var(--text-faint); font-size: var(--text-xs);
  border: var(--bw) solid var(--border); border-radius: var(--r-sm);
  padding: 0 var(--sp-1); white-space: nowrap;
}
.mem-row .affair-del { visibility: visible; }
.mem-junk { border-color: var(--danger); }
.mem-junk .dash-card-title { color: var(--danger); font-weight: 400; font-size: var(--text-sm); }
.mem-junk-actions { display: flex; gap: var(--sp-2); margin-top: var(--sp-2); }
.mem-foot { color: var(--text-faint); font-size: var(--text-sm); max-width: 760px; }
.sec > h2, .sec > .sec-title {
  font-size: var(--text-md); color: var(--text);
  margin: 0 0 var(--sp-3); font-weight: 600;
}
.field { margin-bottom: var(--sp-3); }
.field .label, .field > label {
  display: block; font-size: var(--text-xs); color: var(--text-faint);
  margin-bottom: var(--sp-1);
}
.field select, .field input[type="text"], .field input[type="number"] {
  background: var(--bg); color: var(--text);
  border: var(--bw) solid var(--border); border-radius: var(--r-sm);
  padding: var(--sp-1) var(--sp-2);
  font-family: inherit; font-size: var(--text-sm);
  min-width: 220px;
}
.field .hint, .field .tip { font-size: var(--text-xs); color: var(--text-faint); margin-top: var(--sp-1); }
.save-btn, .preset-btn {
  background: var(--surface-2); color: var(--text);
  border: var(--bw) solid var(--border); border-radius: var(--r-sm);
  padding: var(--sp-1) var(--sp-3);
  font-family: inherit; font-size: var(--text-sm); cursor: pointer;
}
.save-btn { border-color: var(--user); color: var(--user); }
.save-btn:hover, .preset-btn:hover { background: var(--bg); }
.tabs { display: flex; gap: var(--sp-1); border-bottom: var(--bw) solid var(--border); margin-bottom: var(--sp-3); }
.tab {
  background: transparent; border: none; border-bottom: 2px solid transparent;
  color: var(--text-faint); font-family: inherit; font-size: var(--text-sm);
  padding: var(--sp-2) var(--sp-3); cursor: pointer;
}
.tab.active { color: var(--user); border-bottom-color: var(--user); }

/* ── 记忆视图 ───────────────────────────────────────────────── */
.search-bar { display: flex; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.search-bar input {
  flex: 1; max-width: 420px;
  background: var(--bg); color: var(--text);
  border: var(--bw) solid var(--border); border-radius: var(--r-sm);
  padding: var(--sp-2) var(--sp-3);
  font-family: inherit; font-size: var(--text-sm);
}
.mem-card {
  background: transparent;
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: var(--bw) solid var(--glass-border);
  border-left: var(--bw-accent) solid var(--agent);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-2);
  max-width: 760px;
  box-shadow: var(--glass-shadow), var(--glass-inner-glow);
}
.mem-ops { display: flex; gap: var(--sp-2); margin-top: var(--sp-2); }
.mem-op {
  background: transparent; border: var(--bw) solid var(--border); border-radius: var(--r-sm);
  color: var(--text-dim); font-family: inherit; font-size: var(--text-xs);
  padding: 0 var(--sp-2); cursor: pointer;
}
.mem-op:hover { border-color: var(--user); color: var(--user); }

/* ── 编码视图 ───────────────────────────────────────────────── */
.coding-topbar {
  display: flex; align-items: center; gap: var(--sp-2);
  font-size: var(--text-xs); color: var(--text-faint);
  margin-bottom: var(--sp-3);
}
.coding-layout { display: flex; gap: var(--sp-3); align-items: flex-start; }
.coding-left { flex: 1; min-width: 0; }
.coding-right { width: 240px; flex-shrink: 0; }

/* ── 办公视图 ───────────────────────────────────────────────── */
.office-intro { color: var(--text-dim); font-size: var(--text-sm); margin-bottom: var(--sp-4); max-width: 760px; }
.cap-grid {
  display: grid; gap: var(--sp-2);
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  /* 原来这里还有 `max-width: 980px`（没有 margin:auto）—— 于是网格**整体贴左**、
     右边空一大片，看上去"左右距离不一样"（2026-10-02 用户报的）。
     去掉它：网格铺满视图宽度，左右留白由视图自己的 padding 决定，两边一致；
     上面的 intro 文字也是从左边缘起的，两者对齐。 */
}
.cap-card {
  background: transparent;
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border: var(--bw) solid var(--glass-border);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
  cursor: pointer;
  box-shadow: var(--glass-shadow), var(--glass-inner-glow);
  transition: border-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              transform var(--dur) var(--ease),
              background var(--dur) var(--ease);
}
.cap-card:hover {
  background: var(--glass-bg-hover);
  border-color: var(--user);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}
.cap-name { font-size: var(--text-base); color: var(--text); margin-bottom: var(--sp-1); }
.cap-desc { font-size: var(--text-xs); color: var(--text-dim); margin-bottom: var(--sp-2); }
/* 「展开正文预览」在技能页是 <button>（skills.js）—— 浏览器默认给它一层
 * 灰底 + outset 边框（Chromium buttonface），深色主题下就是一块突兀的灰砖，
 * 配上 --text-faint 的字几乎看不见（2026-10-22 用户报）。改成透明底的文字
 * 按钮：字色提到 --text-dim，hover 走强调色，键盘焦点有可见轮廓。 */
.cap-example {
  font-size: var(--text-xs);
  color: var(--text-dim);
  font-style: italic;
  background: transparent;
  border: 0;
  padding: var(--sp-1) 0;
  text-align: left;
}
.cap-example:hover { color: var(--user); }
.cap-example:focus-visible { outline: 2px solid var(--user); outline-offset: 2px; }
.cap-tip {
  font-size: var(--text-xs); color: var(--text-faint);
  margin-top: var(--sp-3); padding-top: var(--sp-2);
  border-top: var(--bw) solid var(--border);
}
.cap-tip .tip-label { color: var(--text-dim); margin-right: var(--sp-1); }
/* 展开后的正文是**要读的内容**，不是提示语 —— 用 --text-dim 而不是
 * --text-faint（#666 在深色卡片上只有 3:1，读正文不够）。 */
.skill-preview { color: var(--text-dim); }
/* 经验→技能草稿（2026-10-23）：两个文字按钮并排；禁用时保持可读。 */
.draft-card { border-color: var(--user); }
.draft-actions { display: flex; gap: var(--sp-4); margin-top: var(--sp-2); }
.draft-approve { color: var(--user); font-style: normal; }
.draft-reject { color: var(--text-faint); font-style: normal; }
.draft-actions button:disabled { opacity: .5; cursor: default; }
.draft-status:empty { display: none; }

/* ───────────────────────────────────────────────────────────────
   08 卷 §3 · Item 视觉规范（流式文档 8 种形态）
   08 卷 §3.9 · 通用规则：item 间距 16px (--sp-4)，无入场动画
   ─────────────────────────────────────────────────────────────── */

/* 通用：所有 item 间距 */
.item-user, .item-agent, .reasoning, .cmd, .filechange,
  .plan, .toolcall, .approval, .item-unknown {
  margin-bottom: var(--sp-4);
}

/* 3.1 用户消息 userMessage
   **必须和 agent 回复一眼分得开**（2026-09-30 用户要求，参考 Hermes）。
   以前两边只差「有没有背景 + 左边条颜色」，文字色都是 var(--text) ——
   扫一眼分不清哪句是自己说的。现在：

     · 底色带上该主题的「用户色」调子（`color-mix` 派生 → 8 套主题自动
       适配，不必逐个去调）
     · 文字色直接用 `--user`：浅色主题下它是中深暖色、深色主题下是浅暖色，
       两头都和正文的 `--text` 拉得开
     · 字重 500，读起来像「用户说的话」而不是正文

   对比度由 `tests/test_theme_contrast.py` 钉着（正文级 ≥ 4.5:1），
   改色改到看不清会直接变红。 */
/* 消息里那一行「这一轮带了哪些资料」（2026-10-01）。
   用户要的「引用这些资料」就是这个：发出去之后要留痕，翻回历史也得在。
   只显示文件名，完整路径在 title 里（鼠标放上去看）。 */
.msg-atts { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .4rem; }
.msg-att {
  display: inline-block; max-width: 100%;
  font-size: var(--text-xs);
  padding: 1px .5rem;
  border: var(--bw) solid var(--border);
  border-radius: 20px;
  color: var(--text-dim);
  background: var(--surface-2, rgba(255,255,255,.05));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.item-user {
  border-left: var(--bw-accent) solid var(--user);
  /* 老浏览器兜底（`color-mix` 要 Chrome/Edge 111+） */
  background: var(--surface-2);
  background: color-mix(in srgb, var(--user) 12%, var(--surface));
  border-radius: 0 var(--r-md) var(--r-md) var(--r-md);
  padding: 10px 14px;
  font-size: var(--text-base);
  line-height: var(--lh-base);
  /* 文字色 = 用户色 + 正文色的混合。
     **不能直接用 var(--user)**：它是给「左边条」用的（只需 3:1 可见度），
     实测在 warm/light 主题下当正文只有 3.39:1，不够 —— 而这个改动的目的
     恰恰是让用户看得更清楚。混进 --text 之后自动继承正文色在该主题下的
     深度，同时保留用户色的调子。对比度由 test_theme_contrast.py 钉着。 */
  color: var(--text);
  color: color-mix(in srgb, var(--user) 45%, var(--text));
  font-weight: 500;
  /* 这两条原在 tokens.css 的重复块里，合并时**必须**带过来 ——
     不然用户输入里的换行会塌成一行。 */
  white-space: pre-wrap;
  word-break: break-word;
}

/* 3.2 agent 消息 agentMessage：品红边条、无背景、无气泡 */
.item-agent {
  border-left: var(--bw-accent) solid var(--agent);
  padding: 0 14px;
  font-size: var(--text-base);
  line-height: var(--lh-base);
  color: var(--text);
  word-wrap: break-word;
}
/* ── 本轮「产出」区 — 毛玻璃面板（2026-10-01）────────────────
 * 用户原话：「文件可以快速找到或者可以直接打开」。 */
.turn-outputs {
  margin: var(--sp-2) 0;
  padding: var(--sp-3);
  border: var(--bw) solid var(--glass-border);
  border-radius: var(--radius);
  background: transparent;
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  box-shadow: var(--glass-shadow), var(--glass-inner-glow);
}
.to-head {
  font-size: var(--text-sm);
  color: var(--text-dim);
  margin-bottom: var(--sp-2);
  display: flex;
  align-items: center;
  transition: color 0.15s;
}
.to-head:hover {
  color: var(--text);
}
.to-arrow {
  display: inline-block;
  transition: transform 0.2s;
}
.to-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 2px 0;
}
.to-name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--text-sm);
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.to-open { flex: 0 0 auto; }
/* 文件类型图标（2026-10-22）：一排同名文件时，用户要能一眼分出
 * 「这是图 / 这是报告 / 这是代码」，而不是全靠猜扩展名。 */
.to-icon {
  flex: 0 0 auto;
  font-size: var(--text-sm);
  line-height: 1;
  opacity: .85;
}

/* 图片产出给缩略图（2026-10-02）：出图是本轮的主产物，光一个文件名
 * 用户还得点开才知道长什么样 —— 用户原话「内容直观看到」。
 * 缩略图在上、文件名+打开在下（竖排）。点缩略图 = 打开大图。 */
.to-row-image {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-2);
  padding: var(--sp-1) 0 var(--sp-2);
}
.to-thumb {
  display: block;
  max-width: 240px;
  max-height: 320px;
  border: var(--bw) solid var(--border);
  border-radius: var(--radius-sm);
  cursor: zoom-in;
}
.to-thumb:hover { border-color: var(--user); }
.to-thumb-err {
  font-size: var(--text-sm);
  color: var(--text-faint);
  padding: var(--sp-2);
  border: var(--bw) dashed var(--border);
  border-radius: var(--radius-sm);
}
.to-meta {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  width: 100%;
  min-width: 0;
}

/* 「二选一」按钮的选中态（2026-10-02 图片面板的精度档在用）。
 * `.pane-x` 本来是为列表项的删除「×」写的（tokens.css），hover 会变红 ——
 * 这里用强调色压住它，让用户一眼看出选的是哪个。
 * views.css 在 tokens.css 之后加载，同优先级下后者胜。 */
.pane-x.is-on,
.pane-x.is-on:hover {
  color: var(--user);
  border-color: var(--user);
  font-weight: 600;
}

/* ── 消息下方的一键操作（2026-09-30）────────────────────────
 * 「复制」「引用」挂在每条消息下面。
 *
 * **默认隐身、悬停才露面**：每条消息都常驻一排小按钮，整屏会变得很吵，
 * 而且会把消息之间的留白撑乱。
 * 但触屏没有 hover —— 那些设备上直接常驻（`@media (hover: none)`），
 * 否则按钮等于不存在。
 */
.msg-actions {
  display: flex;
  gap: var(--sp-1);
  margin-top: var(--sp-1);
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease);
}
.item-user:hover .msg-actions,
.item-agent:hover .msg-actions,
.msg-actions:focus-within { opacity: 1; }
@media (hover: none) {
  .msg-actions { opacity: 1; }
}
.msg-actions button {
  border: none;
  background: none;
  padding: 2px 6px;
  border-radius: var(--r-sm);
  color: var(--text-faint);
  font-size: var(--text-xs);
  font-family: inherit;
  cursor: pointer;
}
.msg-actions button:hover {
  color: var(--user);
  background: var(--surface-2);
}

.item-agent p { margin: 0 0 var(--sp-2); }
.item-agent ul, .item-agent ol { margin: 0 0 var(--sp-2); padding-left: var(--sp-4); }
.item-agent li { margin-bottom: var(--sp-1); }
.item-agent li::marker { color: var(--text-faint); }
.item-agent code {
  font-family: var(--font-mono); font-size: 0.875em;
  background: var(--surface-2); padding: 2px 6px; border-radius: var(--r-sm);
  border: var(--bw) solid var(--border);
}
.item-agent pre {
  background: var(--surface-2); border-radius: var(--r-md);
  padding: var(--sp-3); font-family: var(--font-mono);
  font-size: var(--text-sm); overflow-x: auto;
  border: var(--bw) solid var(--border);
  line-height: var(--lh-code);
  margin-bottom: var(--sp-3);
}
.item-agent pre code {
  font-size: inherit; background: none; padding: 0; border: none;
  color: var(--text);
}
/* Blockquote styling */
.item-agent blockquote {
  border-left: 3px solid var(--border-strong);
  padding-left: var(--sp-3);
  margin: 0 0 var(--sp-2);
  color: var(--text-dim);
  font-style: italic;
}
/* Links */
.item-agent a {
  color: var(--user);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur);
}
.item-agent a:hover {
  border-bottom-color: var(--user);
}

/* 流式光标：闪烁 */
.item-agent .cursor, .cursor {
  display: inline-block;
  width: 2px; height: 14px; margin-left: 2px;
  background: var(--user); vertical-align: text-bottom;
  animation: cursorBlink 800ms step-end infinite;
}
@keyframes cursorBlink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

/* 3.3 思考 reasoning：默认折叠一行，点击展开 */
.reasoning {
  font-size: var(--text-sm);
  color: var(--text-faint);
  margin-bottom: var(--sp-4);
}
.reasoning summary {
  font-size: var(--text-sm);
  color: var(--text-faint);
  cursor: pointer;
  list-style: none; padding: var(--sp-1) 0;
  user-select: none;
}
.reasoning summary::-webkit-details-marker {
  display: none; /* 用 ▸ 伪元素代替 */
}
.reasoning summary::before {
  content: '▸ '; color: var(--text-faint);
}
.reasoning[open] summary::before {
  content: '▾ '; color: var(--text-dim);
}
.reasoning-body {
  display: none;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--text-dim);
  background: var(--surface-2);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-4);
  margin-top: var(--sp-1);
  white-space: pre-wrap;
  word-break: break-word;
}
.reasoning[open] .reasoning-body {
  display: block;
}

/* 3.4 命令执行 — 毛玻璃终端风格 */
.cmd {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  background: var(--glass-bg);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border-radius: var(--r-lg);
  overflow: hidden;
  margin-bottom: var(--sp-4);
  line-height: var(--lh-code);
  border: var(--bw) solid var(--glass-border);
  box-shadow: var(--glass-shadow);
}
.cmd-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--text-sm);
  border-bottom: var(--bw) solid var(--glass-border);
  background: var(--glass-bg-strong);
}
.cmd-name {
  flex: 1;
  color: var(--text);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding-right: var(--sp-3);
}
.cmd-status { flex-shrink: 0; font-size: var(--text-xs); }
.cmd-status.run { color: var(--user); }
.cmd-status.run .spin {
  display: inline-block; animation: spin var(--dur-anim) linear infinite;
}
.cmd-status.ok { color: var(--success); }
.cmd-status.err { color: var(--danger); }
@keyframes spin {
  to { transform: rotate(360deg); }
}
.cmd-body {
  padding: var(--sp-2) var(--sp-3);
  color: var(--text);
  overflow-y: auto;
  max-height: 300px;
}
.cmd-output {
  white-space: pre-wrap;
  word-break: break-word;
}
.cmd-toggle {
  margin-top: var(--sp-1);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--text-dim);
  background: transparent;
  border: var(--bw) solid var(--border);
  border-radius: var(--r-sm);
  padding: var(--sp-1) var(--sp-2);
  cursor: pointer;
}
.cmd-toggle:hover {
  color: var(--user);
  border-color: var(--user);
}

/* 3.5 文件改动 fileChange */
.filechange {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  border-radius: var(--r-lg);
  background: var(--surface-2);
  overflow: hidden;
  margin-bottom: var(--sp-4);
  border: var(--bw) solid var(--border);
}
.fc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-2) var(--sp-3);
  border-bottom: var(--bw) solid var(--border);
  font-family: var(--font-ui);
  cursor: pointer;
  background: var(--surface-3);
  transition: background var(--dur) var(--ease);
}
.fc-head:hover {
  background: var(--surface-3);
  filter: brightness(1.1);
}
.fc-title {
  font-size: var(--text-sm);
  color: var(--text);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding-right: var(--sp-3);
}
.badge {
  display: inline-flex;
  gap: 2px;
  font-size: var(--text-xs);
  font-weight: 600;
}
.badge .add { color: var(--success); }
.badge .del { color: var(--danger); }
/* 出图产物：直接显示出来（2026-10-02）。
   出图是一轮的主产物，用户最想看的就是它 —— 只给个文件名等于让他自己去翻。 */
.fc-image {
  display: block;
  max-width: 100%;
  max-height: 520px;
  margin: var(--sp-1) var(--sp-3) var(--sp-2);
  border: var(--bw) solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.fc-image-err {
  margin: var(--sp-1) var(--sp-3) var(--sp-2);
  font-size: var(--text-sm);
  color: var(--text-dim);
}

.fc-files { padding: var(--sp-1) var(--sp-3) 0; }
.fc-file {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-1) var(--sp-2);
  color: var(--text-dim);
  font-size: var(--text-xs);
  border-left: 2px solid var(--border);
}
.fc-file span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-right: var(--sp-2); }
.diff {
  padding: var(--sp-1) var(--sp-2) var(--sp-2);
  font-size: var(--text-xs);
  overflow-x: auto;
  max-height: 400px;
  overflow-y: auto;
  white-space: pre;
}
.d-add { color: var(--success); background: color-mix(in srgb, var(--success) 8%, transparent); }
.d-del { color: var(--danger); background: color-mix(in srgb, var(--danger) 8%, transparent); }
.d-ctx { color: var(--text-dim); }

/* 3.6 计划 plan */
.plan {
  font-family: var(--font-ui);
  margin-bottom: var(--sp-4);
}
.plan-title {
  font-size: var(--text-sm);
  color: var(--text-dim);
  font-weight: 600;
  margin-bottom: var(--sp-1);
  text-transform: none;
}
.plan-step {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-2);
  font-size: var(--text-sm);
  border-radius: var(--r-sm);
}
.plan-step .ic {
  flex-shrink: 0;
  font-size: var(--text-sm);
  width: 20px;
  text-align: center;
}
.plan-step.done .ic { color: var(--success); }
.plan-step.doing .ic { color: var(--user); }
.plan-step.doing .ic::after {
  content: ''; display: inline-block;
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--user);
  margin-left: 4px;
  animation: pulse var(--dur-anim) infinite ease-in-out;
}
.plan-step.todo .ic { color: var(--text-faint); }
.plan-step.todo { opacity: 0.7; }
@keyframes pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.3; transform: scale(0.5); }
}

/* 3.7 工具调用 toolCall */
.toolcall {
  font-size: var(--text-sm);
  color: var(--text-dim);
  margin-bottom: var(--sp-4);
}
.toolcall summary {
  cursor: pointer;
  list-style: none;
  padding: var(--sp-1) var(--sp-2);
  background: var(--surface-2);
  border-radius: var(--r-sm);
  user-select: none;
}
.toolcall summary::-webkit-details-marker {
  display: none;
}
.toolcall summary::before {
  content: '⚙ '; color: var(--text-faint);
}
.toolcall-body {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--text-dim);
  background: var(--surface-2);
  border-radius: var(--r-sm);
  padding: var(--sp-2) var(--sp-3);
  margin-top: var(--sp-1);
  white-space: pre-wrap;
  overflow-x: auto;
}

/* 3.8 未知类型 item-unknown */
.item-unknown {
  font-size: var(--text-sm);
  color: var(--text-dim);
  margin-bottom: var(--sp-4);
  border: 1px dashed var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-2) var(--sp-3);
}
.item-unknown details {
  margin-top: var(--sp-1);
}
.item-unknown summary {
  cursor: pointer;
  list-style: none;
  font-size: var(--text-xs);
  color: var(--text-faint);
  padding: var(--sp-1) 0;
}
.item-unknown pre {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--text-dim);
  background: var(--surface-2);
  border-radius: var(--r-sm);
  padding: var(--sp-2);
  overflow-x: auto;
  max-height: 200px;
  overflow-y: auto;
  white-space: pre;
}

/* ── 「返回对话」条（2026-10-02）───────────────────────────────
 * 非对话视图（今日 / 办公 / 技能 / 项目 / 设置）顶部那个按钮。
 * 用户原话：「需要…增加一个返回对话的按钮，现在是需要点击左侧的对话导航
 * 才能返回对话，这个用户一般是不会知道的」。
 *
 * `flex: none` —— 它是 `.view` 的第一个 flex item，不参与滚动，
 * 内容区（后面的 `.sec` / `.dashboard` 那些）自己滚。 */
.view-back {
  flex: none;
  padding: var(--sp-2) var(--sp-4) 0;
}
.view-back-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  padding: var(--sp-1) var(--sp-3);
  border: var(--bw) solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text-dim);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: border-color var(--dur), color var(--dur);
}
.view-back-btn:hover {
  border-color: var(--user);
  color: var(--text);
}
.view-back-btn svg {
  width: 16px;
  height: 16px;
  display: block;
}

/* ── 首启模型引导条（2026-10-17，换机可用）─────────────────────
 * 默认模型连不通（本地推理服务没起 / 云端缺 key）时出现：一句原因 +
 * 「去设置 → 模型」按钮。语义色只用既有四个：这里按 08 卷的分工用
 * --agent（warning 档），不当成 error —— 它是引导，不是报错。 */
.model-guide {
  flex: none;
  display: flex;
  align-items: baseline;
  gap: var(--sp-2);
  margin: var(--sp-2) var(--sp-4) 0;
  padding: var(--sp-2) var(--sp-3);
  border: var(--bw) solid var(--border);
  border-left: 3px solid var(--agent);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: var(--text-sm);
}
.model-guide .guide-reason {
  flex: 1;
  color: var(--text-dim);
}
.model-guide .guide-dismiss {
  flex: none;
  border: none;
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
  font-size: var(--text-md);
  line-height: 1;
  padding: 0 var(--sp-1);
}
.model-guide .guide-dismiss:hover {
  color: var(--text);
}

/* ── 办公卡片的小表单（2026-10-02）─────────────────────────────
 * 点一张办公卡弹出来，问两三个具体问题 —— 用户要的「一步一步、
 * 人性化、傻瓜化引导」。填完自动开跑，不用自己按发送。 */
.card-form-mask {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-4);
  background: rgba(0, 0, 0, .45);
}
.card-form {
  width: 100%;
  max-width: 460px;
  max-height: 86vh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4);
  border: var(--bw) solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}
.card-form-title {
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--text);
}
.card-form-row {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}
.card-form-label {
  font-size: var(--text-sm);
  color: var(--text-dim);
}
.card-form-input {
  width: 100%;
  padding: var(--sp-2);
  border: var(--bw) solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  font-family: inherit;
  font-size: var(--text-base);
  resize: vertical;
}
.card-form-input:focus {
  border-color: var(--user);
  outline: none;
}
.card-form-err {
  min-height: 1.2em;
  font-size: var(--text-sm);
  color: var(--user);
}
.card-form-acts {
  display: flex;
  justify-content: flex-end;
  gap: var(--sp-2);
}

/* ── 首页技能卡片墙（2026-10-02）───────────────────────────────
 * 用户要的：新对话页最上方 9 张正方形卡片，点一个直接开始。
 * 取代了原来的空状态（问候 + 能力清单 + 建议）与首启三选一 ——
 * 那两套的样式（.empty* / .fr-guide*）同时删掉了。 */
.home {
  /* 左右留呼吸位（2026-10-02）：卡片网格原本撑满 860px 的内容区，
     两侧只剩 50 来像素，看着和侧栏挤在一起。 */
  padding: var(--sp-4) var(--sp-5) var(--sp-5);
}
.home-tip {
  text-align: center;
  color: var(--text-dim);
  font-size: var(--text-sm);
  margin: 0 0 var(--sp-4);
}
.home-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: var(--sp-2);
}
.home-card {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: var(--sp-1);
  min-height: 76px;
  padding: var(--sp-3);
  /* 毛玻璃与左侧会话条目同一套（2026-10-19 用户定稿）：默认就有玻璃底、
     背景透出来，轮廓用 --glass-border 比 --border 明显 —— 不悬停也能看清卡片边界。 */
  border: var(--bw) solid var(--glass-border);
  border-radius: var(--r-lg);
  background: var(--glass-bg);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: var(--glass-inner-glow);
  color: var(--text);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  transition: background var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease);
}
.home-card:hover {
  background: var(--glass-bg-strong);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-color: var(--user);
  transform: translateY(-2px);
  box-shadow: var(--glass-shadow), var(--glass-inner-glow);
}
.home-card:active {
  transform: translateY(0);
  box-shadow: var(--shadow-sm);
}
.home-card-title {
  font-size: var(--text-base);
  font-weight: 600;
}
.home-card-desc {
  font-size: var(--text-xs);
  color: var(--text-dim);
  line-height: 1.4;
}
/* 开发项目卡：**底色和办公卡分开**（用户明确要求）。
   玻璃底加一档（strong）+ 金色描边，一眼就看出"这是另一个入口"。 */
.home-card-project {
  background: var(--glass-bg-strong);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-color: var(--user);
}
.home-card-project .home-card-title {
  color: var(--user);
}

/* ── 新建项目引导：步骤条（2026-10-02）─────────────────────────
 * 挂在对话视图层（`#project-flow`），不随消息滚动 ——
 * 消息流里的 `#current-task` 是 sticky，放一起会叠行。 */
.pf-flow {
  border-bottom: var(--bw) solid var(--border);
  background: var(--surface);
  padding: var(--sp-2) var(--sp-4);
}
.pf-rail {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-3);
}
.pf-step {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--text-xs);
  color: var(--text-faint);
  white-space: nowrap;
}
.pf-ic { font-style: normal; }
.pf-done { color: var(--text-dim); }
.pf-current { color: var(--user); font-weight: 600; }
.pf-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  margin-top: var(--sp-2);
  /* 做图引导把选项表单也放进 foot 里（2026-10-02）——
     不换行的话表单会被挤成窄窄的一列贴在右边（实测就是这个样子）。 */
  flex-wrap: wrap;
}
.pf-hint { font-size: var(--text-sm); color: var(--text-dim); }
.pf-acts { display: flex; gap: var(--sp-2); flex-shrink: 0; }
.pf-exit { color: var(--text-faint); }

/* 第①步的表单（落在消息区 —— 此时用户还没发过消息，卡片墙已让位） */
.pf-form {
  border: var(--bw) solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  padding: var(--sp-4);
  /* 做图引导的选项比较多（8 个用途 / 6 个风格），矮屏要能滚 */
  max-height: 40vh;
  overflow-y: auto;
  /* 在 `.pf-foot`（flex 行）里占满一整行，压在说明文字下面 */
  flex: 1 0 100%;
}
.pf-form-head {
  font-size: var(--text-base);
  color: var(--text);
  margin-bottom: var(--sp-3);
}
.pf-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-2);
}
.pf-lab {
  font-size: var(--text-sm);
  color: var(--text-dim);
  width: 4.5em;
  flex-shrink: 0;
}
.pf-row input {
  flex: 1 1 auto;
  min-width: 0;
  padding: var(--sp-1) var(--sp-2);
  border: var(--bw) solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  font-family: inherit;
  font-size: var(--text-sm);
}
.pf-note {
  font-size: var(--text-sm);
  color: var(--text-dim);
  margin-top: var(--sp-1);
}
.pf-note.bad { color: var(--user); }

/* 引导里的选项按钮 + 填空行（做图引导用的，2026-10-02）
   —— `projectFlow` 只用过 pf-form 的输入行，没有「一排选项」。 */
.pf-opt {
  display: block;
  width: 100%;
  text-align: left;
  margin-bottom: var(--sp-1);
  padding: var(--sp-2) var(--sp-3);
  border: var(--bw) solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  font-family: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
}
.pf-opt:hover { border-color: var(--user); }
.pf-opt.is-on {
  border-color: var(--user);
  background: var(--selection-soft);
  color: var(--user);
  font-weight: 600;
}
.pf-field {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-2);
}
.pf-field > span {
  font-size: var(--text-sm);
  color: var(--text-dim);
  width: 4.5em;
  flex-shrink: 0;
}
/* 长文本字段（正文）：标签压在上面、输入框占满整行 ——
   按「标签在左、输入在右」的窄行排，正文根本没地方写。 */
.pf-field-block {
  display: block;
}
.pf-field-block > span {
  display: block;
  width: auto;
  margin-bottom: var(--sp-1);
}
/* 素材框（图片引导第 2 步，2026-10-03）——
 * 顺序是刻意的：先贴素材、点提炼，**下面的表单就填好了**。 */
.pf-material {
  margin-bottom: var(--sp-3);
  padding-bottom: var(--sp-3);
  border-bottom: 1px dashed var(--border);
}
.pf-material-label {
  font-size: var(--text-sm);
  color: var(--text-dim);
  margin-bottom: var(--sp-1);
}
.pf-material-input {
  width: 100%;
  min-height: 5em;
  resize: vertical;
  padding: var(--sp-2);
  border: var(--bw) solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  font-family: inherit;
  font-size: var(--text-sm);
  line-height: 1.6;
  margin-bottom: var(--sp-2);
}
.pf-extract { align-self: flex-start; }

/* 多风格提示（2026-10-03）。**放在选项上方**（用户要的）——
   原来看不到就随手点，现在「可以多选」和「选得越多花得越多」都说在前面。
   选中之后它会变成「已选 N 个 —— 会出 N 张，约 X 元」。 */
.pf-multi-tip {
  margin-bottom: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border-left: 3px solid var(--user);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  font-size: var(--text-sm);
  color: var(--user);
}

/* 风格多选时**两列**（用户要的「一行两种，减少上下滚动」）——
   10 个选项一行一个要滚半天，两列省一半高度。
   字段行（正文那种长文本）跨两列 —— 挤成半宽没法写。 */
.pf-form-2col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-1) var(--sp-2);
  align-items: start;
}
.pf-form-2col > .pf-field,
.pf-form-2col > .pf-field-block,
.pf-form-2col > .pf-multi-tip,
.pf-form-2col > .pf-material {
  grid-column: 1 / -1;
}
.pf-form-2col .pf-opt {
  margin-bottom: 0;
  text-align: center;      /* 两列时居中比左对齐好看 */
}

/* 二维码选项（出图那步，2026-10-03）—— 默认不勾、不留位置 */
.pf-qr {
  margin: 0 0 var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  border: var(--bw) dashed var(--border);
  border-radius: var(--radius-sm);
}
.pf-qr-check {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--text-sm);
  color: var(--text);
  cursor: pointer;
}
.pf-qr-file { margin-top: var(--sp-2); }
.pf-qr-input { font-size: var(--text-sm); color: var(--text-dim); }
/* 码上方那行小字（2026-10-03）—— 跟上传框一起显示/隐藏 */
.pf-qr-note { margin-top: var(--sp-2); font-size: var(--text-sm); }

/* 「更多版式元素」折叠区（2026-10-03）——
 * 收起时里面的字段**压根不渲染**（不是渲染后藏起来），所以下面只管
 * 展开后的样子。 */
.pf-more {
  grid-column: 1 / -1;          /* 风格那步是两列网格，它要独占一行 */
  margin-top: var(--sp-2);
  padding-top: var(--sp-2);
  border-top: var(--bw) dashed var(--border);
}
.pf-more-toggle {
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--user);
  font-size: var(--text-sm);
  text-align: left;
}
.pf-more-body { margin-top: var(--sp-2); }

/* 版式选择（出图那步，2026-10-03）—— 默认「自动」，想换点一个。
 * 复用 .pf-opt 的选中态，只把它排成一行、不再整宽。 */
.pf-layout { flex: 1 0 100%; margin-bottom: var(--sp-2); }
.pf-layout-label {
  margin-bottom: var(--sp-1);
  font-size: var(--text-sm);
  color: var(--text-dim);
}
.pf-layout .pf-opt {
  display: inline-block;
  width: auto;
  margin: 0 var(--sp-1) var(--sp-1) 0;
  padding: var(--sp-1) var(--sp-3);
}

.pf-field-block textarea {
  width: 100%;
  min-height: 6em;
  resize: vertical;
  padding: var(--sp-2);
  border: var(--bw) solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  font-family: inherit;
  font-size: var(--text-sm);
  line-height: 1.65;
}

/* 滚动条：10px 宽、轨道透明、滑块 --border、悬停 var(--scrollbar-hover) */
.scrollable {
  scrollbar-width: thin;
}
.scrollable::-webkit-scrollbar {
  width: 10px;
}
.scrollable::-webkit-scrollbar-track {
  background: transparent;
}
.scrollable::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: var(--r-md);
}
.scrollable::-webkit-scrollbar-thumb:hover {
  background: var(--scrollbar-hover);
}

/* ── 审批卡 — 毛玻璃质感（approvalCard.js）──────────────────── */
.approval {
  border: 2px solid var(--agent);
  background: var(--glass-bg-strong);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  border-radius: var(--r-lg);
  padding: var(--sp-4);
  margin-bottom: var(--sp-4);
  font-family: var(--font-ui);
  box-shadow: var(--glass-shadow);
  animation: approvalSlideIn var(--dur-slow) var(--ease-out);
}
@keyframes approvalSlideIn {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
.ap-head {
  font-size: var(--text-base);
  color: var(--agent);
  font-weight: 600;
  margin-bottom: var(--sp-2);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.ap-head::before {
  content: '⚠';
  font-size: 1.2em;
}
.ap-action {
  font-size: var(--text-sm);
  color: var(--text-dim);
  margin-bottom: var(--sp-2);
  line-height: 1.6;
}
.ap-cmd {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  background: var(--surface);
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-sm);
  display: block;
  margin-top: var(--sp-1);
  color: var(--text);
  word-break: break-all;
}
.ap-meta { margin: 0 0 var(--sp-3); }
.ap-meta dt {
  font-size: var(--text-xs);
  color: var(--text-faint);
  margin-bottom: var(--sp-1);
  float: left;
  width: 80px;
}
.ap-meta dd {
  font-size: var(--text-sm);
  color: var(--text);
  margin: 0 0 var(--sp-1) 0;
  font-family: var(--font-mono);
  word-break: break-all;
}
.ap-btns {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}
/* 按钮基础（tokens.css 已有 .btn，这里补变体） */
.approval .btn {
  font-family: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
  padding: var(--sp-1) var(--sp-3);
  border-radius: var(--r-sm);
  border: var(--bw) solid var(--border);
  background: var(--surface);
  color: var(--text);
  transition: background var(--dur), border-color var(--dur), color var(--dur);
}
.approval .btn:hover {
  border-color: var(--text-dim);
  background: var(--surface-2);
}
.approval .btn:disabled {
  opacity: 0.35; cursor: not-allowed;
}
.approval .btn-primary {
  border-color: var(--user);
  color: var(--user);
  font-weight: 600;
}
.approval .btn-primary:hover {
  background: color-mix(in srgb, var(--user) 10%, transparent);
  border-color: var(--user);
}
.approval .btn-persist {
  border-color: var(--agent);
  color: var(--agent);
  font-weight: 600;
}
.approval .btn-persist:hover {
  background: color-mix(in srgb, var(--agent) 10%, transparent);
  border-color: var(--agent);
}
.approval .btn-danger {
  border-color: var(--danger);
  color: var(--danger);
}
.approval .btn-danger:hover {
  background: color-mix(in srgb, var(--danger) 10%, transparent);
  border-color: var(--danger);
}

/* ── 记忆引用脚注（M5-4）────────────────────────────────────── */
.memory-recall {
  font-size: var(--text-xs);
  color: var(--text-faint);
  border-top: var(--bw) solid var(--border);
  padding: var(--sp-2) var(--sp-3);
  margin-top: var(--sp-3);
}
.memory-recall-item {
  padding: var(--sp-1) 0;
  font-family: var(--font-mono);
  word-break: break-all;
}
/* 引用提示行（重设计稿 §4.2）：一行小字，点击展开 */
.memory-recall-summary {
  border: none;
  background: transparent;
  color: var(--text-faint);
  font-size: var(--text-xs);
  cursor: pointer;
  padding: 0;
  font-family: inherit;
}
.memory-recall-summary:hover { color: var(--text-dim); }
.memory-recall-list { margin-top: var(--sp-1); }

/* 轻提示卡（§4.2/§8.5）：不打断，品红 1px 细边框（记住=身份语义） */
.note-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  background: var(--surface-2);
  border: var(--bw) solid var(--agent);
  border-radius: var(--r-md);
  font-size: var(--text-sm);
  color: var(--text-dim);
}
.note-card-btn { padding: var(--sp-1) var(--sp-3); font-size: var(--text-sm); }
/* 下一步建议引擎（§v0.3 二）：任务结束后的一组 chip */
.next-sugs {
  display: flex; align-items: center; gap: var(--sp-2);
  flex-wrap: wrap; padding: var(--sp-1) 0;
}
.next-sugs-label {
  color: var(--text-faint); font-size: var(--text-sm); flex: none;
}

/* ── 错误消息 ─────────────────────────────────────────────── */
.item-error {
  border-left: var(--bw-accent) solid var(--danger);
  background: color-mix(in srgb, var(--danger) 6%, transparent);
  border-radius: var(--r-md);
  padding: var(--sp-2) var(--sp-3);
  color: var(--text);
}
.item-error-btn { margin-left: var(--sp-2); padding: var(--sp-1) var(--sp-3); font-size: var(--text-sm); }
.item-error-detail summary {
  color: var(--text-faint); font-size: var(--text-xs); cursor: pointer;
  margin-top: var(--sp-1);
}
.item-error-detail pre {
  font-family: var(--font-mono); font-size: var(--text-xs);
  color: var(--text-dim); white-space: pre-wrap; word-break: break-all;
  margin-top: var(--sp-1);
}

/* 2026-09-27 检查：这里原本挂着 5 行**没有选择器的孤儿属性**
   （padding / color: var(--danger) / font-size / word-wrap）。
   它们是 .item-error 早期版本的尾巴 —— git show a6099ba 里 .item-error 的
   color 还是 --danger，后来被改成 --text 并去掉了 font-size/word-wrap，
   但这段漏删了。
   有害之处：浏览器会把这段当作**下一条规则的选择器前导**，一路吞到最近的一个
   `{`，于是紧跟其后的 `.mini-btn { ... }` 整条规则被吃进这条坏规则、根本没进
   CSSOM（实测：CSSOM 里有 `.mini-btn:hover` 却没有 `.mini-btn`）。
   `.mini-btn` 目前在整个 web/ 里无人使用，所以没造成可见问题，但是颗地雷。 */

/* ── 小按钮（停止按钮等）─────────────────────────────────────── */
.mini-btn {
  font-family: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-sm);
  border: var(--bw) solid var(--danger);
  background: color-mix(in srgb, var(--danger) 8%, transparent);
  color: var(--danger);
  white-space: nowrap;
  transition: background var(--dur);
}
.mini-btn:hover {
  background: color-mix(in srgb, var(--danger) 15%, transparent);
}

/* ── 会话列表项 — 毛玻璃质感 ────────────────────────────────── */
.session-item {
  padding: var(--sp-2) var(--sp-3);
  font-size: var(--text-sm);
  color: var(--text-dim);
  border-radius: var(--r-md);
  cursor: pointer;
  transition: background var(--dur) var(--ease),
              color var(--dur) var(--ease),
              transform var(--dur-fast) var(--ease),
              box-shadow var(--dur) var(--ease);
  position: relative;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  border: 1px solid transparent;
}
.session-item:hover {
  background: var(--glass-bg-hover);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: var(--text);
  border-color: var(--glass-border);
}
.session-item:active {
  transform: scale(0.98);
}
.session-item.active {
  background: var(--glass-bg-strong);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  color: var(--text);
  font-weight: 500;
  border-color: var(--glass-border-strong);
  box-shadow: var(--glass-shadow);
}
.session-item.active::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 60%;
  background: var(--user);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  box-shadow: 0 0 8px var(--user);
}

/* ── 状态点颜色变体 ────────────────────────────────────────── */
.status .dot.ok { background: var(--success); }
.status .dot.warning { background: var(--user); }
.status .dot.error { background: var(--danger); }
.status .dot.idle { background: var(--text-faint); }

/* ── 响应式适配 ───────────────────────────────────────────── */
/* 平板（768px 以下） */
@media (max-width: 768px) {
  .sidebar {
    width: 200px;
  }
  .sidebar.collapsed {
    width: 48px;
  }
  .coding-layout {
    flex-direction: column;
  }
  .coding-right {
    width: 100%;
  }
  .home-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  }
  .cap-grid {
    grid-template-columns: 1fr;
  }
}

/* 手机（480px 以下） */
@media (max-width: 480px) {
  .sidebar {
    position: fixed;
    left: -240px;
    top: 0;
    bottom: 0;
    z-index: 100;
    width: 240px;
    transition: left var(--dur-slow) var(--ease);
    box-shadow: var(--shadow-lg);
  }
  .sidebar.mobile-open {
    left: 0;
  }
  .sidebar.collapsed {
    width: 240px;
    left: -240px;
  }
  .app {
    flex-direction: column;
  }
  .home-grid {
    grid-template-columns: 1fr;
  }
  .dash-card {
    padding: var(--sp-2) var(--sp-3);
  }
  .sec {
    padding: var(--sp-3);
  }
  .item-user, .item-agent {
    padding: var(--sp-2) var(--sp-3);
  }
  .pf-form-2col {
    grid-template-columns: 1fr;
  }
}

/* 超小屏（360px 以下） */
@media (max-width: 360px) {
  :root {
    /* 窄屏本来就压到 14px；仍要乘界面字号，否则小屏上选「特大」不生效 */
    font-size: calc(14px * var(--ui-font-scale, 1));
  }
  .home-card {
    min-height: 64px;
    padding: var(--sp-2);
  }
  .toast {
    left: var(--sp-2);
    right: var(--sp-2);
    transform: translateY(20px);
    max-width: none;
  }
  .toast.show {
    transform: translateY(0);
  }
}

/* 高对比度模式 */
@media (prefers-contrast: high) {
  :root {
    --border: rgba(255, 255, 255, 0.2);
    --border-strong: rgba(255, 255, 255, 0.3);
  }
  :root[data-theme="light"] {
    --border: rgba(0, 0, 0, 0.2);
    --border-strong: rgba(0, 0, 0, 0.3);
  }
}


/* ── 用量历史 + 计费（2026-10-25，照 Cindy 设置页版面）─────────
 * 概览 → 活跃热力图 → 每日堆叠 → 按模型 → 最耗任务；
 * 余额 hero → 余额构成 → 账单汇总 → 流水 → 充值。
 * 卡片沿用应用整体毛玻璃，内部层级照 Cindy：标题 13/14、说明 12、
 * 数字等宽 tabular-nums，不加装饰色。 */
#view-usage {
  overflow-y: auto;
  padding: var(--sp-5);
  scroll-behavior: smooth;
}
.usage-view {
  /* Cindy 的 --surface-chip：比卡片底亮一档，热力空格与指标底都用它 */
  --ug-chip: color-mix(in srgb, var(--text) 7%, var(--surface-2));
  max-width: 980px;
  margin: 0 auto;
  /* 它是 #view-usage 的列向 flex 子项，min-width:auto 会被表格的
     min-content（约 750px）顶住 —— 右栏展开、窗口一窄就横向溢出被切掉。
     归零后由 .ug-tablewrap 自己横向滚动。 */
  min-width: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.ug-head { display: flex; flex-direction: column; gap: var(--sp-1); }
.ug-head-gap { margin-top: var(--sp-4); }
.ug-title {
  margin: 0; font-size: var(--text-lg); font-weight: 600;
  color: var(--text); letter-spacing: -0.01em;
}
.ug-desc {
  margin: 0; max-width: 640px;
  font-size: var(--text-sm); line-height: 1.55; color: var(--text-dim);
}

/* 工具栏 */
.ug-toolbar { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.ug-toolbar-label { font-size: var(--text-sm); color: var(--text-dim); }
.ug-toolbar-spacer { flex: 1; min-width: 0; }
.ug-seg {
  display: inline-flex; gap: 2px; padding: 2px;
  border: var(--bw) solid var(--border-strong);
  border-radius: var(--r-full);
  background: var(--surface-2);
}
.ug-seg button {
  font: inherit; font-size: var(--text-xs);
  color: var(--text-dim); background: transparent; border: 0;
  border-radius: var(--r-full); padding: 4px 12px; cursor: pointer;
  white-space: nowrap;
}
.ug-seg button:hover { color: var(--text); }
.ug-seg button.is-on {
  color: var(--text); background: var(--surface);
  box-shadow: var(--shadow-sm);
}
.ug-date {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--text-xs); color: var(--text-dim);
}
.ug-date input {
  font: inherit; font-size: var(--text-xs); font-family: var(--font-mono);
  color: var(--text); background: var(--surface-2);
  border: var(--bw) solid var(--border-strong);
  border-radius: var(--r-md); padding: 4px 8px;
}
.ug-ghost {
  font: inherit; font-size: var(--text-xs); cursor: pointer;
  color: var(--text-dim); background: transparent;
  border: var(--bw) solid var(--border-strong);
  border-radius: var(--r-full); padding: 4px 12px;
}
.ug-ghost:hover { color: var(--text); background: var(--surface-2); }
.ug-ghost.is-on { color: var(--text); background: var(--surface-2); }
.ug-hint { font-size: var(--text-xs); color: var(--text-faint); }

/* 卡片 */
.ug-panel {
  display: flex; flex-direction: column; gap: var(--sp-3);
  padding: var(--sp-4);
  border: var(--bw) solid var(--glass-border);
  border-radius: var(--r-lg);
  background: var(--glass-bg);
  backdrop-filter: blur(var(--glass-blur));
  -webkit-backdrop-filter: blur(var(--glass-blur));
  box-shadow: var(--glass-shadow), var(--glass-inner-glow);
  min-width: 0;
}
.ug-panel-head {
  display: flex; align-items: baseline; gap: var(--sp-2); flex-wrap: wrap;
}
.ug-panel-head h3 {
  margin: 0; font-size: var(--text-sm); font-weight: 600; color: var(--text);
}
.ug-panel-head span { font-size: var(--text-xs); color: var(--text-faint); }

/* 概览指标 */
.ug-stats { display: flex; gap: var(--sp-2); flex-wrap: wrap; }
.ug-stat {
  flex: 1 1 130px; min-width: 96px;
  display: flex; flex-direction: column; gap: 2px;
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-md);
  background: var(--ug-chip);
}
.ug-stat b {
  font-size: 1rem; font-weight: 500; line-height: 1.4;
  color: var(--text); font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
.ug-stat span { font-size: var(--text-xs); color: var(--text-dim); }

/* 热力图（尺寸照 Cindy：12px 方块 + 3px 间距 + 2px 圆角） */
.ug-heat-wrap {
  display: flex; flex-direction: column; gap: 6px;
  padding: 3px; overflow-x: auto;
}
.ug-heat-months {
  position: relative; height: 14px; min-width: max-content;
}
.ug-heat-months span {
  position: absolute; top: 0; white-space: nowrap;
  font-size: var(--text-xs); line-height: 1.4; color: var(--text-faint);
}
.ug-heat-grid {
  display: grid; grid-auto-flow: column; gap: 3px;
  grid-template-rows: repeat(7, 12px);
  min-width: max-content;
}
.ug-cell, .ug-heat-pad {
  width: 12px; height: 12px; border-radius: 2px; display: block;
}
.ug-cell {
  padding: 0; border: 0; cursor: pointer;
  background: var(--ug-chip);
  transition: outline-color var(--dur-fast) var(--ease);
}
.ug-cell:hover { outline: 1px solid var(--text-faint); outline-offset: 1px; }
.ug-cell.is-on { outline: 2px solid var(--user); outline-offset: 1px; }
.ug-cell:focus-visible { outline: 2px solid var(--user); outline-offset: 1px; }
.ug-heat-pad { background: transparent; }
/* 四档按非零日的四分位切分（Cindy d4e = 22 / 42 / 68 / 100%） */
.ug-cell.lv1 { background: color-mix(in srgb, var(--user) 22%, var(--ug-chip)); }
.ug-cell.lv2 { background: color-mix(in srgb, var(--user) 42%, var(--ug-chip)); }
.ug-cell.lv3 { background: color-mix(in srgb, var(--user) 68%, var(--ug-chip)); }
.ug-cell.lv4 { background: var(--user); }

/* 每日堆叠柱状图（柱区固定 96px，图内不放横轴标签） */
.ug-chart { display: flex; gap: 6px; height: 96px; min-width: 0; }
.ug-yaxis {
  position: relative; width: 4.5ch; flex: none;
  font-size: var(--text-xs); font-variant-numeric: tabular-nums;
}
.ug-yaxis span {
  position: absolute; right: 0; transform: translateY(50%);
  line-height: 1; color: var(--text-faint); white-space: nowrap;
}
.ug-plot { position: relative; flex: 1; min-width: 0; }
.ug-gridlines { position: absolute; inset: 0; pointer-events: none; }
.ug-gridlines i {
  position: absolute; left: 0; right: 0; height: 0;
  border-top: 1px solid var(--border); opacity: 0.5;
}
.ug-cols {
  position: absolute; inset: 0;
  display: flex; align-items: flex-end; gap: 3px;
}
.ug-col {
  flex: 1; min-width: 0; height: 100%;
  display: flex; align-items: flex-end; justify-content: center;
}
.ug-col-stack {
  width: 100%; display: flex; flex-direction: column-reverse;
  border-radius: 2px; overflow: hidden;
}
.ug-col-stack.is-empty { background: var(--ug-chip); }
.ug-col-stack i { display: block; width: 100%; min-height: 0; }
.ug-col:hover .ug-col-stack { filter: brightness(1.18); }

/* 图下小字注释 */
.ug-note {
  margin: 0; font-size: var(--text-xs); color: var(--text-faint);
}

/* 图表悬浮提示 */
.ug-tip {
  position: fixed; z-index: 10050;
  min-width: 170px; max-width: 300px;
  padding: 8px 10px;
  border: var(--bw) solid var(--border-strong);
  border-radius: var(--r-md);
  background: var(--surface-elevated);
  box-shadow: var(--shadow-lg);
  font-size: var(--text-xs); color: var(--text);
  pointer-events: none;
}
.ug-tip-head { font-size: var(--text-xs); opacity: 0.6; }
.ug-tip-total {
  display: flex; align-items: baseline; gap: 4px; margin-top: 6px;
}
.ug-tip-total b {
  font-size: 1rem; font-weight: 500; line-height: 1;
  font-variant-numeric: tabular-nums;
}
.ug-tip-total span { font-size: var(--text-xs); opacity: 0.6; }
.ug-tip-bar {
  display: flex; gap: 1px; height: 4px; margin-top: 10px;
  border-radius: 2px; overflow: hidden;
}
.ug-tip-bar i { display: block; height: 100%; flex-basis: 0; }
.ug-tip-row {
  display: flex; align-items: center; gap: 6px;
  margin-top: 6px;
  line-height: 1.4; color: var(--text-dim); min-width: 0;
}
.ug-tip-row i {
  width: 8px; height: 8px; border-radius: 2px; flex: none;
}
.ug-tip-row span {
  flex: 1; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.ug-tip-row b {
  margin: 0; flex: none; font-weight: 500;
  font-family: var(--font-mono); font-size: var(--text-xs); color: var(--text);
}
.ug-tip-row em {
  font-style: normal; flex: none; min-width: 3.5ch;
  text-align: right; opacity: 0.5;
  font-family: var(--font-mono); font-size: var(--text-xs);
}

/* 表格 */
.ug-tablewrap { overflow-x: auto; }
.ug-table { width: 100%; border-collapse: collapse; font-size: var(--text-xs); }
.ug-table th {
  text-align: right; font-weight: 500; color: var(--text-faint);
  padding: var(--sp-2); white-space: nowrap;
  border-bottom: var(--bw) solid var(--border-strong);
}
.ug-table th:first-child, .ug-table td:first-child { text-align: left; }
.ug-table td {
  text-align: right; padding: var(--sp-2);
  color: var(--text-dim); border-bottom: var(--bw) solid var(--border);
  white-space: nowrap; font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.ug-table tbody tr:last-child td { border-bottom: 0; }
.ug-table tbody tr:hover td { background: var(--surface-2); }
.ug-table td.ug-name {
  color: var(--text); text-align: left; font-family: var(--font-ui);
  max-width: 340px; overflow: hidden; text-overflow: ellipsis;
}
.ug-table td.ug-when { color: var(--text-faint); text-align: left; }
.ug-table td.ug-dim { color: var(--text-faint); }
.ug-table td.ug-empty-cell {
  text-align: center; color: var(--text-faint);
  font-family: var(--font-ui); padding: var(--sp-4);
}
.ug-rowlink { cursor: pointer; }
.ug-rowlink:focus-visible { outline: 2px solid var(--user); outline-offset: -2px; }
.ug-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 2px;
  margin-right: 6px; vertical-align: 0;
}
.ug-plus { color: var(--user) !important; }
.ug-minus { color: var(--danger) !important; }

/* 余额与套餐 */
.ug-balance {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); flex-wrap: wrap;
}
.ug-balance-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ug-balance-label { font-size: var(--text-xs); color: var(--text-dim); }
.ug-balance-amount {
  font-size: var(--text-2xl); font-weight: 500; line-height: 1.35;
  letter-spacing: -0.02em; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.ug-balance-amount.is-low { color: var(--danger); }
.ug-balance-meta { font-size: var(--text-xs); color: var(--text-faint); }
.ug-btn {
  font: inherit; font-size: var(--text-xs); font-weight: 500;
  cursor: pointer; color: var(--text);
  background: var(--surface-2);
  border: var(--bw) solid var(--border-strong);
  border-radius: var(--r-full); padding: 6px 16px;
  white-space: nowrap;
}
.ug-btn:hover { background: var(--surface-3); }
.ug-btn:disabled { opacity: 0.55; cursor: default; }
.ug-pools {
  display: flex; flex-direction: column;
  border-top: var(--bw) solid var(--border);
}
.ug-pool {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-4); padding: var(--sp-3) 0;
  border-bottom: var(--bw) solid var(--border);
  font-size: var(--text-sm); color: var(--text-dim);
}
.ug-pool:last-child { border-bottom: 0; }
.ug-pool b {
  font-family: var(--font-mono); font-weight: 500; color: var(--text);
  font-variant-numeric: tabular-nums;
}
.ug-prices {
  display: flex; gap: var(--sp-4); flex-wrap: wrap;
  font-size: var(--text-xs); color: var(--text-faint);
}
.ug-warn {
  padding: var(--sp-2) var(--sp-3);
  border: var(--bw) solid var(--danger);
  border-radius: var(--r-md);
  font-size: var(--text-xs); line-height: 1.6;
  color: var(--danger);
}
.ug-warn.soft { color: var(--text-dim); border-color: var(--border-strong); }
.ug-totals { font-size: var(--text-xs); color: var(--text-dim); }
.ug-totals b {
  color: var(--text); font-family: var(--font-mono); font-weight: 500;
}

/* 充值 / 管理员 */
.ug-redeem { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.ug-redeem input,
.ug-form input,
.ug-form select {
  font: inherit; font-size: var(--text-sm); color: var(--text);
  background: var(--surface-2);
  border: var(--bw) solid var(--border-strong);
  border-radius: var(--r-md); padding: 6px 10px;
  outline: none;
}
.ug-redeem input { width: 280px; max-width: 100%; font-family: var(--font-mono); }
.ug-redeem input:focus-visible,
.ug-form input:focus-visible,
.ug-form select:focus-visible,
.ug-date input:focus-visible {
  outline: 2px solid var(--user); outline-offset: 1px;
}
.ug-seg button:focus-visible,
.ug-ghost:focus-visible,
.ug-btn:focus-visible,
.ug-mini:focus-visible { outline: 2px solid var(--user); outline-offset: 1px; }
.ug-admin { display: flex; flex-direction: column; gap: var(--sp-2); }
.ug-admin-body {
  display: flex; flex-direction: column; gap: var(--sp-3);
  padding-top: var(--sp-3);
  border-top: var(--bw) solid var(--border);
}
.ug-admin-loading { font-size: var(--text-xs); color: var(--text-faint); }
.ug-admin-grid {
  display: grid; gap: var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.ug-form { display: flex; flex-direction: column; gap: var(--sp-2); }
.ug-form b { font-size: var(--text-sm); color: var(--text); }
.ug-form label {
  display: flex; flex-direction: column; gap: 4px;
  font-size: var(--text-xs); color: var(--text-dim);
}
.ug-form button { align-self: flex-start; }
.ug-sub-title {
  margin: var(--sp-2) 0 0;
  font-size: var(--text-xs); font-weight: 600; color: var(--text-dim);
}
.ug-tag { font-size: var(--text-xs); color: var(--text-faint); }
.ug-mini {
  font: inherit; font-size: var(--text-xs); cursor: pointer;
  color: var(--text); background: var(--surface-2);
  border: var(--bw) solid var(--border-strong);
  border-radius: var(--r-full); padding: 2px 10px;
}
.ug-mini:hover { background: var(--surface-3); }
.ug-mini:disabled { opacity: 0.55; cursor: default; }

/* 空态 / 加载 / 页脚 */
.ug-empty {
  display: flex; align-items: center; justify-content: center; gap: var(--sp-2);
  padding: var(--sp-6) var(--sp-4);
  font-size: var(--text-sm); color: var(--text-faint);
  text-align: center; line-height: 1.6;
}
.ug-spin {
  width: 14px; height: 14px; flex: none; border-radius: 50%;
  border: 2px solid var(--border-strong);
  border-top-color: var(--user);
  animation: ug-spin 0.8s linear infinite;
}
@keyframes ug-spin { to { transform: rotate(360deg); } }
.ug-foot {
  margin: 0; padding-top: var(--sp-2);
  border-top: var(--bw) solid var(--border);
  font-size: var(--text-xs); line-height: 1.7; color: var(--text-faint);
}

@media (max-width: 720px) {
  #view-usage { padding: var(--sp-3); }
  .usage-view { gap: var(--sp-3); }
  .ug-stat { flex-basis: calc(50% - var(--sp-2)); }
  .ug-balance { align-items: flex-start; }
  .ug-toolbar-spacer { display: none; }
}
