/* Aside — R1 静态原型样式
 *
 * 布局核心（ADR-0001；宽度策略见 ADR-0006）：每一行是 `[文本列 | 注栏列]` 两列网格，
 * 注栏列宽度由 `--gutter-w` 统一控制，且**只有一个写入点**（`viewport.js` 的
 * `applyGutterWidth()`）。
 *
 * ADR-0006 起：打开/收起侧窗**会**改变 `--gutter-w`（有侧窗展开 → 宽档，全收起 →
 * 静息档），因此正文会横向重排，靠 `scroll-anchor.js` 的锚点补偿兜住 I5。
 * 宽度策略（用户意图 vs 面板提议的优先级）在 `gutter-width.js`，本文件只管呈现。
 */

:root {
  --sidebar-w: 220px;
  --gutter-w: 340px;
  --scrollbar-w: 0px;
  --bg: #f6f7f9;
  --surface: #ffffff;
  --line: #e3e6ea;
  --line-strong: #d0d7de;
  --ink: #1f2328;
  --muted: #6b7280;
  --accent: #2f6feb;
  --accent-soft: #eef4ff;
  --warn: #b42318;
}

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  margin: 0;
}

body {
  display: flex;
  flex-direction: column;
  background: var(--bg);
  color: var(--ink);
  font: 14px/1.6 -apple-system, "Segoe UI", "PingFang SC", "Microsoft YaHei", system-ui, sans-serif;
}

/* ---------------------------------------------------------------- 顶栏 */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  flex: none;
}

.brand strong {
  font-size: 16px;
  letter-spacing: 0.02em;
}

.brand .sub {
  margin-left: 10px;
  color: var(--muted);
  font-size: 12px;
}

.tools {
  display: flex;
  align-items: center;
  gap: 8px;
}

.tool-label {
  color: var(--muted);
  font-size: 12px;
}

.btn {
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink);
  border-radius: 6px;
  padding: 4px 10px;
  font-size: 13px;
  cursor: pointer;
}

.btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

.btn-primary:hover {
  color: #fff;
  filter: brightness(1.05);
}

/* ---------------------------------------------------------------- 主体 */

.app {
  position: relative;
  flex: 1;
  min-height: 0;
}

.scroller {
  height: 100%;
  overflow-y: auto;
  scrollbar-gutter: stable;
}

.rows {
  /*
    内容少时**贴着底部**（紧邻输入框），内容多时正常从顶部滚动。
    为什么需要：原先只有 `padding-bottom`，而消息不到一屏时，下面那片空白是
    **布局的空**（rows 只有 216px，而滚动区可见 685px），不是内边距——
    所以只改 padding 完全没用（实测踩过）。
    用 flex 列 + `margin-top: auto` 让内容靠底，同时 `min-height: 100%` 保证
    滚动区始终有完整可滚高度。
  */
  display: flex;
  flex-direction: column;
  min-height: 100%;
  /*
    底部只留一点呼吸空间。
    原来这里写了 40vh——那是为"验证视口是否跳动"留的滚动余量，
    代价是滚到底时对话与输入框之间**空出一大截**（实测约 40% 视口高度）。
    滚动补偿（I5）由 `scroll-anchor.js` 按锚点坐标计算，**不依赖这段空白**，
    因此改为固定的小间距。若将来需要人工验证 I5，临时调大即可。
  */
  padding-bottom: 24px;
}

/* 靠底的关键：把自动外边距给第一个块，剩余空间会全部落在它上方 */
.rows > *:first-child {
  margin-top: auto;
}

/* 每行两列：文本列自适应，注栏列固定宽（常驻，不因侧窗开合而变） */
.row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--gutter-w);
  align-items: start;
}

.cell-content {
  padding: 10px 16px 10px 24px;
  min-width: 0;
}

.cell-gutter {
  position: relative;
  border-left: 1px dashed var(--line-strong);
  /* 纵向不留内边距：绝对定位的子元素以 padding box 为基准，纵向留白会污染量测 */
  padding: 0 12px;
  background: rgba(255, 255, 255, 0.45);
}

/* ---------------------------------------------------------------- 停靠栏 */

/* 每个侧窗一个绝对定位的停靠项，纵向位置由 rail.js 计算。
 * left 留出 44px：那是浮动追问按钮的专用竖条，否则按钮会盖住标记。 */
.rail-item {
  position: absolute;
  left: 44px;
  right: 12px;
  min-width: 0;
}

.rail-item .panel {
  margin-bottom: 0;
}

/* 侧边标记：始终存在，是"这一句有追问"的唯一提示（不变量 I3） */
.marker {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  border-radius: 999px;
  padding: 2px 9px;
  font-size: 12px;
  cursor: pointer;
  color: var(--ink);
  max-width: 100%;
  min-width: 0;
}

.marker.is-closed {
  background: #fff6e5;
  border-color: #e9b949;
  color: #7a4b00;
}

.marker.is-open {
  background: var(--accent-soft);
  border-color: #b9cdf7;
  color: #1c4ed8;
}

.marker:hover {
  filter: brightness(0.97);
}

.marker-title {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

/* 收缩态标记旁的删除入口。绝对定位，避免撑宽标记、把停靠项挤出视口。 */
.rail-item > .danger {
  position: absolute;
  top: -6px;
  right: -6px;
  /* 不要写死 width/height：待确认文案"确认删除？"比 × 宽得多，
     固定盒子会让它溢出（实测内容 20×26、盒子 16×16），
     用户就看不出按钮已进入待确认——那样"两击确认"等于失效。
     用 min-width/height 保证 × 态是个规整的圆点，靠 padding 让它按文案自然变宽。 */
  min-width: 18px;
  min-height: 18px;
  padding: 0 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  line-height: 1.2;
  white-space: nowrap;
  background: var(--surface);
}

.marker-count {
  background: rgba(0, 0, 0, 0.08);
  border-radius: 999px;
  padding: 0 5px;
  font-size: 11px;
}

.rail-item.is-open .marker {
  margin-bottom: 6px;
}

/* 随滚动跟随的追问入口：固定在停靠栏左缘，纵向居中 */
/* 模型选择：与宽度档位同处工具条，宽度自适应且不抢视觉焦点。 */
.model-select {
  max-width: 190px;
  padding: 2px 6px;
  font: inherit;
  font-size: 12px;
  color: inherit;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  cursor: pointer;
}

.rail-add {
  position: fixed;
  right: calc(var(--gutter-w) + var(--scrollbar-w) - 36px);
  top: 50%;
  transform: translateY(-50%);
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: #fff;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  z-index: 30;
  box-shadow: 0 2px 8px rgba(47, 111, 235, 0.35);
}

.rail-add:hover {
  filter: brightness(1.08);
}
/* 拖拽态：光标与"禁止选中"要明确，否则拖到正文上会顺手选中文字。 */
body.is-dragging-rail-add {
  cursor: grabbing;
  user-select: none;
}
body.is-dragging-rail-add .rail-add {
  cursor: grabbing;
  filter: brightness(1.12);
  /* 拖拽中不要过渡/阴影变化，否则按钮会跟手迟滞 */
  transition: none;
}

/* 浮动按钮当前指向的消息 */
.bubble.is-rail-target {
  box-shadow: 0 0 0 2px var(--accent);
  border-color: var(--accent);
}

/* 拖拽把手：绝对定位在文本列与注栏列的分界线上，纵向固定不动 */
.splitter {
  position: absolute;
  top: 0;
  bottom: 0;
  right: calc(var(--gutter-w) + var(--scrollbar-w));
  width: 12px;
  transform: translateX(6px);
  cursor: col-resize;
  background: transparent;
  z-index: 5;
  touch-action: none;
}

.splitter::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 5px;
  width: 2px;
  background: transparent;
}

.splitter:hover::after,
.splitter:focus-visible::after,
body.is-dragging .splitter::after {
  background: var(--accent);
}

.splitter:focus-visible {
  outline: none;
}

/* 拖拽期间禁用过渡，避免与滚动补偿互相打架 */
body.is-dragging {
  user-select: none;
}

body.is-dragging * {
  transition: none !important;
}

/* ---------------------------------------------------------------- 消息 */

.bubble {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 8px 12px 10px;
}

.bubble[data-role="user"] {
  background: var(--accent-soft);
  border-color: #d8e2ff;
}

.who {
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.06em;
}

.msg-text {
  margin: 2px 0 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* 锚点高亮：鼠标停在侧窗或标识上时，对应的那一句会亮起来 */
.is-highlight {
  box-shadow: 0 0 0 2px var(--accent);
  border-radius: 8px;
}

/* ---------------------------------------------------------------- 标识与操作 */

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 6px;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  border-radius: 999px;
  padding: 2px 9px;
  font-size: 12px;
  cursor: pointer;
  color: var(--ink);
}

/* 收缩态的标识必须显眼：它承担"这一句有追问"的唯一提示（不变量 I3） */
.chip.is-closed {
  background: #fff6e5;
  border-color: #e9b949;
  color: #7a4b00;
}

.chip.is-open {
  background: var(--accent-soft);
  border-color: #b9cdf7;
  color: #1c4ed8;
}

.chip:hover {
  filter: brightness(0.97);
}

.chip-count {
  background: rgba(0, 0, 0, 0.08);
  border-radius: 999px;
  padding: 0 5px;
  font-size: 11px;
}

.chip-add {
  color: var(--muted);
  border-style: dashed;
}

/* ---------------------------------------------------------------- 侧窗 */

.panel {
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  padding: 8px 10px 10px;
  margin-bottom: 10px;
  min-width: 0;
  /* 面板必须在内部滚动，而不是把所在行撑高：否则一条超长追问能把文档拉到几千像素，
   * 行高膨胀、停靠标记漂到远低于锚点的位置，收缩时还会把补偿顶到 scrollTop 上限之外 */
  display: flex;
  flex-direction: column;
  max-height: min(64vh, 560px);
}

.panel-body {
  overflow: auto;
  overscroll-behavior: contain;
  min-height: 0;
}

.panel[data-depth="1"] {
  border-left-color: #7c3aed;
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 6px;
}

.panel-title {
  font-size: 12px;
  color: var(--muted);
}

.link {
  border: none;
  background: none;
  color: var(--accent);
  font-size: 12px;
  cursor: pointer;
  padding: 0;
}

.empty {
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 12px;
}

.node {
  border-top: 1px solid var(--line);
  padding: 6px 0 2px;
  min-width: 0;
}

/* 追问节点上的操作区（删除）。默认低调，悬停/聚焦时显形，避免每条追问都挂一个大红按钮。 */
.node-tools {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
  margin-top: 2px;
}

/* 两击确认：第一次点进入待确认，第二次才真删。待确认态必须**一眼可辨**，
   否则用户看不出"再点一次就删了"，反而更容易误删。 */
.danger {
  border: 1px solid var(--line-strong);
  background: none;
  color: var(--muted);
  border-radius: 999px;
  padding: 1px 8px;
  font-size: 11px;
  line-height: 1.6;
  cursor: pointer;
}

.danger:hover,
.danger:focus-visible {
  color: #b42318;
  border-color: #b42318;
}

.danger.is-armed {
  color: #fff;
  background: #b42318;
  border-color: #b42318;
}

.node:first-of-type {
  border-top: none;
}

/* 构建号：低调但可读，用来判断页面跑的是哪一代代码（见 ui/build-id.js）。 */
.build-id {
  margin-left: 6px;
  font-size: 11px;
  color: var(--muted);
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  padding: 0 4px;
}

.node-text {
  margin: 2px 0 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.node[data-role="assistant"] .node-text {
  color: #24303f;
}

.nested {
  margin: 8px 0 2px 10px;
  padding-left: 10px;
  border-left: 2px solid var(--line);
}

/* 侧窗内问答链的下一环：与"嵌套侧窗"用不同线型区分，避免读混 */
.node-children {
  margin: 4px 0 2px 8px;
  padding-left: 10px;
  border-left: 2px dotted var(--line-strong);
}

.interrupted {
  margin: 4px 0 0;
  font-size: 11px;
  color: var(--warn);
}

.depth-hint {
  margin: 6px 0 0;
  font-size: 11px;
  color: var(--muted);
}

/* ---------------------------------------------------------------- 追问输入 */

.ask {
  display: flex;
  gap: 6px;
  margin-top: 8px;
  position: sticky;
  bottom: 0;
  padding: 6px 0 2px;
  background: var(--surface);
}

.ask-input {
  flex: 1;
  min-width: 0;
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  padding: 5px 8px;
  font: inherit;
  font-size: 13px;
  background: #fcfcfd;
}

.ask-input:focus {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
  background: #fff;
}

.ask-send {
  border: 1px solid var(--accent);
  background: var(--accent);
  color: #fff;
  border-radius: 6px;
  padding: 5px 12px;
  font-size: 13px;
  cursor: pointer;
}

/* ---------------------------------------------------------------- 状态栏 */

.statusbar {
  display: flex;
  align-items: center;
  gap: 18px;
  flex: none;
  padding: 6px 16px;
  background: var(--surface);
  border-top: 1px solid var(--line);
  font-size: 12px;
  color: var(--muted);
}

#stat-residual {
  font-variant-numeric: tabular-nums;
}

#stat-residual.warn {
  color: var(--warn);
  font-weight: 600;
}

.statusbar .note {
  /* 提示行占满剩余宽度：错误信息要显眼，不能被诊断读数挤到角落 */
  flex: 1 1 auto;
  min-width: 0;
}

/* ── 诊断读数的可展开区 ──────────────────────────────────────────── */
.diagnostics {
  flex: 0 0 auto;
  font-size: 12px;
}

.diagnostics > summary {
  cursor: pointer;
  color: var(--muted);
  /* 去掉默认三角，用文字本身示意（更省地方） */
  list-style: none;
  padding: 0 4px;
  border-radius: 4px;
}

.diagnostics > summary::-webkit-details-marker {
  display: none;
}

.diagnostics > summary::before {
  content: "▸ ";
}

.diagnostics[open] > summary::before {
  content: "▾ ";
}

.diagnostics > summary:hover {
  color: var(--accent);
}

/* 折叠时**彻底不占布局**：只靠 position:absolute 仍会占着 107px 高度（实测），
   那正是"收起来也占地方"的老问题。 */
.diagnostics:not([open]) .diag-body {
  display: none;
}

.diag-body {
  position: absolute;
  right: 16px;
  bottom: 28px;
  z-index: 20;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 10px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 900px) {
  /* 只隐藏把手。侧栏宽度的收窄由 app.js 的 effectiveMaxGutter() 负责——
   * `--gutter-w` 是写在 <html> 上的 inline style，样式表里的媒体查询覆盖不了它，
   * 原来在这里改 :root 的做法从未生效。 */
  .splitter {
    display: none;
  }
}

/* 窄屏退化为单列：停靠项不再绝对定位，改为跟在消息下方流动 */
body.is-narrow .row {
  grid-template-columns: minmax(0, 1fr);
}

body.is-narrow .cell-gutter {
  border-left: none;
  padding: 0 16px 10px 24px;
  min-height: 0;
}

body.is-narrow .rail-item {
  position: static;
  left: auto;
  right: auto;
  margin-bottom: 8px;
}

body.is-narrow .rail-add {
  right: 12px;
}

/* 强制高对比下颜色会被系统覆盖，改用边框线型区分开启/收起 */
@media (forced-colors: active) {
  .marker.is-closed {
    border-style: dashed;
  }

  .marker.is-open {
    border-style: solid;
    border-width: 3px;
  }
}

/* ═══════════════════════════════════════════════════════════════════
   左侧竖栏 + 输入区 + API 设置（2026-10-12 追加）
   body 改为横向 shell，因此下面这几块是新布局的骨架。
   ═══════════════════════════════════════════════════════════════════ */

body {
  flex-direction: row;
}

.shell {
  display: flex;
  flex: 1;
  min-height: 0;
  width: 100%;
}

/* ── 左侧竖栏 ─────────────────────────────────────────────────────── */
.sidebar {
  display: flex;
  flex-direction: column;
  /* 宽度由 --sidebar-w 驱动（唯一写入点是 app.js 的侧栏拖拽），不写死像素 */
  flex: 0 0 var(--sidebar-w);
  width: var(--sidebar-w);
  min-height: 0;
  padding: 10px 8px;
  gap: 8px;
  background: var(--surface);
  border-right: 1px solid var(--line);
}

.workspace {
  display: flex;
  align-items: center;
  padding: 4px 6px;
}

.workspace-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.new-session {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  padding: 8px 10px;
  font: inherit;
  font-size: 13px;
  color: var(--ink);
  background: var(--accent-soft);
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  cursor: pointer;
}

.new-session:hover {
  border-color: var(--accent);
}

.session-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.session-item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 8px;
  border-radius: 6px;
  cursor: pointer;
  /* 会话项是按钮，去掉浏览器默认样式 */
  font: inherit;
  font-size: 13px;
  color: var(--ink);
  text-align: left;
  background: transparent;
  border: 1px solid transparent;
  width: 100%;
}

.session-item:hover {
  background: var(--accent-soft);
}

.session-item[aria-current="true"] {
  background: var(--accent-soft);
  border-color: var(--accent);
  font-weight: 600;
}

.session-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.session-when {
  flex: 0 0 auto;
  font-size: 11px;
  color: var(--muted);
}

.session-del {
  flex: 0 0 auto;
  padding: 0 4px;
  font: inherit;
  font-size: 14px;
  line-height: 1;
  color: var(--muted);
  background: none;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  opacity: 0;
}

.session-item:hover .session-del,
.session-item:focus-within .session-del {
  opacity: 1;
}

.session-del:hover {
  color: var(--warn);
}

.sidebar-foot {
  /*
    竖排：侧栏只有 150-900px 宽（默认约 220px），三个元素横排会互相挤压、
    文字折成两行（实测：API 设置 / 安装到桌面（手动）/ 未配置… 挤在一起很难看）。
    因此改为纵向堆叠，每个占一行。
  */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
}

.link-btn {
  padding: 2px 4px;
  font: inherit;
  font-size: 12px;
  color: var(--accent);
  background: none;
  border: none;
  cursor: pointer;
}

.api-state {
  font-size: 11px;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.api-state.is-warn {
  color: var(--warn);
}

/* ── 侧栏宽度分隔条 ──────────────────────────────────────────────── */
.sidebar-splitter {
  /* flex 项而非 absolute：它夹在 .sidebar 与 .main 之间，随两者一起排布 */
  /* **12px 命中区**：最初写 6px，实测很难按准（鼠标要很精确才能抓住），
     表现为"拖不动"。视觉线仍只有 2px（见 ::after），所以不会显得粗。
     12px 也是 macOS 上原生分隔条的常用宽度。 */
  flex: 0 0 12px;
  width: 12px;
  cursor: col-resize;
  background: transparent;
  touch-action: none;
  position: relative;
}

.sidebar-splitter:hover {
  background: rgba(47, 111, 235, 0.08);
}

.sidebar-splitter::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  /* 视觉线比命中区窄：命中区 12px 好按，视觉线 2px 不抢眼 */
  left: 5px;
  width: 2px;
  background: transparent;
}

.sidebar-splitter:hover::after,
.sidebar-splitter:focus-visible::after,
body.is-dragging-sidebar .sidebar-splitter::after {
  background: var(--accent);
}

.sidebar-splitter:focus-visible {
  outline: none;
}

body.is-dragging-sidebar {
  cursor: col-resize;
  user-select: none;
}

/* ── 主区：加了输入区后，垂直方向由 main 统一分配 ─────────────────── */
.main {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  min-height: 0;
}

/* ── 输入区 ───────────────────────────────────────────────────────── */
.composer {
  /*
    卡片式输入区：输入框在上、工具条在下。
    上下留白比原来大一些，视觉上"这一整块就是输入区"，
    而不是"一个输入框加两个按钮"。
  */
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 0 0 auto;
  margin: 0 16px 12px;
  padding: 10px 12px 8px;
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: 16px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
  transition: border-color 0.12s ease, box-shadow 0.12s ease;
}

/* 聚焦时整张卡片高亮：比只给边框上色更像"这一块被激活了" */
.composer:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(47, 111, 235, 0.12);
}

.composer-input {
  width: 100%;
  /*
    最小高度约两行半：截图里那种"大对话框"的关键在这里——
    原来 38px 只有一行，看起来像个搜索框。
    但也不宜过高：空态下若框内大片空白，会显得"没内容却很占地方"。
  */
  min-height: 60px;
  max-height: 220px;
  padding: 6px 4px;
  font: inherit;
  font-size: 14px;
  line-height: 1.6;
  color: inherit;
  background: transparent;
  border: none;
  resize: none;
  overflow-y: auto;
}

/* 输入框自身不要边框与外轮廓：边框交给外层卡片 */
.composer-input:focus,
.composer-input:focus-visible {
  outline: none;
}

/* 工具条：左 ＋、右发送 */
.composer-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

/*
  蓝色圆形「＋」：图片与文档共用这一个入口。
  用圆形按钮而不是带文字的按钮，是因为工具条上只放图标更清爽，
  文字说明交给 title 与 aria-label（无障碍仍可用）。
*/
.composer-add {
  flex: none;
  width: 30px;
  height: 30px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font: inherit;
  font-size: 19px;
  line-height: 1;
  color: #fff;
  background: var(--accent);
  border: none;
  border-radius: 50%;
  cursor: pointer;
}

.composer-add:hover {
  filter: brightness(1.08);
}

.composer-add:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* 发送：圆形箭头，位置固定在右下角（与截图一致） */
.composer-send,
.composer-stop {
  flex: none;
  font: inherit;
  cursor: pointer;
}

.composer-send {
  width: 30px;
  height: 30px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  color: #fff;
  background: var(--accent);
  border: none;
  border-radius: 50%;
}

.composer-send:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.composer-stop {
  height: 30px;
  padding: 0 12px;
  font-size: 13px;
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 15px;
}

.composer-stop:hover {
  border-color: var(--warn);
  color: var(--warn);
}


/* ── API 设置对话框 ───────────────────────────────────────────────── */
.modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(15, 23, 42, 0.35);
}

.modal-backdrop[hidden] {
  display: none;
}

.modal {
  width: min(440px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  overflow-y: auto;
  padding: 16px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.25);
}

.modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.field {
  display: block;
  margin-bottom: 12px;
}

.field-label {
  display: block;
  margin-bottom: 4px;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
}

.field-input {
  width: 100%;
  padding: 7px 9px;
  font: inherit;
  font-size: 13px;
  color: inherit;
  background: var(--bg);
  border: 1px solid var(--line-strong);
  border-radius: 6px;
}

.field-input:focus {
  outline: none;
  border-color: var(--accent);
}

.field-hint {
  display: block;
  margin-top: 4px;
  font-size: 11px;
  color: var(--muted);
}

.modal-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 16px;
}

.modal-status {
  font-size: 12px;
  color: var(--muted);
}

.modal-status.is-warn {
  color: var(--warn);
}

.modal-actions {
  display: flex;
  gap: 8px;
}

/* ── 窄屏：竖栏收窄，不挤压主区到不可用 ───────────────────────────── */
@media (max-width: 720px) {
  /* 不再写死 flex-basis：宽度统一由 --sidebar-w 决定，
     否则媒体查询会覆盖用户的拖动结果，表现为"拖了没用" */


  .topbar .sub {
    display: none;
  }
}

/* 用量统计：小字、次要色，不抢正文注意力 */
.msg-usage {
  margin-top: 4px;
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* ── 回答的页脚：复制按钮 + 用量统计 ─────────────────────────────── */
.msg-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 6px;
  /* 默认淡，悬停在气泡上时才明显——不抢正文注意力 */
  opacity: 0.45;
  transition: opacity 0.12s ease;
}

.bubble:hover .msg-foot,
.msg-foot:focus-within {
  opacity: 1;
}

.msg-copy {
  padding: 1px 6px;
  font: inherit;
  font-size: 11px;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  cursor: pointer;
}

.msg-copy:hover {
  color: var(--accent);
  border-color: var(--accent);
}

.msg-copy.is-copied {
  color: #137333;
  border-color: #137333;
}

/* 用量统计进页脚后不再需要上外边距 */
.msg-foot .msg-usage {
  margin-top: 0;
}

/* ── 图片暂存区 ─────────────────────────────────────────────────── */
.attach-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  /* 与卡片左右对齐（卡片 margin 16px） */
  padding: 8px 16px 0;
  flex: none;
}

.attach-item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  width: 76px;
}

.attach-thumb {
  width: 76px;
  height: 76px;
  object-fit: cover;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  background: var(--bg);
}

.attach-name {
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  text-align: center;
  font-size: 10px;
  color: var(--muted);
}

.attach-remove {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 18px;
  height: 18px;
  padding: 0;
  font-size: 12px;
  line-height: 1;
  color: #fff;
  background: rgba(17, 24, 39, 0.75);
  border: none;
  border-radius: 50%;
  cursor: pointer;
}

.attach-remove:hover {
  background: #b42318;
}

/* 选图按钮：与输入框同一行 */
.composer-attach {
  flex: none;
  padding: 6px 10px;
  font: inherit;
  font-size: 12px;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  cursor: pointer;
}

.composer-attach:hover {
  color: var(--accent);
  border-color: var(--accent);
}

/* 拖拽落点提示：整块对话区高亮 */
.main.is-dropping {
  outline: 2px dashed var(--accent);
  outline-offset: -8px;
}

/* 屏幕阅读器可见、视觉隐藏（文件选择框） */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ── markdown 正文排版（参照常见聊天界面的克制风格）───────────────── */
.md-body > *:first-child {
  margin-top: 0;
}

.md-body > *:last-child {
  margin-bottom: 0;
}

.md-p {
  margin: 0 0 8px;
}

.md-heading {
  margin: 14px 0 6px;
  line-height: 1.35;
  font-weight: 600;
}

h1.md-heading { font-size: 19px; }
h2.md-heading { font-size: 17px; }
h3.md-heading { font-size: 15px; }
h4.md-heading,
h5.md-heading,
h6.md-heading { font-size: 14px; color: var(--muted); }

.md-list {
  margin: 0 0 8px;
  padding-left: 22px;
}

.md-list li {
  margin: 2px 0;
}

.md-quote {
  margin: 0 0 8px;
  padding: 2px 0 2px 10px;
  border-left: 3px solid var(--line-strong);
  color: var(--muted);
}

.md-hr {
  margin: 12px 0;
  border: none;
  border-top: 1px solid var(--line);
}

.md-inline-code {
  padding: 1px 5px;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 0.92em;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: 4px;
}

.md-link {
  color: var(--accent);
}

/* 代码块：头部（语言 + 复制）固定，正文可横向滚动 */
.md-code {
  margin: 0 0 8px;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg);
}

.md-code-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 8px;
  border-bottom: 1px solid var(--line);
  font-size: 11px;
  color: var(--muted);
}

.md-code-copy {
  padding: 1px 6px;
  font: inherit;
  font-size: 11px;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  cursor: pointer;
}

.md-code-copy:hover {
  color: var(--accent);
  border-color: var(--accent);
}

.md-code-body {
  margin: 0;
  padding: 8px 10px;
  overflow-x: auto;
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 12.5px;
  line-height: 1.55;
}

.md-code-body code {
  font: inherit;
  white-space: pre;
}

/* 表格：外框 + 表头底色，窄屏可横向滚动 */
.md-table {
  width: 100%;
  margin: 0 0 8px;
  border-collapse: collapse;
  font-size: 13px;
  /* 列多时不挤成一团，允许横向滚动（外层包裹见渲染层） */
  display: block;
  overflow-x: auto;
}

.md-th,
.md-td {
  padding: 5px 9px;
  border: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}

.md-th {
  background: var(--accent-soft);
  font-weight: 600;
}

/* ── 对话中的图片 ─────────────────────────────────────────────────── */
.msg-image {
  display: block;
  max-width: 100%;
  max-height: 320px;
  margin: 0 0 8px;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  background: var(--bg);
  /* 原图可能很大，按比例缩放而不是拉伸 */
  object-fit: contain;
}

.msg-attach-broken {
  margin: 0 0 8px;
  padding: 6px 8px;
  font-size: 12px;
  color: #b42318;
  background: #fef3f2;
  border: 1px solid #fecdca;
  border-radius: 6px;
}

/* ── 对话里模型产出的文件 ─────────────────────────────────────────── */
.msg-file {
  margin: 0 0 8px;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  overflow: hidden;
  background: var(--bg);
}

.msg-file-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  font-size: 12px;
}

.msg-file-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
}

.msg-file-size {
  flex: none;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.msg-file-actions {
  flex: none;
  display: flex;
  gap: 6px;
}

.msg-file-btn {
  padding: 2px 8px;
  font: inherit;
  font-size: 11px;
  color: var(--muted);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  cursor: pointer;
}

.msg-file-btn:hover {
  color: var(--accent);
  border-color: var(--accent);
}

.msg-file-save {
  color: #fff;
  background: var(--accent);
  border-color: var(--accent);
}

.msg-file-save:hover {
  color: #fff;
  filter: brightness(1.08);
}

.msg-file-preview {
  margin: 0;
  padding: 8px 10px;
  max-height: 320px;
  overflow: auto;
  border-top: 1px solid var(--line);
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 12px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-break: break-word;
}

.msg-file-preview code {
  font: inherit;
}

/* ── 设置项：复选框与标签同一行 ───────────────────────────────────── */
.field-inline {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.field-inline input[type="checkbox"] {
  flex: none;
  width: 14px;
  height: 14px;
  margin: 0;
  accent-color: var(--accent);
}

.field-inline .field-label {
  flex: none;
}

.field-inline .field-hint {
  /* 提示紧跟标签，占满剩余宽度并自然折行 */
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
}

/* ── 搜索来源 ─────────────────────────────────────────────────────── */
.msg-sources {
  margin: 8px 0 6px;
  padding: 6px 10px;
  border-left: 3px solid var(--accent);
  background: var(--bg);
  border-radius: 0 6px 6px 0;
  font-size: 12px;
}

.msg-sources-head {
  margin-bottom: 4px;
  color: var(--muted);
}

.msg-sources-list {
  margin: 0;
  padding-left: 18px;
}

.msg-sources-list li {
  margin: 2px 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.msg-source-link {
  color: var(--accent);
}

/*
  安装按钮的手动说明。
  平时 hidden；只有在浏览器没给出安装事件、用户又点了按钮时才展开——
  此时需要说明"去哪找安装入口"，否则按钮看起来像坏的。
*/
.install-hint {
  margin: 0 0 8px;
  padding: 0 10px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
}

/*
  诊断区里可点击的状态项（目前是"上下文"）。
  与旁边的 span 视觉一致，但允许点击触发动作，所以要去掉按钮默认样式。
*/
.stat-button {
  padding: 0;
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
  text-align: left;
}

.stat-button:hover {
  color: var(--accent);
  text-decoration: underline;
}

/* 占用偏高时提示可以从这里压缩 */
.stat-button.warn {
  color: var(--warn);
  font-weight: 600;
}

/*
  「上下文」常驻在状态栏，需要与说明行分开一点，并保证不被挤压。
  `margin-left:auto` 把它推到右侧，与折叠的「诊断」相邻。
*/
#stat-context {
  flex: 0 0 auto;
  margin-left: auto;
  padding: 0 6px;
  white-space: nowrap;
}
