/* ============================================================
   0. 本地字体（fonts/ 与本文件同级）
   ============================================================ */
@font-face{
  font-family:"Anthropic Serif";
  src:url("fonts/AnthropicSerif-Roman.woff2") format("woff2"),
      url("fonts/AnthropicSerif-Roman.ttf") format("truetype");
  font-weight:300 800;
  font-style:normal;
  font-display:swap;
}
@font-face{
  font-family:"Anthropic Serif";
  src:url("fonts/AnthropicSerif-Italic.woff2") format("woff2"),
      url("fonts/AnthropicSerif-Italic.ttf") format("truetype");
  font-weight:300 800;
  font-style:italic;
  font-display:swap;
}
@font-face{
  font-family:"Anthropic Sans";
  src:url("fonts/AnthropicSans-Roman.woff2") format("woff2"),
      url("fonts/AnthropicSans-Roman.ttf") format("truetype");
  font-weight:300 800;
  font-style:normal;
  font-display:swap;
}
@font-face{
  font-family:"Anthropic Sans";
  src:url("fonts/AnthropicSans-Italic.woff2") format("woff2"),
      url("fonts/AnthropicSans-Italic.ttf") format("truetype");
  font-weight:300 800;
  font-style:italic;
  font-display:swap;
}

/* 同一份字体文件，但用 unicode-range 把它限制在拉丁字母、数字和 ASCII 标点上。
   浏览器只会拿它去渲染落在这个区间里的字符，中文自动落到 font-family 里的
   下一个候选 —— 所以这不是"两套字体互相抢"，而是按码位分工。

   为什么不直接把 "Anthropic Sans" 排在最前面就完事：那样能不能生效完全取决于
   这个字体文件里有没有中文字形。有的话中文就被它接管了，字形不对；没有的话
   碰巧能work，但那是靠运气而不是靠声明。unicode-range 是把意图写死。

   区间只取 U+0000-00FF（ASCII + 拉丁扩展，含全部英文字母、数字、英文标点）
   加几个常见连字。**故意不含 U+2000-206F（通用标点）**：破折号、省略号、
   弯引号这些是中英文共用的，划给英文字体会让中文段落里的标点风格突变。
   如果你希望英文引号也用 Anthropic Sans，把 U+2018-201F 加进来即可。 */
/* Serif 的拉丁专用族。和上面 Sans Latin 同样的思路：同一份字体文件，
   用 unicode-range 限制在拉丁字母、数字和 ASCII 标点上，中文自动落到
   font-family 里的下一个候选。区间和 Sans Latin 保持一致，
   不含 U+2000-206F —— 破折号省略号弯引号是中英共用的，划给英文字体
   会让中文段落里的标点风格突变。*/
@font-face{
  font-family:"Anthropic Serif Latin";
  src:url("fonts/AnthropicSerif-Roman.woff2") format("woff2"),
      url("fonts/AnthropicSerif-Roman.ttf") format("truetype");
  font-weight:300 800;
  font-style:normal;
  font-display:swap;
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC;
}
@font-face{
  font-family:"Anthropic Serif Latin";
  src:url("fonts/AnthropicSerif-Italic.woff2") format("woff2"),
      url("fonts/AnthropicSerif-Italic.ttf") format("truetype");
  font-weight:300 800;
  font-style:italic;
  font-display:swap;
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC;
}
@font-face{
  font-family:"Anthropic Sans Latin";
  src:url("fonts/AnthropicSans-Roman.woff2") format("woff2"),
      url("fonts/AnthropicSans-Roman.ttf") format("truetype");
  font-weight:300 800;
  font-style:normal;
  font-display:swap;
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC;
}
@font-face{
  font-family:"Anthropic Sans Latin";
  src:url("fonts/AnthropicSans-Italic.woff2") format("woff2"),
      url("fonts/AnthropicSans-Italic.ttf") format("truetype");
  font-weight:300 800;
  font-style:italic;
  font-display:swap;
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC;
}

/* Anthropic Mono。Roman/Italic 两份，和上面 Serif/Sans 同样的两段式声明：
   "Anthropic Mono" 是完整族（真要等宽排版时用），
   "Anthropic Mono Latin" 带 unicode-range，只接管拉丁字母/数字/ASCII 标点，
   中文自动落到 font-family 里的下一个候选（微软雅黑）。
   行内 code 是中英混排的，所以用的是后者。 */
@font-face{
  font-family:"Anthropic Mono";
  src:url("fonts/AnthropicMono-Roman.woff2") format("woff2"),
      url("fonts/AnthropicMono-Roman.ttf") format("truetype");
  font-weight:300 800;
  font-style:normal;
  font-display:swap;
}
@font-face{
  font-family:"Anthropic Mono";
  src:url("fonts/AnthropicMono-Italic.woff2") format("woff2"),
      url("fonts/AnthropicMono-Italic.ttf") format("truetype");
  font-weight:300 800;
  font-style:italic;
  font-display:swap;
}
@font-face{
  font-family:"Anthropic Mono Latin";
  src:url("fonts/AnthropicMono-Roman.woff2") format("woff2"),
      url("fonts/AnthropicMono-Roman.ttf") format("truetype");
  font-weight:300 800;
  font-style:normal;
  font-display:swap;
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC;
}
@font-face{
  font-family:"Anthropic Mono Latin";
  src:url("fonts/AnthropicMono-Italic.woff2") format("woff2"),
      url("fonts/AnthropicMono-Italic.ttf") format("truetype");
  font-weight:300 800;
  font-style:italic;
  font-display:swap;
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC;
}

/* anthropic-sans —— 小写连字符的这个名字是 claude.ai 线上那份 CSS 里用的族名。
   侧栏 Recents 那一列直接照抄了它的字体栈（见 --font-sans-recents），
   所以这里补一条同名声明，让那个名字在本地真的指向 Anthropic Sans 的字体文件；
   不补的话浏览器认不出这个族，第一顺位直接落空，整列掉到 system-ui。

   带 unicode-range，只接管拉丁字母/数字/ASCII 标点 —— 跟 "Anthropic Sans Latin"
   同一套区间。汉字于是继续往后找，落到 system-ui（Windows 上是 Segoe UI，
   它没有汉字，浏览器再往下走到系统默认中文字体，也就是微软雅黑）。
   这正是那份字体栈里一个中文字体都没写、中文却仍然是雅黑的原因。 */
@font-face{
  font-family:anthropic-sans;
  src:url("fonts/AnthropicSans-Roman.woff2") format("woff2"),
      url("fonts/AnthropicSans-Roman.ttf") format("truetype");
  font-weight:300 800;
  font-style:normal;
  font-display:swap;
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC;
}
@font-face{
  font-family:anthropic-sans;
  src:url("fonts/AnthropicSans-Italic.woff2") format("woff2"),
      url("fonts/AnthropicSans-Italic.ttf") format("truetype");
  font-weight:300 800;
  font-style:italic;
  font-display:swap;
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC;
}

/* 思源黑体（Noto Sans SC）—— 中文用。
   Anthropic Sans 没有任何中文字形（实测 625 个字形，无 CJK），以前汉字是掉到
   系统的苹方/雅黑，字重和字面跟 Anthropic Sans 对不齐。这里自带一份，
   小字号下骨架比苹方更贴。

   这份文件是子集 + 可变字体：
   - 字符范围取 GB2312 全集（一级 3755 + 二级 3008 + 符号区）+ 拉丁 + 中文标点
     + 全角形式，共 7812 个码位。原始文件 15MB，子集后 woff2 1.7MB。
   - wght 轴用 varLib.instancer 从 100–900 收到 300–700（UI 只用到 400/500/600），
     省掉两端不用的插值数据。
   - unicode-range 限定在 CJK 相关区段：不写这行的话，浏览器渲染纯英文页面时
     也会把这 1.7MB 拉下来。写了之后只有真的出现汉字才下载。
   - GB2312 之外的生僻字（"甪""崂"之类）落在 unicode-range 内但文件里没有字形，
     浏览器会按字符继续往 font-family 后面找，即掉到系统苹方 —— 不会变豆腐块。
   - font-display:swap：1.7MB 不该挡首屏，先用系统字体顶上，下完再换。

   要更小可以只保留 wght=400 的静态实例（约 1.0MB），代价是 500/600 会变合成粗体。 */
@font-face{
  font-family:"Noto Sans SC Subset";
  src:url("fonts/NotoSansSC-Subset-VF.woff2") format("woff2-variations"),
      url("fonts/NotoSansSC-Subset-VF.woff2") format("woff2");
  font-weight:300 700;
  font-style:normal;
  font-display:swap;
  unicode-range:U+2E80-2EFF, U+3000-303F, U+3400-4DBF, U+4E00-9FFF,
                U+F900-FAFF, U+FE10-FE1F, U+FE30-FE4F, U+FF00-FFEF;
  /* 可选：度量覆盖。思源黑体原生 ascent/descent 是 116% / 32%，比 Anthropic Sans
     高出一截，所以中英混排的段落里只要冒出一个汉字，整行行盒就会被撑高、基线下移，
     表现为行距忽宽忽窄、图标和文字对不齐。把下面三行取消注释，就能让它和拉丁字体
     共用一套行盒，上面这些问题一次性消掉。
     百分比要填 Anthropic Sans 的实测值，控制台里跑：
       await document.fonts.ready;
       const c = document.createElement('canvas').getContext('2d');
       c.font = '100px "Anthropic Sans Latin"';
       const m = c.measureText('Hxg');
       console.log(m.fontBoundingBoxAscent, m.fontBoundingBoxDescent);   // 两个数就是百分比
     下面 96 / 24 只是常见拉丁无衬线体的典型值，不是量出来的，别直接用。
     副作用：ascent 压到 88% 以下时，行高很紧的地方相邻两行汉字可能会咬到一起。
  ascent-override:96%;
  descent-override:24%;
  line-gap-override:0%;
  */
}

/* ============================================================
   1. 设计令牌
   ============================================================ */
:root{
  /* 想让全站衬线体都用 Anthropic Serif，把它加到下面这行最前面即可 */
  --font-anthropic-serif: "Anthropic Serif", "Copernicus", "Tiempos Text", Georgia, "Songti SC", "Times New Roman", serif;
  /* "Anthropic Serif" 之前漏在这个栈外面：@font-face 声明了、字体文件也加载了，
     但没有任何 font-family 引用到它，于是标题和字标一直在用 Copernicus/Georgia
     兜底。补在最前面。*/
  --font-serif: "Anthropic Serif", "Copernicus", "Tiempos Text", Georgia, "Songti SC", "Times New Roman", serif;
  /* 侧栏专用无衬线体（CJK 交给后面的回退字体） */
  --font-anthropic-sans: "Anthropic Sans", "Noto Sans SC Subset",
               "Source Han Sans SC", "Noto Sans SC", "Noto Sans CJK SC",
               "Styrene B", -apple-system, BlinkMacSystemFont, "Segoe UI",
               "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Helvetica, Arial, sans-serif;
  /* "Anthropic Sans Latin" 放在最前面：它带 unicode-range，只接管拉丁字母/数字/
     ASCII 标点，汉字自动落到后面的 PingFang / 雅黑。
     以前这个栈的第一顺位是 "Styrene B" —— 那份字体 fonts/ 里没有，也不在系统里，
     于是凡是只写 var(--font-sans) 的地方（body、输入框正文、用户气泡、模型档位
     "Medium"）英文全都掉到系统 sans。补在这里之后这些地方自动跟上，
     不用一处处挂 var(--font-latin)。
     注意：Anthropic Sans 本身没有中文字形（实测 625 个字形，无 CJK），
     所以汉字交给紧随其后的思源黑体。

     顺序：Anthropic Sans Latin（拉丁/数字）→ Noto Sans SC Subset（自带子集，
     GB2312 范围内的汉字）→ 系统上装了的完整思源黑体（补生僻字）→ 苹方/雅黑
     （最后兜底）。前两个都带 unicode-range，各管各的码位，不会互相抢。*/
  --font-sans: "Anthropic Sans Latin", "Noto Sans SC Subset",
               "Source Han Sans SC", "Noto Sans SC", "Noto Sans CJK SC",
               "Styrene B", -apple-system, BlinkMacSystemFont, "Segoe UI",
               "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", Helvetica, Arial, sans-serif;
  /* 侧栏 Recents 那一列对话标题专用。原样照抄 claude.ai 线上那份字体栈
     （在他们的 devtools 里读出来的）：
       anthropic-sans, system-ui, "Segoe UI", Roboto, Helvetica, Arial,
       sans-serif, ui-sans-serif, system-ui, -apple-system

     里面**一个中文字体都没有**。中文靠浏览器的逐字回退落到系统默认中文字体
     —— Windows 上就是微软雅黑。所以这一栈不需要、也不应该显式写雅黑。

     跟正文那个 --font-sans 的关键区别：**不含思源黑体**。
     思源排在前面的话汉字会被它接管，就落不到雅黑了。

     中间一度把思源黑体插进来过，为的是能把字重调到 400 和 700 之间
     （雅黑没有中间档）。撤了 —— 线上根本不靠字重：同一份栈、同样一档
     Regular，它看着"实"靠的是字号 14px 和几乎纯黑的字色（devtools 上量到
     #0B0B0B、对比度 16.64）。这一列想调视觉重量，动 font-size 和 color，
     别动 font-weight。

     照抄归照抄，有一点得记着：`sans-serif` 是通用族、一定命中，
     所以它后面那三项（ui-sans-serif / system-ui / -apple-system）永远走不到。
     保留只是为了跟线上那份逐字一致。 */
  --font-sans-recents: anthropic-sans, system-ui, "Segoe UI", Roboto,
               Helvetica, Arial, sans-serif, ui-sans-serif, system-ui,
               -apple-system;
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  /* 放在任何字体栈最前面用：只接管英文和数字，中文继续走后面的候选 */
  --font-latin: "Anthropic Sans Latin";
  /* 同上，但衬线。现在只剩思维链正文（.think-pre）在用；模型回答正文已改回 Sans */
  --font-latin-serif: "Anthropic Serif Latin";
  /* 行内 code 用：Anthropic Mono 的拉丁专用族 */
  --font-latin-mono: "Anthropic Mono Latin";
  --font-anthropic-mono: "Anthropic Mono";
  /* 对话内容列宽度。输入框是 780px，所以两侧各内收 (780 - 值) / 2。
     整体左右位置见 .feed / .composer-dock 的 padding-left —— 那个一起挪，
     不会破坏这里的对称。*/
  --col-max: 700px;

  --sidebar-w: 288px;
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-xl: 20px;

  --accent: #d97757;
  /* AI 回复正文的统一字号。.md 里所有文字（标题/列表/行内 code/公式）
     都被钉在这一个数上，改这里就整体缩放，不用再逐条找。 */
  --md-fs: 15.5px;
  --ok: #4a9d6e;
  --danger: #c2543f;
  --ease: cubic-bezier(.32,.72,0,1);

  /* 输入框描边的两个「共用件」——必须放在 :root，不能放在某个主题块里。
     它们之前定义在 [data-theme="light"] 下，结果暗色下 var(--composer-ambient)
     解析不出来：CSS 里只要 box-shadow 里有一个 var() 是未定义的，
     **整条声明**在计算值阶段就作废（不是忽略那一段，是整条没了），
     于是暗色下输入框一条边都不画。这类 bug 不报错、不留痕迹，只是"没效果"。

     官网浅色暗色用的是同一组弥散阴影（3.5% / 7.5% 的黑），所以放这儿也对。
     --cds-ring-hairline：1x 屏 1px，2x 屏 0.5px（见 .composer 附近的 media query）。 */
  --cds-ring-hairline: 1px;
  --composer-ambient:       0 0.25rem 1.25rem rgb(0 0 0 / 0.035);
  --composer-ambient-focus: 0 0.25rem 1.25rem rgb(0 0 0 / 0.075);
}

/* 亮色 */
[data-theme="light"]{
  /* 正文里的超链接色。要求是"白色"——但亮色主题下白字在白底上等于看不见，
     所以亮色这里取正文色（跟周围文字同色，仅靠下划线区分），
     暗色才是真正的白。想两套都强制纯白，把下面这行改成 #ffffff 即可。 */
  --md-link:      var(--text-body);
  /* 行内 code 的字色。浅色下用更深的 #943333（#C86D6D 在浅底上发飘），
     暗色仍是原来的玫瑰色。 */
  --code-fg:      #943333;
  --edit-ring:    #b9b8b2;
  --bg-main:      #fcfcfb;
  --bg-sidebar:   #fcfcfb;
  --bg-composer:  #ffffff;
  /* 输入框自己的底色，从 --bg-composer 里拆出来单开一个变量。
     --bg-composer 还被另外三处借用（.icon-btn.btn-plain:hover、代码块头、
     附件卡片），那几处要的是"比页面底色亮一档"，跟着输入框一起变会让
     它们在暗色下直接糊进背景。浅色这两个值目前相同，拆开只是为了以后
     单独调输入框时不会误伤它们。 */
  --composer-bg:  #ffffff;
  --bg-pop:       #ffffff;
  --bg-hover:     rgba(0,0,0,.045);
  --bg-active:    rgba(0,0,0,.07);
  /* 侧栏那一列（New/Chats/... 和 Recents 里的历史对话）单独一套底色。
     不复用 --bg-hover / --bg-active 的半透明黑：那两个是叠在任意底上的通用
     值，而侧栏要的是设计稿里定死的两个实色，半透明叠出来的灰偏冷、也压不准。 */
  --bg-nav-hover:  #F0EFEC;
  --bg-nav-active: #EDECE8;
  /* 顶栏右上角的 Beta 标签 */
  --bg-beta:      #EDECE8;
  --fg-beta:      #3d3d3a;
  /* 头像那个账户菜单单独一套底色。不跟 --bg-pop / --bg-hover 走：
     那两个是所有浮层共用的通用值，这里要的是设计稿定死的实色。 */
  --bg-acct:      #FFFFFF;
  --bg-acct-hover:#F3F3F3;
  /* 菜单是纯白的，浮在同样发白的侧栏上（--bg-sidebar #fcfcfb），
     只靠 --border(#e8e6e0) 那道线几乎看不出边界。这里单独给一档更实的灰。 */
  --bd-acct:      #D3D1C9;
  /* 历史对话那一行右边三个点自己的 hover 底色。比行底色再深一档 ——
     它经常压在已经有底色的行上（hover 行、当前行），同色就看不出反馈了。 */
  --bg-more-hover:#E2E0DA;
  --danger:       #C2453B;
  --bg-danger-hover:#FBEDEB;
  /* 菜单里的灰字（顶上那行邮箱、行尾的快捷键、右侧的小箭头）。
     比全局 --text-muted(#8b8a84) 稍暖一点，是设计稿给的值。 */
  --fg-acct-muted:#898781;
  --bg-code:      #FEFDFD;
  /* 行内 code 的玫瑰色底纹（与 #C86D6D 同色系，带透明）。亮色下浅一点。 */
  --bg-inline-code:     #F3F3F2;   /* 行内 code 底纹（亮色），实色贴主题 */
  --bg-avatar:    #2c2b28;
  --fg-avatar:    #f5f4ee;

  --text-strong:  #1f1e1d;
  --text-body:    #1f1e1d;   /* 亮色下正文就用原来的深色，见暗色块里的说明 */
  --text-greeting:#1a1a1a;
  --text:         #3d3d3a;
  --text-muted:   #8b8a84;
  --text-faint:   #a5a49d;
  /* Recents 左边那个点在"正在生成"时的颜色。灰色，不是主题橙 ——
     它标的是"这条还在跑"，属于状态提示，不该跟 accent 抢；一列里同时有两三条
     在跑的时候，三个橙点比内容还抢眼。取值是从设计稿里量出来的（#A4A29D），
     刚好跟 --text-faint 重合，但仍然单开一个名字：这两者语义不同，
     哪天正文的次要灰要调，不该顺手把这个点也带走。 */
  --dot-live:     #a5a49d;
  /* Recents 里当前这条对话的文字颜色。**只换颜色，不加粗** ——
     一列里唯一一条变粗，会把这一行的字面宽度也顶开（雅黑没有中间字重，
     500 在拉丁字母上是真的变粗、汉字纹丝不动），于是中英混排的那条
     看着比邻居"胖"一截，还更容易撞省略号。颜色是零成本的状态区分。
     #0B0B0B 是从 claude.ai 的 devtools 上量的（那条选中项的字色，
     对比度 16.64）—— 比全局的 --text-strong(#1f1e1d) 还实一档。 */
  --recent-fg-active: #0b0b0b;

  --border:       #e8e6e0;
  --border-strong:#dcdad3;
  /* 输入框专用描边。不复用 --border-strong：那个是不透明的暖灰（#dcdad3），
     在输入框这种大圆角、无阴影的大块面上显得偏黄也偏重。半透明黑会
     跟着下面的底色走，投在白底上就是中性淡灰，和目标稿一致。 */
  /* 官网做法：没有 CSS border，边线是 box-shadow 画的“环”。
     厚度永远不超过 1px——看起来“刚好”不是靠加粗，是靠两件事：
       1) 环本身很淡（alpha 0.15），交互时只改 alpha 不改宽度；
       2) 环下面垫一层大范围弥散阴影，把块面从背景上托起来。
     弥散阴影和 --cds-ring-hairline 两个主题共用，定义在 :root，不在这里。 */
  --composer-border:       hsl(60 2% 12% / 0.15);
  --composer-border-hover: hsl(60 2% 12% / 0.30);
  --composer-border-focus: hsl(60 2% 12% / 0.30);
  --composer-edge-shadow:
    var(--composer-ambient),
    0 0 0 var(--cds-ring-hairline) var(--composer-border);
  --composer-edge-shadow-hover:
    var(--composer-ambient),
    0 0 0 var(--cds-ring-hairline) var(--composer-border-hover);
  --composer-edge-shadow-focus:
    var(--composer-ambient-focus),
    0 0 0 var(--cds-ring-hairline) var(--composer-border-focus);
  --shadow-composer: 0 2px 4px rgba(0,0,0,.03), 0 8px 24px rgba(0,0,0,.05);
  --shadow-pop:   0 4px 16px rgba(0,0,0,.10), 0 1px 3px rgba(0,0,0,.06);
  --scroll-thumb: #d4d2ca;
  /* 悬停小提示（目前只有回答末尾那个时间在用）。亮色下是近黑底白字。 */
  --tip-bg:       #0b0b0b;
  --tip-fg:       #fcfcfb;
  --tip-border:   transparent;
}

/* 暗色 */
[data-theme="dark"]{
  --md-link:      #ffffff;
  --code-fg:      #C86D6D;
  --edit-ring:    #2f6fe4;
  --bg-main:      #151515;
  --bg-sidebar:   #111111;
  /* 注意：这个值不再作用于输入框，输入框走下面的 --composer-bg。
     这里的 #383835 留给那三处"要比背景亮一档"的小控件。 */
  --bg-composer:  #383835;
  /* 暗色输入框底色。比 --bg-main(#151515) 亮，靠描边把它
     从页面上分出来，而不是靠明度差。 */
  --composer-bg:  #20201F;
  --bg-pop:       #30302e;
  --bg-hover:     rgba(255,255,255,.055);
  --bg-active:    rgba(255,255,255,.09);
  /* 暗色下 hover 和激活是同一个值 —— 这是设计要求，不是漏写。 */
  --bg-nav-hover:  #232323;
  --bg-nav-active: #232323;
  --bg-beta:      #232323;
  --fg-beta:      #C3C2B7;
  --bg-acct:      #20201F;
  --bg-acct-hover:#313130;
  /* 暗色下菜单比底色亮，本来就分得开，沿用通用描边即可 */
  --bd-acct:      var(--border);
  --fg-acct-muted:var(--text-muted);
  --bg-more-hover:#3A3A39;
  --danger:       #E8695D;
  --bg-danger-hover:#3A2523;
  --bg-code:      #1A1A19;
  --bg-inline-code:     #1E1E1D;   /* 行内 code 底纹（暗色） */
  --bg-avatar:    #c9c7bf;
  --fg-avatar:    #1f1e1d;

  --text-strong:  #f5f4ee;
  /* 对话正文（模型回答 + 用户气泡）在暗色下用纯白。
     --text-strong 是暖白 #f5f4ee，用在侧栏、按钮这些界面元素上没问题，
     但大段正文并排看时会显得发灰。正文单独一个变量，只改这一处，
     不影响其余 UI 的整体色调。亮色模式沿用原来的正文色。*/
  --text-body:    #ffffff;
  --text-greeting:#ffffff;
  --text:         #d6d4cc;
  --text-muted:   #8f8e87;
  --text-faint:   #6e6d67;
  /* 暗色下取 #8F8E87（量出来是 #87857F，差一点点，直接用现成的 muted 值）。
     不能跟着用亮色那个 --text-faint：暗色的 faint 是 #6e6d67，
     压在 #313130 的行底色上几乎看不见，"闪烁"就只剩"偶尔冒一下"。 */
  --dot-live:     #8f8e87;
  /* 暗色下用纯白：深底上要的是"这条更亮"，任何带灰的值都会往回退一档。 */
  --recent-fg-active: #ffffff;

  --border:       #3a3937;
  --border-strong:#4a4946;
  /* 描边不复用上面的 --border。从官网暗色截图上量的：输入框底色 #20201F
     （和 --composer-bg 完全一致），描边峰值 (77,77,76) = #4D4D4C。
     --border 是 (58,57,55)，比官网暗了近 20 阶——这就是"看着完全不一样"的原因：
     #3a3937 压在 #20201F 上只差 26 阶，边基本糊进底色里了。

     截图上这条线跨了两个像素（77 然后 54），说明元素边界没落在整像素上被抗锯齿
     摊开了。取峰值 #4D4D4C 是保守值；如果你那边渲染得很实、显得比官网亮，
     往回收到 #464544；反之觉得还不够，最多到 #636362（把两像素的墨量合回一条线的值）。

     hover/focus 那一档截图里没有，是按浅色 0.15→0.30 的翻倍关系折算的估值。

     深色仍然是 inset 1px，线画在框内侧、不占外圈厚度，也不用 0.5px 发丝环：
     半像素的白线抗锯齿后在深底上基本看不见，所以固定 1px、靠亮度分档。 */
  --composer-border:       #383837;
  --composer-border-hover: #4d4d4c;
  --composer-border-focus: #4d4d4c;
  --composer-edge-shadow:
    var(--composer-ambient),
    inset 0 0 0 1px var(--composer-border);
  --composer-edge-shadow-hover:
    var(--composer-ambient),
    inset 0 0 0 1px var(--composer-border-hover);
  --composer-edge-shadow-focus:
    var(--composer-ambient-focus),
    inset 0 0 0 1px var(--composer-border-focus);
  --shadow-composer: 0 2px 6px rgba(0,0,0,.28);
  --shadow-pop:   0 4px 20px rgba(0,0,0,.45), 0 1px 3px rgba(0,0,0,.3);
  --scroll-thumb: #4a4946;
  /* 暗色下**不是**反过来的白底黑字：仍然是深色小块，只比背景亮一点点，
     靠一圈更亮的描边把它从底上分出来。整块反白在深色界面上太扎眼。 */
  --tip-bg:       #20201f;
  --tip-fg:       #edece8;
  --tip-border:   #2b2b2a;
}

/* ============================================================
   2. 基础
   ============================================================ */
*,*::before,*::after{box-sizing:border-box;}
html,body{height:100%;}
body{
  margin:0;
  font-family:var(--font-sans);
  font-size:14px;
  line-height:1.5;
  color:var(--text);
  background:var(--bg-main);
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  overflow:hidden;
}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer;}
input,textarea{font:inherit;}
svg{display:block;flex:none;}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--radius-sm);}

.scroll{overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--scroll-thumb) transparent;}
.scroll::-webkit-scrollbar{width:6px;}
.scroll::-webkit-scrollbar-track{background:transparent;}
.scroll::-webkit-scrollbar-thumb{background:var(--scroll-thumb);border-radius:3px;}

.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
}
.mono{font-family:var(--font-mono);font-size:12px;}

/* ============================================================
   3. 骨架
   ============================================================ */
.app{display:flex;height:100dvh;width:100%;}

/* ---------- 侧栏 ---------- */
.sidebar{
  /* 侧栏整体用 Anthropic Sans；.wordmark 单独保留衬线体 */
  font-family:var(--font-anthropic-sans);
  width:var(--sidebar-w);
  flex:none;
  display:flex;
  flex-direction:column;
  background:var(--bg-sidebar);
  border-right:1px solid var(--border);
  transition:margin-left .35s var(--ease);
}
.app[data-sidebar="closed"] .sidebar{margin-left:calc(var(--sidebar-w) * -1);}

.sidebar-head{
  flex:none;
  display:flex;align-items:center;gap:4px;
  height:50px;padding:8px 10px 8px 8px;
}
.wordmark{
  font-family:var(--font-serif);
  font-size:21px;
  letter-spacing:-.01em;
  color:var(--text-strong);
}
.sidebar-head .wordmark{font-size:21px;line-height:28px;font-weight:500;letter-spacing:-.6px;color:#0b0b0b;}
.sidebar-head .sidebar-collapse{width:32px;height:32px;flex:none;color:#898984;}
.head-actions{display:flex;align-items:center;margin-left:auto;padding:2px;border-radius:8px;background:#efefed;}
.head-actions .workspace-btn{width:32px;height:24px;border-radius:6px;color:#898984;}
.head-actions .workspace-btn svg{width:16px;height:16px;}
.head-actions .workspace-btn[aria-pressed="true"]{background:#fff;color:#222;box-shadow:0 0 0 1px #e5e5e3,0 1px 3px #00000014;}
[data-theme="dark"] .sidebar-head .wordmark{color:#f5f5f2;}
[data-theme="dark"] .head-actions{background:#1e1e1e;}
[data-theme="dark"] .head-actions .workspace-btn[aria-pressed="true"]{background:#333;color:#e8e8e3;box-shadow:0 0 0 1px #484848,0 1px 3px #00000026;}

.icon-btn{
  display:grid;place-items:center;
  width:30px;height:30px;
  border-radius:var(--radius-sm);
  color:var(--text-muted);
  transition:background .15s,color .15s;
}
.icon-btn:hover{background:var(--bg-hover);color:var(--text-strong);}
.icon-btn.btn-plain:hover{background:var(--bg-composer);color:var(--text-strong);}
.icon-btn:disabled{opacity:.4;cursor:default;}

/* 导航 */
.nav{padding:2px 8px;}
.sidebar-new{flex:none;padding-bottom:0;}
.sidebar-scroll > .nav:first-child{padding-top:0;}
/* Match the scroller's reserved scrollbar space in both themes so the two
   navigation sections end at the same edge. Theme colors stay independent. */
.sidebar-new{
  overflow:hidden;scrollbar-gutter:stable;scrollbar-width:thin;padding-right:2px;
}
.sidebar-new::-webkit-scrollbar{width:6px;}
.sidebar-scroll > .nav{padding-right:2px;}
[data-theme="dark"] .sidebar{
  --bg-nav-active:#343434;
  --bg-nav-hover:#232323;
}
.nav-item{
  display:flex;align-items:center;gap:10px;
  width:100%;
  font-weight:450;
  padding:7px 8px;
  border-radius:var(--radius-md);
  color:var(--text);
  text-align:left;
  transition:background .15s;
}
.nav-item:hover{background:var(--bg-nav-hover);}
/* 激活态只由 JS 给 New / Chats 打（见 app.js 的 setNavActive）。
   Projects / Artifacts / Customize 现在只有 hover，没有激活 —— 它们还没有
   对应的页面，亮着一个点不进去的高亮只会让人以为坏了。 */
.nav-item[aria-current="page"]{background:var(--bg-nav-active);color:var(--text-strong);}
.nav-item svg{flex:none;color:var(--text-muted);}
.nav-item[aria-current="page"] svg{color:var(--text-strong);}
/* 新建（add）那个图标是"圆底 + 加号"，实心底纹的视觉重量和其余描边图标
   不一样 —— 画成同样的 17px 会显得瘪，所以放大到 20px。
   但布局上仍然让它只占 17px（负 margin 把多出来的 3px 吃回去），
   否则这一行的文字会比上下几行往右缩一格，整列的左边缘就参差了。 */
.nav-item .ic-add{margin:-1.5px;}

.section-label{
  display:flex;align-items:center;justify-content:space-between;
  padding:6px 16px 4px;
  font-size:12px;
  font-weight:500;
  color:var(--text-faint);
}
.section-label .icon-btn{width:24px;height:24px;}

.sidebar-scroll{
  flex:1;min-height:0;overflow-x:hidden;padding-bottom:8px;
  overscroll-behavior-y:contain;scrollbar-gutter:stable;
}
.sidebar-scroll > .section-label{margin-top:22px;}
.sidebar-scroll::-webkit-scrollbar{width:6px;}
.sidebar-scroll::-webkit-scrollbar-thumb{border-radius:999px;}

/* The reserved 6px scrollbar gutter already supplies most of the right inset. */
.recents{padding:0 2px 0 8px;display:flex;flex-direction:column;gap:1px;}

/* 一行 = 标题按钮 + 右边那个三个点。
   拆成两个按钮是因为 <button> 里不能再套 <button>（HTML 不合法，
   点击事件也会打架）。所以外面套一层 div 承载底色，两个按钮平铺在里面。 */
.recent-row{
  position:relative;display:flex;align-items:center;
  border-radius:var(--radius-md);
  transition:background .15s;
}

/* 每行最左边那个小圆点。

   它是 .recent-row 的 ::before，也就是**一个 flex 项**，不是绝对定位的装饰 ——
   这样标题会被它自然地往右推，两者永远不会叠在一起；行高变了、字号变了，
   align-items:center 也会让它自己跟着居中，不用维护一个 top 值。

   平时是空心的（1px 描边、无填充、压低透明度），只起"这是一列条目"的
   视觉节奏作用，不该跟标题抢注意力。真正要说话的是下面那个 data-live：
   这条对话还在生成时它变成实心的主题色并开始呼吸。

   为什么把"正在生成"从标题**后面**挪到**前面**：跟在标题后面时，长标题会被
   省略号截断，那个点要么被一起截掉、要么把可用宽度又挤掉一截 ——
   最需要被看见的状态，反而挂在最容易消失的位置上。左边这一列宽度是固定的，
   跟标题多长完全无关。 */
.recent-row::before{
  content:'';
  flex:none;
  width:6px;height:6px;
  /* 13 / 12 这两个数是从截图里量出来的，不是估的：参考图是 1.5x 的，
     环的外径 9px（=6px）、环左边缘距行底色左边缘 20px（=13.3px）、
     文字左边缘距行底色左边缘 59px（=39.3px）。
     于是 margin-left=13（点心落在距行左边缘 16px），
     margin-right=12（12 + .recent-item 自己的 8px 左内边距 = 20，
     点右边缘 19 + 20 = 39，对上文字那一列）。
     换算方式是"以环的直径为尺"量的比例，跟截图裁切位置无关。 */
  margin-left:13px;margin-right:12px;
  border-radius:50%;
  border:1px solid var(--text-faint);
  background:transparent;
  opacity:.5;
  transition:opacity .15s,background .15s,border-color .15s;
}
.recent-row:hover::before{opacity:.85;}
.recent-row[aria-current="true"]::before{opacity:1;border-color:var(--text-muted);}

.recent-row:hover{background:var(--bg-nav-hover);}
.recent-row[aria-current="true"]{background:var(--bg-nav-active);}
/* 选中那条只换字色，字重跟其余行保持一致（理由见 --recent-fg-active）。 */
.recent-row[aria-current="true"] .recent-item{color:var(--recent-fg-active);}

/* 单行。原来每条底下还挂一行"3 小时前 · 12 条"，两行一条时列表里塞不下
   几个对话，而那行小字几乎没人看 —— 真正要认的是标题。去掉之后同样高度
   能多列出一倍的对话，扫起来也干净。时间和条数移到 title 属性里，
   悬停还能看到。 */
.recent-item{
  display:block;flex:1;min-width:0;
  /* 上下 5、左右 8。左右那个 8 是标题左边缘位置的一部分（行内边距 8 +
     圆点那 31px + 这里的 8 = 47px），动它整列文字会横向挪位，跟量出来的
     设计稿就对不上。
     底纹（.recent-row 那块圆角底色）没有自己的高度，是被这里的内容撑出来的，
     所以条目高度和底纹高度永远一起变。 */
  padding:5px 8px;
  border-radius:var(--radius-md);
  color:var(--text);
  font-family:var(--font-sans-recents);
  /* 字号 14 + 行盒**固定** 21px，跟 claude.ai 一致（他们 devtools 里那个
     标题 span 就是 126 × 21，字号写着 14px anthropic-sans）。
     加上上下各 5px 内边距 = 整条 31px。

     行高写成绝对值而不是倍数，是为了让**字号和条目高度解耦**：以后想调字号
     随便调，31px 这个高度钉在原地，不用重新配内边距。
     顺带这对中英混排也是必要的 —— 中文字体的 ascent/descent 普遍比拉丁字体
     高出一截，交给字体自己撑的话，一行里冒出一个汉字就会把行盒顶高。 */
  font-size:14px;
  line-height:21px;
  /* 400。这个数来回调过 450 → 400 → 350 → 400 → 500 → 450 → 420 → 400，
     结论是**在这一栈上它基本调不动中文**，别再在这儿使劲：

     汉字落到系统的微软雅黑，而雅黑只有 Regular(400) 和 Bold(700) 两档，
     中间是空的。按 CSS 的字重匹配规则，350/400/450/500 全都落回同一个
     Regular；跨到 600 才跳 Bold，那是"变粗体"不是"稍微粗一点"。
     所以调这个数只有英文在变，中文一个像素不动。

     线上也没在这儿使劲：它就用 Regular 一档，看着"实"靠的是字号和字色。
     要调这一列的视觉重量，动 font-size 和 color。

     另外两条走不通的路，记下来省得再试：
       · -webkit-text-stroke 描一圈同色细边 —— Windows 的次像素抗锯齿下
         描边和字形错开半个像素，糊成重影（真要用得配 paint-order:stroke fill）；
       · 换一份可变字重的中文字体（项目里那份思源黑体子集就是）——
         字重确实连续可调了，代价是字形从雅黑变成思源黑体。 */
  font-weight:400;
  text-align:left;
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
}

/* 三个点。平时不占位也看不见，鼠标进这一行才出现。
   用 opacity 而不是 display:none —— 后者会让这一行在鼠标进出时
   宽度跳一下（标题的可用宽度变了，长标题的省略号会闪）。
   position:absolute 把它从流里拿出来，标题的宽度从头到尾不变。 */
.recent-more{
  position:absolute;right:4px;top:50%;transform:translateY(-50%);
  display:grid;place-items:center;
  width:24px;height:24px;border-radius:6px;
  color:var(--text-muted);
  opacity:0;pointer-events:none;
  transition:opacity .12s,background .12s,color .12s;
}
.recent-row:hover .recent-more,
.recent-more:focus-visible,
.recent-more[aria-expanded="true"]{opacity:1;pointer-events:auto;}
.recent-more:hover,
.recent-more[aria-expanded="true"]{background:var(--bg-more-hover);color:var(--text-strong);}
/* 三个点出现时给标题让出位置，免得长标题从它底下穿过去 */
.recent-row:hover .recent-item,
.recent-row:has(.recent-more[aria-expanded="true"]) .recent-item{padding-right:30px;}
/* 这个会话被切走了但还在生成 —— 左边那个点填实成主题色并开始呼吸。
   （以前是在标题**后面**另起一个点，理由见上面 .recent-row::before 的注释。） */
.recent-row[data-live="true"]::before{
  background:var(--dot-live);
  border-color:var(--dot-live);
  opacity:1;
  animation:recent-live 1.4s ease-in-out infinite;
}
/* 下限 .3 而不是 .25：灰点跟行底色的对比本来就比橙点小，压到 .25 那一下
   等于整个消失，看着像"点没了"而不是"在闪"。 */
@keyframes recent-live{0%,100%{opacity:.3;}50%{opacity:1;}}

.empty-hint{padding:4px 16px 8px;font-size:12.5px;color:var(--text-faint);}

/* A plain text entry after the last conversation, inside the sidebar scroller. */
.recents-foot{
  display:none;flex:none;padding:8px 2px 6px 8px;background:var(--bg-sidebar);
}
.recents-foot[data-on="true"]{display:block;}
.view-all{
  display:block;width:100%;padding:5px 8px;border-radius:var(--radius-md);cursor:pointer;text-decoration:none;
  color:var(--text-muted);font-size:14px;font-weight:400;line-height:21px;
  font-family:var(--font-sans-recents);
  text-align:left;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  transition:color .15s;
}
.view-all:hover{background:var(--bg-nav-hover);color:var(--text);}

/* 侧栏底部用户区 */
.sidebar-foot{
  flex:none;
  position:relative;
  display:flex;align-items:center;gap:0;
  height:48px;padding:7px 8px 8px 12px;
  border-top:1px solid var(--border);
}
.avatar{
  display:grid;place-items:center;
  width:34px;height:34px;flex:none;
  border-radius:50%;
  background:var(--bg-avatar);
  color:var(--fg-avatar);
  font-size:14px;font-weight:600;
  text-transform:uppercase;
}
.user-trigger{display:flex;align-items:center;gap:10px;flex:0 1 auto;min-width:0;max-width:calc(100% - 68px);height:32px;padding:0 8px 0 4px;margin-left:-4px;margin-right:auto;border-radius:10px;text-align:left;transition:background .15s;}
.user-trigger:hover,.user-trigger[aria-expanded="true"]{background:#f0efec;}
[data-theme="dark"] .user-trigger:hover,[data-theme="dark"] .user-trigger[aria-expanded="true"]{background:#232323;}
.sidebar-foot .avatar{width:24px;height:24px;font-size:10px;font-weight:400;background:#e3e3e2;color:#222;}
[data-theme="light"] .user-trigger:hover .avatar,
[data-theme="light"] .user-trigger[aria-expanded="true"] .avatar{background:#d9d8d5;}
[data-theme="dark"] .sidebar-foot .avatar{background:#292929;color:#e5e5e2;}
[data-theme="dark"] .user-trigger:hover .avatar,
[data-theme="dark"] .user-trigger[aria-expanded="true"] .avatar{background:#393939;}
.sidebar-foot > .icon-btn{position:relative;width:32px;height:32px;flex:none;border-radius:8px;color:var(--text);}
.sidebar-foot > .icon-btn svg{width:16px;height:16px;}
.account-chevron{flex:none;margin-left:8px;color:#898984;}

.user-meta{display:flex;align-items:baseline;gap:4px;min-width:0;line-height:20px;}
.user-name{
  display:block;min-width:0;
  font-size:14px;font-weight:400;color:var(--text);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.user-plan{display:block;flex:none;font-size:13px;font-weight:400;color:#898984;white-space:nowrap;}

.sidebar-tooltip{
  position:absolute;bottom:calc(100% + 4px);left:50%;transform:translateX(-50%);z-index:90;
  display:flex;align-items:center;gap:8px;white-space:nowrap;pointer-events:none;
  padding:3px 8px;border:1px solid transparent;border-radius:6px;
  background:#0b0b0b;color:#f5f5f5;box-shadow:0 2px 6px #00000020;
  font-size:13px;font-weight:400;line-height:16px;visibility:hidden;opacity:0;
  transition:visibility 0s,opacity 0s;
}
.sidebar-tooltip .shortcut{color:#92928a;font-size:12px;}
.sidebar-tool:hover .sidebar-tooltip{visibility:visible;opacity:1;transition-delay:500ms;}
.sidebar-tool:focus-visible .sidebar-tooltip{visibility:visible;opacity:1;transition-delay:0s;}
[data-theme="dark"] .sidebar-tooltip{background:#20201f;border-color:#3b3b38;}

/* ---------- 会话总览 ---------- */
.main[data-mode="chats"] .chat-title,
.main[data-mode="chats"] .share-btn,
.main[data-mode="chats"] .beta-pill,
.main[data-mode="chats"] #stage{display:none;}
.main[data-mode="chats"] .topbar{position:absolute;inset:0 0 auto;z-index:2;pointer-events:none;}
.main[data-mode="chats"] .topbar button{pointer-events:auto;}
.chats-page{flex:1;min-height:0;overflow-y:auto;overflow-x:hidden;}
.chats-page[hidden],.chats-page [hidden]{display:none !important;}
.chats-content{width:calc(100% - 80px);max-width:960px;margin:0 auto;padding:56px 0 32px;container-type:inline-size;}
.chats-header{display:flex;align-items:center;justify-content:space-between;gap:20px;margin-bottom:32px;}
.chats-header h1{font:400 26px/1.2 var(--font-serif);letter-spacing:-.5px;margin:0;color:var(--text-strong);white-space:nowrap;flex:none;}
.chats-header h1:focus{outline:none;}
.chats-actions{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex:none;min-width:0;margin-left:auto;}
.chats-actions[data-search="true"]{flex:1;max-width:610px;}
.chats-actions .icon-btn{width:30px;height:32px;color:var(--text-strong);}
.chats-actions .icon-btn svg{width:20px;height:20px;}
.chats-btn{padding:6px 12px;min-height:32px;border:1px solid var(--border);border-radius:8px;font-size:14px;line-height:18px;background:var(--bg-main);color:var(--text-strong);box-shadow:0 1px 3px #0000000d;}
.chats-btn:hover{background:var(--bg-hover);}
[data-theme="dark"] .chats-btn{background:#2b2b2b;border-color:transparent;}
.chats-btn.chats-new{background:var(--text-strong);color:var(--bg-main);border-color:transparent;}
.chats-btn.chats-new:hover{opacity:.85;}
.chats-row{position:relative;display:flex;align-items:center;min-height:54px;border-radius:8px;}
.chats-row::after{content:"";position:absolute;bottom:0;left:0;right:0;height:1px;background:var(--text-strong);opacity:.055;pointer-events:none;}
.chats-row:hover,.chats-row:focus-within,.chats-row[data-menu-open="true"]{background:var(--bg-hover);box-shadow:12px 0 var(--bg-hover),-12px 0 var(--bg-hover);}
.chats-row:hover::after,.chats-row:focus-within::after{opacity:0;}
.chats-open{display:flex;align-items:center;justify-content:space-between;gap:20px;width:100%;min-width:0;min-height:54px;text-align:left;font:400 14px/1.5 var(--font-sans);}
.chats-row-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-strong);}
.chats-time{color:var(--text-muted);flex:none;white-space:nowrap;font-size:13px;}
.chats-more svg{width:18px;height:18px;}
.chats-more{position:absolute;right:0;top:50%;transform:translateY(-50%);opacity:0;pointer-events:none;}
.chats-row:hover .chats-more,.chats-row:focus-within .chats-more,.chats-row[data-menu-open="true"] .chats-more{opacity:1;pointer-events:auto;}
.chats-more[aria-expanded="true"]{background:var(--bg-hover);}
.chats-row:hover .chats-time,.chats-row:focus-within .chats-time,.chats-row[data-menu-open="true"] .chats-time{visibility:hidden;}
.chats-row:hover .chats-row-title,.chats-row:focus-within .chats-row-title{padding-right:34px;}
.chats-search{display:flex;align-items:center;gap:6px;flex:1;min-width:0;height:34px;border:1px solid var(--border-strong);border-radius:9px;padding:0 8px;background:var(--bg-main);color:var(--text-muted);}
.chats-search:focus-within{border-color:#2383ed;box-shadow:0 0 0 1px #2383ed26,0 2px 7px #2383ed22;}
[data-theme="dark"] .chats-search{background:#202020;}
.chats-actions .chats-search .icon-btn{width:22px;height:26px;flex:none;}
.chats-actions .chats-search svg{width:16px;height:16px;}
.chats-actions #chatsSortDirection{color:var(--text-muted);}
.chats-search input{width:100%;min-width:0;padding:0;border:0;outline:0;background:transparent;color:var(--text-strong);font:14px var(--font-sans);}
.chats-search input::-webkit-search-cancel-button{display:none;}
.chats-search input::placeholder{color:var(--text-muted);}
.chats-filters{display:flex;align-items:center;gap:12px;margin-bottom:16px;font-size:13px;color:var(--text-muted);}
.chats-selection{display:flex;align-items:center;gap:10px;margin-left:auto;font-size:13px;color:var(--text-muted);white-space:nowrap;}
.chats-selection .icon-btn{width:28px;height:32px;margin-left:2px;color:var(--text-strong);}
.chats-filters select{padding:6px 10px;border:1px solid var(--border);border-radius:8px;background:var(--bg-main);color:var(--text-strong);font:inherit;}
.chats-selection .chats-delete{background:#d53638;color:#fff;border-color:transparent;box-shadow:none;}
.chats-selection .chats-delete:hover{background:#be2e31;}
.chats-btn:disabled{opacity:.45;cursor:default;}
.chats-check{appearance:none;position:relative;margin:0 18px 0 6px;flex:none;width:16px;height:16px;border:1px solid var(--border-strong);border-radius:4px;background:transparent;cursor:pointer;}
.chats-check:checked{background:#2c80df;border-color:#2c80df;}
.chats-check:checked::after{content:"";position:absolute;left:4px;top:1px;width:5px;height:9px;border:solid #fff;border-width:0 1.6px 1.6px 0;transform:rotate(45deg);}
.chats-check:disabled{cursor:default;opacity:.5;}
.chats-page[data-selecting="true"] .chats-row{background:transparent;box-shadow:none;}
.chats-page[data-selecting="true"] .chats-row::after{opacity:.055;}
.chats-page[data-selecting="true"] .chats-time{visibility:visible;}
.chats-page[data-selecting="true"] .chats-row-title{padding-right:0;}
.chats-empty{display:block;width:100%;text-align:center;padding:40px 16px;color:var(--text-muted);font-size:14px;}
.chats-page button:focus-visible,.chats-page select:focus-visible,.chats-page input[type="checkbox"]:focus-visible{outline:2px solid var(--text-muted);outline-offset:3px;}
@media(hover:none){
  .chats-more{position:static;transform:none;opacity:1;pointer-events:auto;flex:none;margin-left:10px;}
  .chats-time{font-size:12px;}
  .chats-row:hover .chats-time,.chats-row:focus-within .chats-time{visibility:visible;}
}
@media(max-width:700px){
  .chats-content{width:calc(100% - 40px);padding-top:64px;}
  .chats-header{gap:16px;flex-wrap:wrap;margin-bottom:24px;}
  .chats-header h1{font-size:24px;}
  .chats-actions{gap:8px;margin-left:auto;}
  .chats-open{font-size:14px;gap:12px;}
  .chats-time{font-size:12px;}
}
@container(max-width:640px){
  .chats-header{flex-wrap:wrap;gap:16px;}
  .chats-actions[data-search="true"]{flex-basis:100%;max-width:none;flex-wrap:wrap;}
  .chats-search{flex-basis:100%;}
}

/* ---------- 主区 ---------- */
.main{
  flex:1;min-width:0;
  display:flex;flex-direction:column;
  background:var(--bg-main);
  position:relative;
}
.topbar{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  /* 上、左都收了一点，标题因此更贴左上角。右侧内边距不动，
     Share / Beta 与窗口右缘的距离保持原样。 */
  padding:9px 16px 9px 10px;
  min-height:48px;
}
.topbar-left{display:flex;align-items:center;gap:4px;min-width:0;}
.topbar-right{display:flex;align-items:center;gap:6px;flex:none;}
.main[data-mode="chat"] .topbar-right{margin-right:-4px;}
.rail-btn{display:none;}
.app[data-sidebar="closed"] .rail-btn{display:grid;}

.chat-title{
  display:flex;align-items:center;gap:5px;
  padding:4px 6px;border-radius:var(--radius-md);
  color:var(--text-strong);font-size:13.5px;font-weight:450;
  max-width:46vw;transition:background .15s;
}
.chat-title:hover{background:var(--bg-hover);}
.chat-title span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* Compact topbar actions, with equal height and a crisp document outline. */
.share-btn{
  padding:4.5px 10px;border-radius:7px;
  border:1px solid var(--border-strong);
  color:var(--text-strong);font-size:13.5px;font-weight:500;line-height:19px;
  box-shadow:0 1px 3px rgb(0 0 0 / .08);
  transition:background .15s;
}
.share-btn:hover{background:var(--bg-hover);}
.topbar .share-btn{padding:3.5px 8px;}
[data-theme="dark"] .share-btn{background:var(--bg-hover);box-shadow:none;}
.conversation-files-btn{position:relative;width:30px;height:30px;border-radius:7px;color:#161616;}
.conversation-files-btn > svg{width:18px;height:18px;}
[data-theme="dark"] .conversation-files-btn{color:var(--text-strong);}
.main:not([data-mode="chat"]) .conversation-files-btn{display:none;}
.conversation-files-btn[aria-expanded="true"]{background:#D2E5FF;color:#155DA9;}
[data-theme="dark"] .conversation-files-btn[aria-expanded="true"]{background:#062644;color:#70AFF7;}
.conversation-files-tooltip{
  position:absolute;top:calc(100% + 8px);left:50%;z-index:30;
  padding:5px 9px;border-radius:7px;background:#111;color:#fff;
  font-size:14px;font-weight:400;line-height:1.4;white-space:nowrap;
  box-shadow:0 2px 7px rgb(0 0 0 / .15);pointer-events:none;
  opacity:0;transform:translate(-50%,-3px);transition:opacity .15s,transform .15s;
}
.conversation-files-btn:hover .conversation-files-tooltip,
.conversation-files-btn:focus-visible .conversation-files-tooltip{opacity:1;transform:translate(-50%,0);}
.conversation-files-btn:focus-visible,.share-btn:focus-visible{outline:2px solid #70AAEA;outline-offset:2px;}
.conversation-files{
  flex:0 0 clamp(300px,30vw,460px);min-width:0;
  margin:56px 8px 8px 0;padding:22px;border:1px solid var(--border);
  border-radius:20px;background:var(--bg-main);overflow-y:auto;
  scrollbar-width:thin;scrollbar-color:var(--scroll-thumb) transparent;
  animation:attachment-preview-enter .2s cubic-bezier(.22,1,.36,1) both;
}
.conversation-files::-webkit-scrollbar{width:6px;}
.conversation-files::-webkit-scrollbar-track{background:transparent;margin-block:16px;}
.conversation-files::-webkit-scrollbar-thumb{background:var(--scroll-thumb);border-radius:999px;}
.conversation-files::-webkit-scrollbar-thumb:hover{background:var(--text-faint);}
.conversation-files::-webkit-scrollbar-button{display:none;width:0;height:0;}
.conversation-files::-webkit-scrollbar-corner{background:transparent;}
/* Use the custom scrollbar in Chromium/WebKit, including removal of native arrows. */
@supports selector(::-webkit-scrollbar){
  .conversation-files{scrollbar-width:auto;scrollbar-color:auto;}
}
.conversation-files-header{display:flex;align-items:center;gap:4px;margin-bottom:18px;}
.conversation-files-header h2{flex:1;margin:0;font-size:17px;font-weight:550;color:var(--text-strong);}
.conversation-files-download-all{
  display:inline-flex;align-items:center;gap:6px;flex:none;
  padding:6px 8px;margin-right:-8px;border-radius:8px;
  color:var(--text-strong);font-size:14px;line-height:20px;
  transition:background .15s;
}
.conversation-files-download-all:hover{background:var(--bg-hover);}
.conversation-files-download-all:focus-visible{outline:2px solid #70AAEA;outline-offset:2px;}
.conversation-files-download-all:disabled{opacity:.5;cursor:wait;}
.conversation-files-list{display:flex;flex-direction:column;gap:12px;}
.conversation-files .filecard{max-width:none;height:84px;margin:0;padding:0 15px 0 20px;gap:18px;border-radius:14px;}
.conversation-files .fc-icon{width:64px;height:64px;margin-top:19px;}
.conversation-files .fc-sheet,.conversation-files .fc-icon::before{height:84px;border-radius:9px;}
.conversation-files .fc-sheet{padding-top:22px;}
.conversation-files .fc-name{font-size:16px;}
.conversation-files .fc-sub{font-size:14px;}
.conversation-files .fc-btn{display:grid;place-items:center;width:32px;padding:0;border:0;background:transparent;box-shadow:none;}
.conversation-files .fc-btn:hover{background:var(--bg-hover);}
.conversation-files .fc-btn:disabled{opacity:.45;cursor:wait;}
.conversation-files-status{font-size:14px;line-height:1.6;color:var(--text-muted);margin:16px 0 0;overflow-wrap:anywhere;}
.conversation-files-status:empty{display:none;}
.conversation-files-retry{margin-top:12px;}
@media(max-width:1100px){.conversation-files{flex-basis:320px;padding:18px;}.conversation-files .filecard{gap:12px;padding-left:14px;}}
@media(max-width:767px){
  .conversation-files{position:fixed;inset:56px 8px 8px;z-index:35;margin:0;padding:20px;box-shadow:0 8px 32px rgb(0 0 0 / .12);}
}
@media(prefers-reduced-motion:reduce){.conversation-files{animation:none;}.conversation-files-tooltip{transition:none;}}

/* 右上角的 Beta 标签。判据是 .main[data-mode="empty"] —— 也就是"这一页还没有
   任何消息、显示的是问候语 + 输入框"，那就是新对话页。

   一开始用的是"当前会话 == New 出来的那个 id"，判据太窄：从 localStorage
   恢复出来的空会话（以及这次改动之前就已经攒在 Recents 里的那些空对话）
   都不算数，于是明明看着是新对话页，右上角却还是 Share。空态本身就是
   最准的判据 —— 用户看到问候语的那一刻，这就是新对话页。 */
.beta-pill{
  display:none;align-items:center;
  padding:4.5px 11px;border-radius:8px;
  background:var(--bg-beta);color:var(--fg-beta);
  font-size:13px;font-weight:500;line-height:1.35;
  letter-spacing:.005em;user-select:none;
}
.main[data-mode="empty"] .beta-pill{display:inline-flex;}
.main[data-mode="empty"] .share-btn{display:none;}
/* 新对话页不显示左上角那个标题：还没聊出内容，"新对话 ⌄" 只是一句废话，
   占着位置还把视线往左上角拽。有了第一条消息（data-mode 变成 chat）它自然回来。 */
.main[data-mode="empty"] .chat-title{display:none;}

/* 舞台：空态居中，有对话时上下分区。
   **滚动条在这一层**，不在 .feed 上。以前 .feed 是滚动容器，滚动条就只
   占 feed 那一段高度 —— 到输入框上沿就断了，看着像半截。现在整块（消息 +
   输入框）一起滚，输入框用 sticky 钉在底部，滚动条自然贯穿整个主区。 */
.body-col{
  flex:1;min-height:0;display:flex;flex-direction:column;
  overflow-y:auto;
  scrollbar-gutter:stable;
  /* 内容变短时（切会话、压缩）别让浏览器自作主张地"保持滚动位置"，
     那会和下面 JS 里的贴底逻辑打架 */
  overflow-anchor:none;
}

.greet-wrap{display:none;}
.main[data-mode="empty"] .greet-wrap{
  display:flex;flex:1;min-height:0;
  align-items:flex-end;justify-content:center;
  padding:0 24px 30px;
}
.greeting{
  display:flex;align-items:center;gap:8px;
  flex-wrap:wrap;justify-content:center;
  font-family:var(--font-anthropic-serif);
  font-size:42px;font-weight:300;letter-spacing:-.015em;
  font-variation-settings:"opsz" 48,"wght" 300;
  color:var(--text-greeting);margin:0;text-align:center;
}
/* 问候区整体（logo + 文字）相对问题框居中，不再用右侧占位把文字单独对齐 */
.spark{color:var(--accent);flex:none;}
.greeting-logo{display:block;object-fit:contain;}

/* 内容列是 margin:0 auto 居中的，所以左右 padding 必须相等，它才真的在正中。
   之前左边给 72px、右边 24px，是想"视觉上往右挪一点"，代价是整列中轴右偏
   24px —— 空态没有 .feed 看不出来，一下沉就和居中的问候语对不上了。
   现在两边都是 24px：消息列和输入框互相对齐，同时各自居中，
   而且输入框下沉前后中轴不动，没有横向跳动。 */
/* flex:1 0 auto —— 内容少时撑满（把 sticky 的输入框顶到底部），
   内容多时按自身高度往下长，交给 .body-col 去滚。 */
.feed{flex:1 0 auto;padding:8px 24px 10px;}
/* 一个会话一块。切换只是显示/隐藏，不重画 —— 见 app.js 里 paneFor 的注释。
   pane 本身不参与布局（没有 margin/padding），.turn 的样式一个字都不用改。 */
.pane{display:block;}
.pane[hidden]{display:none;}
/* Shared first-paint and per-conversation placeholders. */
.skeleton-bar{display:block;height:13px;border-radius:6px;background:var(--bg-active);animation:skeleton-pulse 1.8s ease-in-out infinite;}
.list-skeleton{display:flex;flex-direction:column;gap:20px;padding:12px 10px;}
.list-skeleton .skeleton-bar{width:82%;}
.list-skeleton .skeleton-bar:nth-child(3n+2){width:64%;}
.list-skeleton .skeleton-bar:nth-child(3n){width:91%;}
.history-skeleton{width:100%;max-width:780px;margin:0 auto;padding:28px 0;}
.skeleton-question{width:38%;height:48px;margin:0 0 34px auto;border-radius:18px;}
.skeleton-answer{display:flex;flex-direction:column;gap:14px;margin-bottom:42px;}
.skeleton-answer .skeleton-mark{width:26px;height:26px;border-radius:50%;margin-bottom:8px;}
.skeleton-answer .skeleton-bar:nth-child(3){width:94%;}
.skeleton-answer .skeleton-bar:last-child{width:62%;}
.chats-list .list-skeleton{gap:0;padding:0;}
.chats-list .list-skeleton .skeleton-bar{height:16px;margin:28px 0;max-width:520px;}
.main[data-booting="true"] .topbar :is(.chat-title,.topbar-right),
.main[data-booting="true"] .composer-dock{visibility:hidden;}
@keyframes skeleton-pulse{0%,100%{opacity:.5}50%{opacity:1}}
@media(prefers-reduced-motion:reduce){.skeleton-bar{animation:none;}}
@media(max-width:767px){.history-skeleton{padding-top:20px;}.skeleton-question{width:56%;}}
.main[data-mode="empty"] .feed{display:none;}
.dock-tail{display:none;}
.main[data-mode="empty"] .dock-tail{display:block;flex:1.2;min-height:0;}

/* 历史对话的输入框、说明和模型选择整体贴近底部。 */
.composer-dock{
  padding:0 36px 2px;display:flex;flex:none;justify-content:center;
  /* 钉在滚动容器底部。它仍然在滚动流里，所以滚动条是整条的；
     但视觉上永远贴着底边。 */
  position:sticky;bottom:0;z-index:5;
  background:var(--bg-main);
}
/* 内容滚到输入框底下时给一小段渐隐，别让文字齐刷刷地被切断 */
.composer-dock::before{
  content:"";position:absolute;left:0;right:0;bottom:100%;height:28px;
  background:linear-gradient(to top, var(--bg-main), transparent);
  pointer-events:none;
}

/* ---------- 回到底部 ---------- */
.jump-btn{
  position:absolute;left:50%;bottom:100%;
  transform:translateX(-50%);
  /* 和输入框隔开一段。这个数要大于上面那条渐隐的 28px，
     否则按钮会泡在渐变里，边缘看不清。 */
  margin-bottom:14px;
  width:34px;height:34px;border-radius:50%;
  display:grid;place-items:center;
  color:var(--text-strong);
  background:var(--bg-pop);
  border:1px solid var(--border);
  box-shadow:var(--shadow-pop);
  z-index:6;
  transition:background .12s, transform .12s;
}
.jump-btn:hover{background:var(--bg-hover);transform:translateX(-50%) translateY(-1px);}
.jump-btn[hidden]{display:none;}

/* 送出新问题时垫在最后的空白：让"这条问题滚到最上面"真的滚得动。
   高度由 JS 按剩余内容算，回答长到够了它自己就变成 0。 */
.scroll-pad{flex:none;}
/* 首页仍保留居中的大输入框，与历史对话的贴底布局分开。 */
.main[data-mode="empty"] .composer-dock{padding-bottom:14px;}
.main[data-mode="empty"] .composer-dock{padding-left:36px;padding-right:36px;}
.main[data-mode="empty"] .greeting,
.main[data-mode="empty"] .composer-dock{transform:translateY(-12px);}
.thread{width:100%;max-width:780px;margin:0 auto;}

/* 502 fallback notice. It sits above the composer so the recovery action stays
   available after the response has finished, matching the model status shown in
   the conversation UI. */
.model-fallback{
  width:100%;margin:0 0 8px;padding:8px 12px;
  display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px 12px;
  border:1px solid var(--border);border-radius:14px;
  background:var(--composer-bg);color:var(--text-strong);
  font-family:var(--font-latin),var(--font-sans);font-size:15px;
  box-sizing:border-box;
}
.model-fallback[hidden]{display:none;}
.fallback-top{display:flex;align-items:center;min-width:0;}
.fallback-toggle{
  display:inline-flex;align-items:center;gap:7px;min-width:0;
  padding:3px 0;border:0;background:none;color:inherit;
  font:inherit;cursor:pointer;text-align:left;
}
.fallback-toggle .fallback-chevron{display:inline-flex;transition:transform .15s ease;}
.model-fallback[data-open="true"] .fallback-toggle .fallback-chevron{transform:rotate(90deg);}
.fallback-actions{display:flex;align-items:center;gap:7px;}
.fallback-action{
  min-height:31px;padding:4px 10px;border:1px solid var(--border);
  border-radius:8px;background:var(--composer-bg);color:var(--text-strong);
  font:inherit;font-size:14px;line-height:1.2;white-space:nowrap;
  box-shadow:0 1px 2px rgb(0 0 0 / .06);cursor:pointer;
}
.fallback-action:hover{background:var(--bg-hover);}
.fallback-action:active{transform:translateY(1px);}
.fallback-action:disabled{opacity:.6;cursor:wait;}
.fallback-body{
  grid-column:1 / -1;margin:1px 0 1px;
  color:var(--text-muted);font-size:14px;line-height:1.45;overflow-wrap:anywhere;
}
.fallback-body[hidden]{display:none;}
.fallback-body code{font-family:var(--font-mono);font-size:.92em;}
[data-theme="dark"] .model-fallback{background:#191918;border-color:#343433;}
[data-theme="dark"] .fallback-action{background:#30302f;border-color:#30302f;color:#f5f4ee;box-shadow:none;}
[data-theme="dark"] .fallback-action:hover{background:#3a3a39;}
@media(max-width:600px){
  .model-fallback{grid-template-columns:1fr;gap:6px;padding:8px 10px;}
  .fallback-actions{justify-content:flex-end;}
  .fallback-action{font-size:13px;}
}

/* 输入框 */
.composer{
  width:100%;max-width:780px;
  /* 外面还有一层 .thread（780px、margin:0 auto）。.thread 自己在右侧区域里
     是居中的，但 .composer 只是它里面的块级元素——一旦 max-width 比 .thread
     小（空态的 660px），没有 auto 外边距它就会贴左边，看起来整体左偏。 */
  margin-inline:auto;
  /* 上边框之前是"白的"：环是 box-shadow，画在 border-box **外面**，而
     .composer-dock 的 padding-top 是 0——那 1px 正好落在 dock 顶边之上，
     被 .composer-dock::before（渐隐层，底部是不透明的 --bg-main）盖掉了。
     ::before 是绝对定位、composer 是普通流内元素，所以前者天然压在后者上面。
     给 composer 一个定位上下文抬到 ::before 之上就行，布局一个像素都不动。
     （.jump-btn 是 z-index:6，仍然在它上面，不受影响。） */
  position:relative;z-index:1;
  background:var(--composer-bg);
  border:0;
  /* 12px 偏方；16px 略圆。14px 保留柔和感，但轮廓更利落。 */
  border-radius:14px;
  box-shadow:var(--composer-edge-shadow);
  padding:8px 12px;
  transition:box-shadow .2s;
}
/* 2x 以上的屏才用半像素。1x 上 0.5px 会被抗锯齿摊成半透明的 1px，
   等于把本来就淡的线又淡了一半，反而"看不见边"。 */
@media (min-resolution: 2dppx){
  :root{ --cds-ring-hairline: 0.5px; }
}
/* 悬停只抬 alpha（0.15 → 0.30），宽度不动。
   :not(:has(button:hover,...)) 是官网的写法：鼠标压在框内的按钮上时外框不跟着亮，
   否则按钮的 hover 底色和外框高亮会同时闪，显得脏。 */
.composer:hover:not(:focus-within):not(:has(button:hover,a:hover,[role="button"]:hover,label:hover)){
  box-shadow:var(--composer-edge-shadow-hover);
}
.composer:focus-within{
  box-shadow:var(--composer-edge-shadow-focus);
}
/* 空态的输入框比对话态窄一点：居中大留白时 780px 显得太横，收到 640px
   更接近官网观感。只收空态，对话态仍和 .thread 内容列同宽（780px），
   否则输入框和上面的气泡对不齐。 */
.main[data-mode="empty"] .composer-dock .thread{max-width:640px;}

.composer-row{
  display:grid;grid-template-columns:max-content minmax(0,1fr) auto;
  grid-template-areas:"attach input actions";align-items:end;column-gap:10px;
}
.composer-tools{grid-area:attach;display:flex;align-items:center;gap:4px;margin-block:1px;}
.composer-tools .icon-btn{flex:none;}
.composer-tools [hidden]{display:none;}
#attach[aria-expanded="true"]{background:var(--bg-hover);}
.composer-tools .research-btn{color:#0861ad;background:#cce1ff;border-radius:8px;}
.composer-tools .research-btn:hover{color:#075395;background:#bad7ff;}
[data-theme="dark"] .composer-tools .research-btn{color:#91c4ff;background:#183d65;}
/* 输入框左侧加号：深色用纯白，浅色使用同等醒目的深色，避免白底不可见。 */
#attach{color:var(--text-strong);}
[data-theme="dark"] #attach{color:#fff;}
.composer-actions{grid-area:actions;display:flex;align-items:center;gap:6px;margin-block:1px;min-width:0;}
.composer-actions > .icon-btn{flex:none;}
.composer-input{grid-area:input;}
/* The reference menus use the same compact scale as the rest of the app chrome. */
.composer-menu{
  position:fixed;z-index:300;width:244px;max-width:calc(100vw - 16px);
  max-height:calc(100dvh - 16px);overflow-y:auto;padding:4px;
  background:var(--bg-acct);color:var(--text-strong);
  border:1px solid var(--bd-acct);border-radius:12px;
  box-shadow:0 12px 30px #0002,0 2px 5px #0001;
  font-family:var(--font-latin),var(--font-sans);font-size:14px;
  font-weight:400;font-optical-sizing:none;
}
.composer-menu[hidden]{display:none;}
[data-theme="dark"] .composer-menu{box-shadow:0 14px 30px #0006,0 2px 5px #0003;}
#composerSubmenu{width:max-content;min-width:184px;z-index:301;}
#composerSubmenu[data-kind="connectors"]{min-width:228px;}
.composer-menu-row{
  display:flex;align-items:center;gap:10px;width:100%;height:32px;
  padding:0 10px;border:0;border-radius:8px;background:transparent;color:inherit;
  font:inherit;line-height:20px;text-align:left;white-space:nowrap;cursor:pointer;
}
.composer-menu-row:hover,.composer-menu-row:focus-visible,
.composer-menu-row[aria-expanded="true"]{background:var(--bg-acct-hover);outline:none;}
.composer-menu-row:focus-visible{box-shadow:inset 0 0 0 1px var(--text-faint);}
.composer-menu-row > svg{width:18px;height:18px;flex:none;}
.composer-menu-tail{display:flex;align-items:center;margin-left:auto;flex:none;color:var(--text-muted);}
.composer-menu-arrow svg{width:14px;height:14px;}
.composer-menu-shortcut{font-size:13px;padding-left:8px;}
.composer-menu-separator{height:1px;margin:5px 9px;background:var(--border);}
.composer-menu-check{visibility:hidden;color:#287bd5;}
.composer-menu-check svg{width:17px;height:17px;}
.composer-menu-row[aria-checked="true"] .composer-menu-check{visibility:visible;}
.composer-menu-switch{width:30px;height:18px;border-radius:12px;background:var(--text-faint);position:relative;}
.composer-menu-switch::after{content:"";position:absolute;width:14px;height:14px;border-radius:50%;left:2px;top:2px;background:#fff;box-shadow:0 1px 2px #0002;}
.composer-menu-row[aria-disabled="true"]{cursor:default;}
.research-btn svg{width:18px;height:18px;}
/* 多行内容占满上方，按钮在下方；首页始终使用原来的上下两层布局。 */
.composer[data-expanded="true"] .composer-row,
.main[data-mode="empty"] .composer-row{
  grid-template-columns:max-content minmax(0,1fr);
  grid-template-areas:"input input" "attach actions";row-gap:4px;
}
.composer[data-expanded="true"] .composer-actions,
.main[data-mode="empty"] .composer-actions{justify-self:end;max-width:100%;}
.main[data-mode="empty"] .composer{padding:13px 14px 9px;}
.main[data-mode="empty"] .composer-input{height:48px;min-height:48px;}
.main[data-mode="empty"] .composer-row{row-gap:0;}
.main[data-mode="empty"] .composer-footer{display:none;}
.composer-actions .model-btn{min-width:0;}
.composer-actions .model-btn b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}

.composer-input{
  display:block;width:100%;flex:1;min-width:0;
  /* 默认一行；长文本沿用 autoGrow，最多展开到 280px。 */
  height:32px;min-height:32px;max-height:280px;
  border:0;outline:0;resize:none;
  background:transparent;color:var(--text-strong);
  font:inherit;font-size:15.5px;line-height:24px;
  padding:4px 0;overflow-y:auto;
}
.composer-input::placeholder{
  color:var(--text-faint);
  /* 官网这里是无衬线。之前用衬线族，加上 Anthropic Serif 有 opsz 16-48 的光学
     尺寸轴、下限 16，在 15.5px 上会被钳住，笔画显得挤 —— 看起来像"降级"其实
     是同一份字体在错误的设计尺寸上。改成和输入框正文同一族，敲字时不再换脸。*/
  font-family:var(--font-latin), var(--font-sans);
}

/* 输入框下面那行免责声明。字族跟 placeholder 走同一套无衬线。
   颜色写死 #73726c（不走 --text-faint）：这行在深浅两套主题里都要是这个灰，
   而 --text-faint 是跟着主题翻转的。 */
.composer-footer{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  min-height:30px;flex-wrap:nowrap;
  margin-top:6px;padding:0 12px;
}
/* 型号和强度只在各自按钮内变化，不能挤换行、抬高整个输入框。 */
.composer-footer .model-btn{
  flex:0 1 auto;min-width:0;max-width:50%;height:30px;line-height:20px;
  margin-left:auto;white-space:nowrap;
}
.composer-footer .model-btn b{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.composer-footer .model-btn > span{flex:none;}
.composer-note{
  margin:0;min-width:0;flex:1;text-align:left;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-family:var(--font-latin), var(--font-sans);
  font-size:12.5px;line-height:1.4;font-weight:400;
  color:#73726c;
}
/* 首页悬浮态不显示这行 */
.main[data-mode="empty"] .composer-note{display:none;}

.model-btn{
  display:flex;align-items:center;gap:6px;
  padding:5px 8px;border-radius:var(--radius-md);
  color:var(--text-muted);font-size:13.5px;
  transition:background .15s;
}
.model-btn:hover{background:var(--bg-hover);}
/* 13.5px 的 UI chrome 不适合衬线：可变字体的 opsz 轴下限是 16，这个尺寸下
   字形按 16pt 的设计画再缩小，又胖又挤。统一走 Sans，并关掉光学尺寸自动挡，
   避免小字号被钳到轴下限。旁边的 #modelEffort（"Medium"）没写字体，
   靠 --font-sans 已修好，两者现在是同一族。*/
/* <b> 默认 bold，这里显式压回常规字重 —— 只靠颜色和字号跟旁边的
   #modelEffort（"Medium"）拉开层级 */
.model-btn b{font-weight:400;color:var(--text-strong);font-size:14px;
  font-family:var(--font-latin), var(--font-sans);
  font-optical-sizing:none;}
.model-btn{font-optical-sizing:none;}
.model-effort-warning{display:inline-flex;align-items:center;flex:none;}
.model-effort-warning[hidden]{display:none;}
.max-effort-tooltip{
  position:fixed;z-index:400;width:220px;max-width:calc(100vw - 16px);
  padding:7px 8px;border:1px solid transparent;border-radius:6px;
  background:#0b0b0b;color:#f7f7f7;box-shadow:0 3px 8px #0002;
  font-family:var(--font-latin),var(--font-sans);font-size:13px;
  font-weight:400;line-height:18px;font-optical-sizing:none;text-align:left;
}
.max-effort-tooltip[hidden]{display:none;}
[data-theme="dark"] .max-effort-tooltip{background:#20201f;border-color:#393938;box-shadow:0 3px 8px #0003;}

.send-slot{position:relative;width:30px;height:30px;flex:none;}
.send-slot > button{position:absolute;inset:0;}
.mic-btn{color:var(--text-strong);}
[data-theme="dark"] .mic-btn{color:#fff;}
/* 空输入时发送槽不占宽度，右侧只保留一个麦克风。输入后或生成中再显示槽。 */
.composer[data-has-text="false"][data-busy="false"] .send-slot{display:none;}

.send-btn{
  display:grid;place-items:center;
  border-radius:var(--radius-md);
  background:var(--accent);color:#fff;
  opacity:0;transform:scale(.85);pointer-events:none;
  transition:opacity .18s,transform .18s var(--ease),background .15s,color .15s;
}
.send-icon-compact{display:none;}
/* 历史对话的单行紧凑框用“回车发送”图标，不再套强调色方块。
   首页大输入框仍保留原来的上箭头按钮，两个状态互不影响。 */
.main:not([data-mode="empty"]) .send-btn{
  border-radius:var(--radius-sm);
  background:transparent;color:var(--text-strong);
}
.main:not([data-mode="empty"]) .send-btn:hover,
.stop-btn:hover{background:var(--bg-hover);}
.main:not([data-mode="empty"]) .send-icon-home{display:none;}
.main:not([data-mode="empty"]) .send-icon-compact{display:block;}

/* 生成态的圆环与回车图标保持接近的视觉重量。按钮仍占满 30px 槽位，
   且圆角和 hover 底纹与紧凑态发送按钮完全一致。 */
.stop-btn{
  display:grid;place-items:center;
  border-radius:var(--radius-sm);
  background:transparent;color:var(--text-strong);
  opacity:0;transform:scale(.85);pointer-events:none;
  transition:opacity .18s,transform .18s var(--ease),background .15s;
}
.composer[data-has-text="true"] .send-btn{opacity:1;transform:none;pointer-events:auto;}
.composer[data-has-text="true"]:not([data-busy="true"]) .send-btn:disabled{opacity:.45;cursor:not-allowed;}
.composer[data-has-text="true"]:not([data-busy="true"]) .mic-btn{display:none;}
.composer[data-busy="true"] .send-btn{opacity:0;transform:scale(.85);pointer-events:none;}
.composer[data-busy="true"] .send-slot{order:-1;transform:translateX(3px);}
.composer[data-busy="true"] .stop-btn{opacity:1;transform:none;pointer-events:auto;}

/* 上传区单行滚动；已发送的附件独立放在文字气泡上方。 */
.atts{
  display:flex;gap:12px;flex-wrap:nowrap;min-width:0;max-width:100%;
  overflow-x:auto;padding:8px 8px 10px 0;margin-top:-8px;margin-bottom:10px;
  scrollbar-width:thin;scrollbar-color:var(--text-faint) transparent;
}
.atts[hidden]{display:none;}
.att{
  position:relative;display:flex;flex-direction:column;align-items:flex-start;
  flex:0 0 120px;width:120px;height:120px;padding:11px;
  border-radius:6px;border:1px solid var(--border-strong);
  background:var(--bg-main);box-shadow:0 1px 2px rgb(0 0 0 / .06);
  font-size:12px;line-height:1.35;color:var(--text-strong);
  transition:background-color .15s ease;
}
[data-theme="dark"] .att:hover{background:#1A1A19;}
.att-name{
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;
  width:100%;overflow:hidden;overflow-wrap:anywhere;word-break:break-all;font-weight:400;
}
.att-type{
  max-width:100%;margin-top:auto;padding:2px 6px;border-radius:5px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  background:var(--bg-hover);color:var(--text);font-size:11px;font-weight:500;
}
.att-remove{
  position:absolute;z-index:1;top:-7px;right:-7px;display:grid;place-items:center;
  width:21px;height:21px;padding:0;border:1px solid var(--border-strong);
  border-radius:50%;background:var(--bg-main);color:var(--text);
  font-size:17px;line-height:1;cursor:pointer;opacity:0;
  transition:opacity .15s;
}
.att:hover .att-remove,.att:focus-within .att-remove{opacity:1;}
.att-remove:hover{color:var(--danger);}
.att-remove:focus-visible{outline:2px solid var(--text-muted);outline-offset:2px;}
.att-open{position:absolute;inset:0;width:100%;height:100%;border:0;border-radius:inherit;cursor:pointer;background:transparent;}
.att-open:hover{background:rgb(128 128 128 / .05);}
.att-open:focus-visible{outline:2px solid var(--text-muted);outline-offset:-3px;}
.att-image{padding:0;border-radius:10px;align-items:center;justify-content:center;}
.att-pdf{border-radius:9px;}
.att-pdf > .att-thumbnail{position:absolute;inset:0;}
.att-pdf-preview{padding:0;align-items:center;justify-content:center;}
.att-pdf-preview .att-type{
  position:absolute;left:9px;bottom:8px;z-index:1;margin:0;padding:1px 4px;
  border:1px solid #cecece;border-radius:4px;background:rgb(255 255 255 / .92);
  color:#555;font-size:11px;line-height:15px;font-weight:400;pointer-events:none;
  box-shadow:0 1px 4px rgb(0 0 0 / .15);
}
[data-theme="dark"] .att-pdf{background:#20201f;}
[data-theme="dark"] .att-pdf-preview .att-type{background:rgb(51 51 49 / .86);border-color:#62625e;color:#d3d3ca;}
.att-thumbnail{display:block;width:100%;height:100%;object-fit:contain;border-radius:inherit;}
.att-image .att-open{cursor:zoom-in;}
.att-image-mask{
  position:absolute;inset:0;border-radius:inherit;overflow:hidden;pointer-events:none;
  background:rgb(0 0 0 / .72);
}
.att-image-mask::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(110deg,transparent 15%,rgb(255 255 255 / .22) 50%,transparent 85%);
  will-change:transform;animation:att-image-shimmer 1.4s linear infinite;
}
@keyframes att-image-shimmer{from{transform:translate3d(-100%,0,0);}to{transform:translate3d(100%,0,0);}}
.att-image-error{padding:10px;overflow-wrap:anywhere;font-size:12px;color:var(--text-muted);}

/* Uploaded source files occupy their own column; the chat remains usable. */
.attachment-preview{
  flex:0 0 clamp(320px,calc((100% - var(--preview-sidebar-width,var(--sidebar-w)) - 16px) * var(--preview-ratio,.5)),calc(100% - var(--preview-sidebar-width,var(--sidebar-w)) - 336px));min-width:0;margin:8px 8px 8px 0;
  border:1px solid var(--border-strong);border-radius:12px;
  background:#fff;box-shadow:0 1px 5px rgb(0 0 0 / .08);overflow:hidden;
  animation:attachment-preview-enter .22s cubic-bezier(.22,1,.36,1) both;
}
.attachment-divider{flex:0 0 8px;position:relative;margin:8px 0;cursor:col-resize;touch-action:none;outline:none;}
.attachment-divider::after{content:"";position:absolute;top:50%;left:3px;width:2px;height:28px;transform:translateY(-50%);background:transparent;border-radius:1px;transition:background .12s;}
.attachment-divider:hover::after,.attachment-divider:focus-visible::after,.preview-resizing .attachment-divider::after{background:var(--border-strong);}
.attachment-divider[hidden]{display:none;}
body.preview-resizing,body.preview-resizing *{cursor:col-resize !important;user-select:none !important;}
@keyframes attachment-preview-enter{
  from{opacity:0;transform:translateX(24px);}
  to{opacity:1;transform:translateX(0);}
}
.attachment-source{height:100%;display:flex;flex-direction:column;min-height:0;padding:16px;}
.attachment-header{display:flex;align-items:center;gap:10px;min-width:0;}
.attachment-header h2{
  flex:1;min-width:0;margin:0;color:var(--text-strong);font-family:var(--font-sans);
  font-size:18px;line-height:1.4;font-weight:550;overflow-wrap:anywhere;
}
.attachment-header .icon-btn{flex:none;width:32px;height:32px;border-radius:8px;}
.attachment-header .icon-btn:disabled{opacity:.4;cursor:default;}
.attachment-header .icon-btn:focus-visible,.attachment-download:focus-visible{
  outline:2px solid var(--text-muted);outline-offset:2px;
}
.attachment-meta{color:var(--text-muted);font-size:12px;line-height:1.5;margin:5px 2px 12px;}
.attachment-code{
  flex:1;min-height:0;overflow:auto;margin:0;padding:18px;
  background:#fff;border:1px solid var(--border);border-radius:9px;
  box-shadow:0 2px 5px rgb(0 0 0 / .08);color:var(--text-strong);
  font-family:var(--font-anthropic-mono),var(--font-mono);font-size:13px;line-height:1.55;
  white-space:pre-wrap;overflow-wrap:anywhere;tab-size:4;
  scrollbar-width:thin;scrollbar-color:var(--text-faint) transparent;overscroll-behavior:contain;
}
.attachment-code code{font:inherit;color:inherit;}
.attachment-overlay{
  position:fixed;inset:0;z-index:63;display:grid;place-items:center;padding:24px;
  background:rgba(20,19,18,.20);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);
}
.attachment-dialog{
  position:relative;display:flex;flex-direction:column;width:min(560px,100%);height:min(480px,calc(100dvh - 48px));
  padding:24px 28px;background:#fff;border:1px solid var(--border-strong);
  border-radius:16px;box-shadow:0 12px 32px rgb(0 0 0 / .16);overflow:auto;
}
.attachment-dialog .attachment-header{align-items:flex-start;padding-right:28px;}
.attachment-dialog .attachment-close{position:absolute;top:12px;right:12px;}
.attachment-dialog h2{font-size:20px;font-weight:600;}
.attachment-unavailable{
  flex:1;min-height:160px;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:14px;text-align:center;padding:24px 0;
}
.attachment-status{margin:0;color:var(--text);font-size:16px;line-height:1.5;overflow-wrap:anywhere;max-width:100%;}
.attachment-download{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:7px 13px;
  border:1px solid var(--border);border-radius:9px;box-shadow:0 1px 3px rgb(0 0 0 / .09);
  background:#fff;color:var(--text-strong);font-size:16px;line-height:1.4;cursor:pointer;
}
.attachment-download:hover{background:var(--bg-hover);}
.attachment-download:disabled{opacity:.5;cursor:wait;}
[data-theme="dark"] .attachment-preview{background:#1b1b1a;}
[data-theme="dark"] .attachment-code,[data-theme="dark"] .attachment-dialog{background:#212120;}
[data-theme="dark"] .attachment-overlay{background:rgba(0,0,0,.36);}
[data-theme="dark"] .attachment-download{background:#383837;}
[data-theme="dark"] .attachment-download:hover{background:#444443;}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .attachment-overlay{background:rgba(20,19,18,.48);}
  [data-theme="dark"] .attachment-overlay{background:rgba(0,0,0,.6);}
}
.attachment-overlay.image-lightbox{
  padding:48px 56px;background:rgb(0 0 0 / .76);
  backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px);
  animation:image-lightbox-enter .2s ease-out both;
}
.attachment-overlay.pdf-overlay{background:rgb(0 0 0 / .4);backdrop-filter:none;-webkit-backdrop-filter:none;padding:24px;}
.pdf-dialog{
  --pdf-arrow:#fff;position:relative;width:min(400px,calc(100vw - 48px));max-width:100%;max-height:calc(100dvh - 48px);overflow:auto;
  padding:20px 24px 26px;border:1px solid #dedede;border-radius:13px;background:#fff;
  box-shadow:0 12px 36px #00000020;animation:pdf-dialog-enter .18s ease-out;
}
.pdf-dialog h2{margin:0;padding-right:32px;font:600 22px/28px var(--font-anthropic-sans);color:#161616;overflow-wrap:anywhere;}
.pdf-dialog > .attachment-close{position:absolute;right:18px;top:18px;width:28px;height:28px;color:var(--text);}
.pdf-preview-content{display:flex;flex-direction:column;align-items:center;margin-top:48px;}
.pdf-stack{position:relative;display:block;flex:none;width:var(--pdf-width,188px);max-width:calc(100% - 24px);aspect-ratio:var(--pdf-ratio,.707);cursor:pointer;}
.pdf-sheet{position:absolute;inset:0;width:100%;height:100%;border-radius:9px;border:1px solid #e1e1e1;background:#fff;transition:transform .24s cubic-bezier(.2,.7,.2,1),border-color .2s;transform-origin:50% 90%;}
.pdf-sheet-back{transform:translate(8px,3px);background:#e9e9e9;}
.pdf-sheet-middle{transform:translate(4px,1px);background:#f4f4f4;}
.pdf-sheet-front{object-fit:contain;box-shadow:0 2px 6px #0000001f;}
.pdf-preview-content[aria-busy="true"] .pdf-sheet-front{visibility:hidden;}
.pdf-preview-content:hover .pdf-sheet-back,.pdf-preview-content:focus-within .pdf-sheet-back{transform:translate(12px,4px) rotate(3deg);border-color:#9cc5ff;}
.pdf-preview-content:hover .pdf-sheet-middle,.pdf-preview-content:focus-within .pdf-sheet-middle{transform:translate(6px,1px) rotate(1.5deg);border-color:#9cc5ff;}
.pdf-preview-content:hover .pdf-sheet-front,.pdf-preview-content:focus-within .pdf-sheet-front{transform:rotate(-1deg) translateY(-2px);border-color:#71acff;}
.pdf-stack:focus-visible{outline:2px solid #71acff;outline-offset:6px;border-radius:9px;}
.pdf-preview-footer{display:grid;place-items:center;margin-top:14px;min-height:20px;font:400 14px/20px var(--font-anthropic-sans);}
.pdf-page-count,.pdf-download{grid-area:1/1;}
.pdf-page-count{color:#64645f;pointer-events:none;transition:opacity .15s;}
.pdf-download{display:flex;align-items:center;gap:6px;color:#1e5ba6;opacity:0;pointer-events:none;font:inherit;transition:opacity .15s;}
.pdf-preview-content:hover .pdf-page-count,.pdf-preview-content:focus-within .pdf-page-count{opacity:0;}
.pdf-preview-content:hover .pdf-download,.pdf-preview-content:focus-within .pdf-download{opacity:1;pointer-events:auto;}
.pdf-download:focus-visible{outline:2px solid currentColor;outline-offset:3px;border-radius:3px;}
[data-theme="dark"] .pdf-overlay{background:rgb(0 0 0 / .6);}
[data-theme="dark"] .pdf-dialog{--pdf-arrow:#20201f;background:#20201f;border-color:#383837;}
[data-theme="dark"] .pdf-dialog h2{color:#eee;}
[data-theme="dark"] .pdf-sheet-back{background:#828281;}
[data-theme="dark"] .pdf-sheet-middle{background:#b9b9b8;}
[data-theme="dark"] .pdf-page-count{color:#c3c3b8;}
[data-theme="dark"] .pdf-download{color:#70aff7;}
@keyframes pdf-dialog-enter{from{opacity:0;transform:scale(.97);}to{opacity:1;transform:none;}}
@media(prefers-reduced-motion:reduce){.pdf-dialog{animation:none;}.pdf-sheet,.pdf-page-count,.pdf-download{transition:none;}}
@media(hover:none){.pdf-preview-footer{gap:8px;}.pdf-page-count,.pdf-download{grid-area:auto;}.pdf-download{opacity:1;pointer-events:auto;}.pdf-preview-content:focus-within .pdf-page-count{opacity:1;}}
.image-lightbox-frame{position:relative;width:max-content;margin:0;max-width:100%;text-align:center;}
.image-lightbox .attachment-full-image{
  display:block;width:auto;height:auto;max-width:min(640px,calc(100vw - 112px));max-height:calc(100dvh - 144px);
  object-fit:contain;border-radius:6px;box-shadow:0 8px 40px rgb(0 0 0 / .2);
  transform-origin:top left;visibility:hidden;
}
.image-lightbox.image-ready .attachment-full-image{visibility:visible;}
.image-lightbox .attachment-close{
  position:absolute;top:0;right:-40px;width:32px;height:32px;color:#d5d5d5;border-radius:6px;
}
.image-lightbox .attachment-close:hover{color:#fff;background:rgb(255 255 255 / .1);}
.image-lightbox .attachment-close:focus-visible{outline:2px solid #ddd;outline-offset:2px;}
.image-lightbox figcaption{width:0;min-width:100%;margin-top:12px;color:#eee;font:400 14px/20px var(--font-anthropic-sans);overflow-wrap:anywhere;}
@keyframes image-lightbox-enter{from{opacity:0;}to{opacity:1;}}
@media(prefers-reduced-motion:reduce){.att-image-mask::after{animation:none;}}
.app[data-sidebar="closed"] .attachment-preview{--preview-sidebar-width:0px;}
@media (max-width:1023px){.attachment-preview{--preview-sidebar-width:0px;}}
@media (max-width:767px){
  .attachment-divider{display:none;}
  .attachment-preview{position:fixed;inset:8px;z-index:40;margin:0;max-width:none;}
  .attachment-source{padding:12px;}
  .attachment-code{padding:14px;font-size:12.5px;}
  .attachment-overlay{padding:16px;}
  .attachment-dialog{height:min(480px,calc(100dvh - 32px));padding:20px;}
  .attachment-dialog h2{font-size:18px;}
}
.att-skeleton{display:flex;flex-direction:column;gap:7px;width:100%;height:100%;}
.att-skeleton span{
  position:relative;overflow:hidden;flex:none;width:100%;height:12px;
  border-radius:4px;background:var(--bg-active);
}
.att-skeleton span:nth-child(2){width:72%;}
.att-skeleton .att-skeleton-tag{width:36px;height:18px;margin-top:auto;}
.att-skeleton span::after{
  content:'';position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,color-mix(in srgb,var(--text-faint) 25%,transparent),transparent);
  animation:att-shimmer 1.5s ease-in-out infinite;
}
@keyframes att-shimmer{to{transform:translateX(100%);}}
@media (prefers-reduced-motion:reduce){.att-skeleton span::after{animation:none;}}
@media (hover:none){.att-remove{opacity:1;}}

/* ============================================================
   4. 对话流
   ============================================================ */
/* 内容列比输入框窄，且左右对称。
   margin:0 auto 让它在和输入框同一个盒子里居中，于是两侧内收量必然相等
   ——（740 - --col-max）/ 2。
   之前这里用 padding-left 同时做"右移 + 变窄"，那必然左右不等：
   padding 只作用于一侧。整体位置该由 .feed / .composer-dock 的 padding 管，
   那个会把内容列和输入框一起挪，对称关系不受影响。*/
.turn{
  margin:0 auto 22px;
  max-width:var(--col-max);
}
/* column + align-items:flex-end：气泡靠右，下面还要挂一条动作条，
   所以这一轮是纵向的两行，不再是单个横向 flex。
   align-items 用 flex-end 而不是在子元素上 margin-left:auto —— 后者
   会让气泡先撑到 78% 再往回缩，长短句之间宽度会跳。 */
/* 下外边距单独收小：这一轮末尾还挂着一排动作图标，22px 是按"气泡直接接
   下一轮"定的，加上图标那一行就显得空。 */
.turn.me{display:flex;flex-direction:column;align-items:flex-end;margin-bottom:8px;}
.turn.me .bubble{
  background:var(--bg-hover);
  border-radius:11px;padding:7px 15px;
  max-width:78%;
  /* 包不住文字的两个来源，一起堵掉：
     1) min-width:0 —— flex 子元素默认 min-width:auto，内容比容器宽时
        不肯收缩，气泡就被内容顶破；
     2) overflow-wrap:anywhere —— 长 URL、连着的英文串、路径这种中间
        没有空格的东西，浏览器默认不肯断行，会直接戳出圆角外面。
        break-word 只在"这一行放不下"时才断，anywhere 连计算宽度时也算，
        配合 max-width 才真的收得住。 */
  min-width:0;
  overflow-wrap:anywhere;
  word-break:break-word;
  color:var(--text-body);font-size:14.8px;line-height:1.8;
  /* 气泡不用 --font-sans：那个栈的中文是思源黑体。这里要的是英文 Anthropic Sans
     + 中文微软雅黑，所以单独排一条，绕开思源。
     Windows 以外没有雅黑，退到苹方/冬青黑；Anthropic Sans Latin 带 unicode-range，
     只吃拉丁和数字，不会跟中文抢。*/
  font-family:var(--font-latin), "Microsoft YaHei", "PingFang SC",
              "Hiragino Sans GB", Helvetica, Arial, sans-serif;
  font-optical-sizing:none;
}
/* 气泡里的段落自带 1em 上下外边距，会把气泡撑高，这里清掉 */
.turn.me .bubble p{margin:0;}
.turn.me .bubble p + p{margin-top:9px;}
.turn.me .bubble > :first-child{margin-top:0;}
.turn.me .bubble > :last-child{margin-bottom:0;}
.turn.me .bubble ul,.turn.me .bubble ol{margin:6px 0;padding-left:20px;}
.turn.me .bubble pre{margin:8px 0;max-width:100%;overflow-x:auto;}
.turn.me .bubble img{max-width:100%;height:auto;}
.turn.me .atts{flex-wrap:wrap;justify-content:flex-end;align-items:flex-end;gap:8px;overflow:visible;padding:0;margin-top:0;margin-bottom:8px;}
.turn.me .att-image{flex:0 1 var(--image-width,240px);width:var(--image-width,240px);height:var(--image-height,160px);max-width:100%;}

/* 模型回答正文：英文和数字走 Anthropic Sans，中文沿用原来的 --font-sans。
   .md 只在助手的文本块上用（见 el('div','md')），所以不会波及用户消息。
   代码块不受影响 —— .md code / .md pre 自己声明了 --font-mono，优先级更高。 */
/* 只改模型回答（.md）的字号和行距；用户气泡走 .turn.me .bubble，
   仍是 14.8px / 1.65，不受这里影响。
   字号加大、行距收紧是配套的：行距是字号的倍数，字号一大而倍数不变，
   行间空白会跟着一起放大，看起来反而更松。1.72 → 1.62 抵掉这部分。*/
/* 15 -> 15.5，1.78 -> 1.70。行距是字号的倍数，字号变大而倍数不动，
   行间空白会跟着一起涨，看起来反而更松，所以两个必须一起调。
   实际行高：15 × 1.78 = 26.7px  ->  15.5 × 1.70 = 26.4px，字大了行反而略紧。 */
.md{color:var(--text-body);font-size:var(--md-fs);line-height:1.7;
  /* 英文/数字走 Anthropic Serif Latin（带 unicode-range，只接管 U+0000-00FF
     那段拉丁码位），中文一律微软雅黑 —— 衬线族拿不到汉字字形，会自动往后落。
     末尾 var(--font-serif) 只是没装雅黑时的兜底。
     opsz 显式钉在 16：Anthropic Serif 的光学尺寸轴下限就是 16，正文 15.5px
     会被钳住，不写死的话不同浏览器插值出来的笔画粗细不一致。 */
  font-family:var(--font-latin-serif), "Microsoft YaHei", "微软雅黑", var(--font-serif);
  font-variation-settings:"opsz" 16;}
.md p{margin:0 0 14px;}
.md p:last-child{margin-bottom:0;}
/* 标题跟正文同族。字号都在 17px 以上，opsz 不用钳，让它按字号自己插值。 */
.md h1,.md h2,.md h3,.md h4,.md h5,.md h6{font-family:var(--font-latin-serif), "Microsoft YaHei", "微软雅黑", var(--font-serif);font-weight:500;letter-spacing:-.01em;
  margin:22px 0 10px;line-height:1.3;}
.md h1,.md h2,.md h3,.md h4,.md h5,.md h6{font-size:var(--md-fs);}
.md h1{font-weight:650;} .md h2{font-weight:600;} .md h3{font-weight:560;}
.md h4,.md h5,.md h6{font-weight:500;}

/* 兜底：.md 里任何元素都不许自己改字号（<pre> 代码块除外，它要等宽小一号）。
   AI 有时会吐出带 <small>/<sub>/内联样式的片段，或 KaTeX 自带 em 缩放，
   这条把它们统统拉回 --md-fs，就不会一段大一段小。 */
.md :not(pre):not(pre *):not(sup):not(sub):not(code):not(.katex):not(.katex *):not(.md-cell-k):not(.md-th-sub):not(td):not(td *):not(.md-cell-v):not(.md-code *){
  font-size:var(--md-fs);
}
.md sup,.md sub{font-size:.75em;}
.md ul,.md ol{margin:0 0 14px;padding-left:22px;}
.md li{margin:4px 0;}
.md code{
  /* 行内 code：灰底 + 玫瑰色字，深浅两套主题下一致。 */
  /* 英文/数字走 Anthropic Mono（带 unicode-range 的 Latin 族），中文仍是微软雅黑。
     末尾兜底换成 --font-mono 而不是 --font-serif：万一本地字体没加载上，
     退到等宽而不是衬线，观感更接近本意。 */
  font-family:var(--font-latin-mono), "Microsoft YaHei", "微软雅黑", var(--font-mono);
  /* 比正文小一点点。Mono 的字面本来就比正文那套宽，同字号下看着更"胀"，
     收掉这 1px 正好和周围齐平。用 calc 而不是写死 14.5px：正文字号是
     --md-fs 一处控制的，改那个的时候这里要跟着一起走。
     0.95em 之类的比例值也能用，但 .md 上有兜底规则把子元素钉回 --md-fs，
     em 会被那条规则的 px 值替掉，所以这里必须自己也是 px。
     font-variation-settings 显式清成 normal：别让 .md 钉的 opsz 16 漏进 Mono。 */
  font-size:calc(var(--md-fs) - 1px);
  font-variation-settings:normal;
  /* 380 原本是给 Anthropic Serif 补偿底纹视重的。换成 Mono 后笔画本来就更细、
     字面更窄，再减重会发虚，所以回到 400。 */
  font-weight:400;
  color:var(--code-fg);
  background:var(--bg-inline-code);
  border:1px solid var(--border);   /* 灰色边框，跟随主题 */
  border-radius:var(--radius-sm);padding:1px 5px;}
.md pre{
  font-family:"SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size:var(--md-fs);line-height:1.65;
  font-variation-settings:normal;   /* 同上，别让正文的 opsz 漏进等宽体 */
  background:var(--bg-code);border:1px solid var(--border);
  border-radius:var(--radius-md);padding:8px 12px;overflow-x:auto;margin:0 0 12px;}
.md pre code{background:none;border:0;padding:0;font-size:inherit;
  color:inherit;font-family:inherit;}
.md .md-code{
  overflow:hidden;margin:0 0 12px;background:var(--bg-code);
  border:1px solid var(--border);border-radius:var(--radius-md);
}
.md .md-code-head{
  height:36px;padding:0 8px 0 16px;display:flex;align-items:center;
  justify-content:space-between;
  color:var(--text-muted);font-family:var(--font-sans);font-size:12px;
  font-weight:400;line-height:1;font-variation-settings:normal;
}
.md .md-code-lang{font-size:11px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.md .md-code-copy{
  position:relative;width:30px;height:30px;padding:0;display:grid;
  place-items:center;flex:none;border:0;border-radius:7px;
  background:transparent;color:var(--text-strong);cursor:pointer;
  transition:background-color .12s,color .12s;
}
.md .md-code-copy:hover{background:#F2F2F1;}
[data-theme="dark"] .md .md-code-copy:hover{background:#2B2B2A;}
.md .md-code-copy:focus-visible{outline:2px solid var(--border-strong);outline-offset:1px;}
.md .md-code-copy svg{display:block;}
.md .md-code-copy .code-copy-front{fill:var(--bg-code);}
.md .md-code-copy:hover .code-copy-front{fill:#F2F2F1;}
[data-theme="dark"] .md .md-code-copy:hover .code-copy-front{fill:#2B2B2A;}
.md .md-code-copy::after{
  content:attr(data-tip);position:absolute;z-index:3;
  top:calc(100% + 7px);right:0;padding:4px 8px;
  border:1px solid var(--tip-border);border-radius:8px;
  background:var(--tip-bg);color:var(--tip-fg);box-shadow:var(--shadow-pop);
  font-family:var(--font-sans);font-size:12px;font-weight:400;line-height:1.2;
  white-space:nowrap;opacity:0;pointer-events:none;
  transform:translateY(-2px);transition:opacity .12s,transform .12s;
}
.md .md-code-copy[data-tip]:hover::after,
.md .md-code-copy[data-tip]:focus-visible::after{
  opacity:1;transform:translateY(0);
}
.md .md-code-copy.is-copied:hover{background:transparent;}
.md .md-code pre{
  font-size:14px;
  margin:0;padding:5px 20px 18px;border:0;border-radius:0;background:transparent;
  overflow-x:auto;
}
/* Highlight.js 只负责生成 token；代码颜色和底色跟随应用主题。 */
.md .md-code .hljs-comment,.md .md-code .hljs-quote{color:#6a737d;font-style:italic;}
.md .md-code .hljs-keyword,.md .md-code .hljs-selector-tag,.md .md-code .hljs-literal{color:#a626a4;}
.md .md-code .hljs-string,.md .md-code .hljs-regexp,.md .md-code .hljs-addition,.md .md-code .hljs-attribute{color:#0C860C;}
.md .md-code .hljs-number,.md .md-code .hljs-symbol,.md .md-code .hljs-bullet{color:#986801;}
.md .md-code .hljs-title,.md .md-code .hljs-section,.md .md-code .hljs-name,.md .md-code .hljs-selector-id,.md .md-code .hljs-selector-class{color:#4078f2;}
.md .md-code .hljs-variable,.md .md-code .hljs-template-variable,.md .md-code .hljs-type,.md .md-code .hljs-built_in{color:#c18401;}
.md .md-code .hljs-meta,.md .md-code .hljs-link{color:#0184bc;}
.md .md-code .hljs-deletion{color:#e45649;}
[data-theme="dark"] .md .md-code .hljs-comment,[data-theme="dark"] .md .md-code .hljs-quote{color:#7f848e;}
[data-theme="dark"] .md .md-code .hljs-keyword,[data-theme="dark"] .md .md-code .hljs-selector-tag,[data-theme="dark"] .md .md-code .hljs-literal{color:#c678dd;}
[data-theme="dark"] .md .md-code .hljs-string,[data-theme="dark"] .md .md-code .hljs-regexp,[data-theme="dark"] .md .md-code .hljs-addition,[data-theme="dark"] .md .md-code .hljs-attribute{color:#83C255;}
[data-theme="dark"] .md .md-code .hljs-number,[data-theme="dark"] .md .md-code .hljs-symbol,[data-theme="dark"] .md .md-code .hljs-bullet{color:#d19a66;}
[data-theme="dark"] .md .md-code .hljs-title,[data-theme="dark"] .md .md-code .hljs-section,[data-theme="dark"] .md .md-code .hljs-name,[data-theme="dark"] .md .md-code .hljs-selector-id,[data-theme="dark"] .md .md-code .hljs-selector-class{color:#61aeee;}
[data-theme="dark"] .md .md-code .hljs-variable,[data-theme="dark"] .md .md-code .hljs-template-variable,[data-theme="dark"] .md .md-code .hljs-type,[data-theme="dark"] .md .md-code .hljs-built_in{color:#e6c07b;}
[data-theme="dark"] .md .md-code .hljs-meta,[data-theme="dark"] .md .md-code .hljs-link{color:#56b6c2;}
[data-theme="dark"] .md .md-code .hljs-deletion{color:#e06c75;}
/* Generated source uses the same syntax colors as conversation code blocks. */
.generated-preview{--source-bg:#fff;background:var(--source-bg);border-radius:10px;animation:none;}
[data-theme="dark"] .generated-preview{--source-bg:#212120;background:var(--source-bg);}
.generated-source{display:flex;flex-direction:column;height:100%;min-height:0;}
.generated-header{flex:none;height:44px;padding:0 10px 0 18px;gap:6px;border-bottom:1px solid var(--border);}
.generated-header h2{font-size:14px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.generated-format{color:var(--text-muted);font-weight:400;}
.generated-copied{display:inline-flex;align-items:center;justify-content:flex-end;gap:6px;flex:none;width:76px;margin-right:8px;color:#00a800;font-family:var(--font-sans);font-size:13px;line-height:1;white-space:nowrap;visibility:hidden;}
.generated-copied.is-copied{visibility:visible;}
.generated-copied svg{flex:none;}
.generated-copy-group{position:relative;display:flex;flex:none;height:28px;border:1px solid var(--border);border-radius:7px;}
.generated-copy{padding:0 10px;border:0;border-radius:6px 0 0 6px;background:transparent;color:var(--text-strong);font:inherit;font-size:13px;cursor:pointer;}
.generated-copy:disabled{opacity:.45;cursor:default;}
.generated-copy:hover:not(:disabled),.generated-menu button:hover{background:var(--bg-hover);}
.generated-copy:focus-visible,.generated-menu button:focus-visible{outline:2px solid var(--text-muted);outline-offset:2px;}
.generated-header .generated-menu-toggle{width:26px;height:26px;border-radius:0 6px 6px 0;}
.generated-menu-toggle::before{content:'';position:absolute;left:0;top:5px;bottom:5px;border-left:1px solid var(--border);}
.generated-menu-toggle{position:relative;}
.generated-menu{position:absolute;z-index:3;top:calc(100% + 6px);right:0;min-width:140px;padding:4px;background:var(--source-bg);border:1px solid var(--border-strong);border-radius:8px;box-shadow:var(--shadow-pop);}
.generated-menu[hidden],.generated-status[hidden]{display:none;}
.generated-menu button{display:flex;align-items:center;gap:8px;width:100%;padding:7px 9px;border:0;border-radius:4px;background:transparent;color:var(--text);font:inherit;font-size:13px;cursor:pointer;}
.generated-status{margin:10px 18px;}
.generated-image-host{flex:1;min-height:0;min-width:0;display:flex;align-items:center;justify-content:center;padding:24px;overflow:hidden;}
.generated-image-host[hidden]{display:none;}
.generated-image{display:block;width:100%;height:100%;min-height:0;object-fit:contain;}
.generated-menu button[aria-pressed="true"]{background:var(--bg-hover);color:var(--text-strong);}
.generated-menu button:disabled{opacity:.45;cursor:default;}
.generated-html-host{flex:1;min-height:0;display:flex;background:#fff;}
.generated-html-frame{display:block;flex:1;width:100%;height:100%;min-height:0;border:0;background:#fff;color-scheme:normal;}
.generated-scroll[hidden],.generated-html-host[hidden],.generated-html-reload[hidden]{display:none;}
body.preview-resizing .generated-html-frame{pointer-events:none;}
.generated-scroll{flex:1;min-height:0;min-width:0;overflow:auto;overscroll-behavior:contain;}
.generated-canvas{position:relative;min-width:100%;min-height:100%;}
.generated-scroll.md .generated-code{position:absolute;left:0;top:0;display:grid;grid-template-columns:max-content minmax(0,1fr);width:100%;margin:0;border:0;border-radius:0;overflow:visible;background:var(--source-bg);}
.generated-scroll.md .generated-static .generated-code{position:relative;width:max-content;min-width:100%;}
.generated-scroll.md .generated-code pre{margin:0;padding:6px 18px 20px 14px;overflow:visible;white-space:pre;overflow-wrap:normal;word-break:normal;font-family:var(--font-latin-mono),Consolas,"Microsoft YaHei",monospace;font-size:12px;line-height:21px;font-weight:400;tab-size:4;color:var(--text-strong);}
.generated-scroll.md .generated-code code,.generated-scroll.md .generated-code code span{font-family:inherit;font-size:inherit;line-height:inherit;letter-spacing:0;}
.generated-scroll.md .generated-code .generated-lines{position:sticky;left:0;min-width:38px;padding:6px 9px 20px 12px;border-right:1px solid var(--border);background:var(--source-bg);color:var(--text-muted);text-align:right;user-select:none;}
.attachment-preview.generated-expanded{position:fixed;inset:8px;z-index:50;max-width:none;margin:0;}
@media (max-width:767px){
  .generated-header{padding-left:12px;gap:3px;}
  .generated-header h2{font-size:13px;}
  .generated-copied{width:70px;margin-right:3px;gap:4px;font-size:12px;}
  .generated-scroll.md .generated-code pre{padding-right:12px;}
}
/* 超链接统一走 --md-link，并把 :visited / :hover / :active 一起钉死 ——
   不写全的话浏览器会给已访问过的链接套上默认的紫色，就成了"各种颜色"。 */
.md a,.md a:link,.md a:visited,.md a:hover,.md a:active{
  color:var(--md-link);
  text-decoration:underline;
  text-decoration-color:color-mix(in srgb, var(--md-link) 45%, transparent);
  text-underline-offset:2px;
}
.md a:hover{text-decoration-color:var(--md-link);}
/* AI 这一轮里其它容器（文件卡、检查点、工具结果）中的链接同样收编 */
.turn.ai a:not(.fc-btn):not(.ob-zip){color:var(--md-link);}
.md img{max-width:100%;border:1px solid var(--border);border-radius:var(--radius-md);
  margin:4px 0 14px;display:block;background:#fff;}
.md blockquote{margin:0 0 14px;padding-left:14px;border-left:2px solid var(--border-strong);color:var(--text-muted);}

/* GFM 表格：圆角卡片。对比表（表头首格为空）把行标签写进每个格子。 */
.md .md-table-wrap{
  overflow-x:auto;margin:8px 0 18px;
  border:1px solid var(--border);border-radius:16px;
  background:var(--bg-main);
  font-family:var(--font-latin), "Microsoft YaHei", "微软雅黑", var(--font-sans);
  font-variation-settings:normal;
}
.md .md-table-wrap table{
  width:100%;border-collapse:separate;border-spacing:0;
  table-layout:fixed;font-variant-numeric:tabular-nums;
}
.md .md-table-wrap th,
.md .md-table-wrap td{
  padding:14px 16px;vertical-align:top;line-height:1.55;
  border-bottom:1px solid var(--border);
  border-right:1px solid var(--border);
  color:var(--text-strong);
}
.md .md-table-wrap th:last-child,
.md .md-table-wrap td:last-child{border-right:0;}
.md .md-table-wrap thead th{
  font-weight:400;background:transparent;
  border-bottom:1px solid var(--border);
}
.md .md-th-t{font-weight:400;letter-spacing:-.01em;}
.md .md-th-sub{
  margin-top:5px;font-weight:400;font-size:13px;
  color:var(--text-muted);line-height:1.4;
}
.md .md-table-wrap td,
.md .md-table-wrap td *{
  font-size:13.5px;
}
.md .md-cell-k{
  margin:0 0 6px;font-size:12.5px;font-weight:400;
  color:var(--text-muted);line-height:1.35;
}
.md .md-cell-v{font-weight:500;color:var(--text-strong);font-size:13.5px;}
.md .md-table-wrap tbody tr{cursor:pointer;}
.md .md-table-wrap tbody tr:hover td{background:var(--bg-hover);}
.md .md-table-wrap tbody tr[data-on] td{background:var(--bg-active);}
.md .md-table-wrap thead th:first-child{border-top-left-radius:16px;}
.md .md-table-wrap thead th:last-child{border-top-right-radius:16px;}
.md .md-table-wrap tbody tr:last-child td{border-bottom:0;}
.md .md-table-wrap tbody tr:last-child td:first-child{border-bottom-left-radius:16px;}
.md .md-table-wrap tbody tr:last-child td:last-child{border-bottom-right-radius:16px;}

/* 流式正文里刚出现的字。span 是临时的：动画一结束 JS 就把它摊平成纯文本，
   所以同一时刻页面上最多两三个，blur 的开销可以忽略。
   一块一块淡入：每次 .tk 里是半行、一行或一整段，不再是一个字一个字。 */
.md .tk{display:inline;animation:tk-in .45s cubic-bezier(.22,.61,.36,1) both;}
@keyframes tk-in{
  from{opacity:0;filter:blur(1.5px);}
  60% {opacity:.75;filter:blur(.3px);}
  to  {opacity:1;filter:blur(0);}
}
/* 已收尾的整块（段落/列表/标题/代码块/表格）首次插入时的淡入 */
.md .ln{animation:ln-in .45s cubic-bezier(.22,.61,.36,1) both;}
@keyframes ln-in{
  from{opacity:0;transform:translateY(5px);filter:blur(1px);}
  to  {opacity:1;transform:translateY(0);filter:blur(0);}
}
@media (prefers-reduced-motion:reduce){
  .md .tk,.md .ln{animation:none;}
}

/* KaTeX：让公式颜色跟随正文，行间公式不撑破容器、可横向滚动 */
/* KaTeX 内部靠 em 做上下标/分数排版，所以整棵子树从上面的兜底里排除掉，
   只在根节点钉一次字号。 */
.md .katex{color:inherit;font-size:var(--md-fs);}
.md .katex-display{margin:8px 0;overflow-x:auto;overflow-y:hidden;padding:2px 0;}

/* 光标 */
.caret{display:inline-block;width:8px;height:16px;border-radius:2px;
  background:var(--text-faint);vertical-align:-3px;animation:blink 1s steps(2) infinite;}
@keyframes blink{50%{opacity:.15;}}

/* 等待首个响应（连沙箱 + 模型还没吐字）时的占位行。
   排版完全对齐 .tg-head：28px 图标 + 13.5px 中英混排 + 同一条 shimmer，
   所以真正的工具组头一到，位置和基线都不动，只是图标和文字被换掉。 */
.tg-wait{
  display:flex;align-items:flex-start;gap:12px;
  margin:0 0 4px;padding:1px 0 2px;
  color:var(--text-muted);font-size:13.5px;line-height:1.6;
  font-family:var(--font-latin), var(--font-sans);
  font-optical-sizing:none;
}
.tg-wait .tg-ic{display:grid;width:28px;height:28px;flex:none;
  place-items:center;color:var(--accent);}
/* 等待期的图标自带逐帧动画（SVG 内联 style），这里不再叠外部动画 */
.tg-wait .ht{flex:0 1 auto;min-width:0;display:flex;align-items:center;min-height:28px;}
/* 换词：新词淡入，旧词不留残影（每次换词都重建这个 span，动画自然重放） */
.tg-wait .ht > span{display:inline-block;animation:wait-word .34s var(--ease);}
@keyframes wait-word{from{opacity:0;transform:translateY(2px);}to{opacity:1;transform:none;}}

/* ---------- 思考 / 工具调用分组 ---------- */
/* 组（summary + 工具步骤）和前后正文之间的间距。
   原来是 16px 外边距 + 10px 组头内边距，一组只有一行 summary 时，
   上下加起来快 30px，正文被这些灰行切得很散。收到 10 + 6。
   展开、有步骤时留原来的呼吸感（.tgroup:not([data-empty]) 那条）。 */
.tgroup{margin:0 0 4px;}
.tgroup[data-open="false"]{margin-bottom:3px;}
.tgroup[data-open="false"] .tg-head{padding-bottom:1px;}
/* 组里真的有工具步骤时，步骤块和下方正文之间需要多一点间隔。
   注意这里不是唯一的间距来源：最后一条 .tstep 自带 5px 下内边距，
   所以 8 实际落地是 13px 左右，比看数值想象的松。 */
.tgroup:not([data-empty="true"]){margin-bottom:8px;}
.tg-head{
  display:flex;align-items:flex-start;gap:12px;
  width:100%;text-align:left;
  color:var(--text-muted);font-size:13.5px;line-height:1.6;
  padding:1px 0 2px;
  /* 组头 summary 是中英混排（"Ran a shell command" / "读取路由表"）：
     英文和数字走 Anthropic Sans（--font-latin 带 unicode-range），
     汉字落到 --font-sans 里的 PingFang / 雅黑 —— Anthropic Sans 没有中文字形，
     这是能做到的上限，不是回退失败。
     14.5px 低于 Anthropic Sans 的 opsz 轴下限 16，关掉自动挡免得被钳住。*/
  font-family:var(--font-latin), var(--font-sans);
  font-optical-sizing:none;
}
.tg-head .tg-ic{
  /* 25 -> 28：图标本体从 15 放到 18，容器要跟着放，不然描边贴边 */
  display:none;width:28px;height:28px;flex:none;
  place-items:center;color:var(--accent);
}
.tgroup[data-running="true"] .tg-head .tg-ic{display:grid;}
/* 组头和步骤行同一个毛病、同一个解法：文字盒在自己盒子里居中。
   min-height 只在跑着的时候给，因为左边那个 28px 的 .tg-ic 也只有这时才显示。
   不跑的时候保持自然行高，组头高度和改动前完全一致，不会有跳动。 */
.tg-head .ht{flex:0 1 auto;min-width:0;display:flex;align-items:center;}
.tgroup[data-running="true"] .tg-head .ht{min-height:28px;}
.tg-head .tg-elapsed{
  flex:none;white-space:nowrap;color:var(--text-faint);
  font-variant-numeric:tabular-nums;line-height:inherit;
}
.tg-head .tg-elapsed[hidden]{display:none;}
.tgroup[data-running="true"] .tg-head .tg-elapsed{
  display:flex;align-items:center;min-height:28px;
}
.tgroup[data-running="true"] .tg-head .tg-elapsed[hidden]{display:none;}
.tg-head .hc{
  color:var(--text-faint);margin-top:5px;margin-left:-5px;
  opacity:0;transition:opacity .15s,transform .18s var(--ease);
}
.tg-head:hover .hc,
.tg-head:focus-visible .hc{opacity:1;}
.tgroup[data-open="false"] .hc{transform:rotate(-90deg);}
.tgroup[data-open="false"] .tg-steps{display:none;}
/* 只有还没出步骤（纯思考阶段）时组头才闪；等待占位行同一套 */
.tg-wait .ht,
.tgroup[data-running="true"] .tg-head .ht,
.tgroup[data-running="true"] .tg-steps > .tstep:last-child .step-label{
  background-image:linear-gradient(90deg,
    var(--text-muted) 0%, var(--text-muted) 34%,
    var(--text-strong) 50%,
    var(--text-muted) 66%, var(--text-muted) 100%);
  background-size:300% 100%;
  background-repeat:no-repeat;
  -webkit-background-clip:text;background-clip:text;color:transparent;
  animation:shimmer 3.6s linear infinite;
}
/* 0%~100% 是渐变始终盖满文字的安全区间，越界会有字没被背景覆盖而变透明 */
@keyframes shimmer{
  from{background-position:100% 0;}   /* 亮带在第一个字母左侧 */
  to  {background-position:0% 0;}     /* 扫到最后一个字母右侧 */
}
@media (prefers-reduced-motion:reduce){
  .tg-wait .ht,
  .tgroup[data-running="true"] .tg-head .ht,
  .tgroup[data-running="true"] .tg-steps > .tstep:last-child .step-label{
    background-image:none;color:var(--text-muted);
  }
  .tg-wait .ht > span{animation:none;}
  .tg-wait .wait-spark *{animation:none !important;}
}
.tstep[data-state="run"] .step-label:hover{color:transparent;}

.tg-steps{display:flex;flex-direction:column;}
/* 运行中只露最后几条：早的直接收起，最新的永远在最下面 */
.tstep[data-rolled="true"]{display:none;}
.tstep[data-fresh="true"]{animation:step-in .22s var(--ease);}
@keyframes step-in{
  from{opacity:0;transform:translateY(7px);}
  to{opacity:1;transform:none;}
}
.tstep{position:relative;display:flex;gap:12px;padding:5px 0;}
.tstep:not(:last-child)::before{
  /* left 取图标容器的中线（28/2 = 14），top 从图标下沿起（padding 5 + 28 - 1） */
  content:"";position:absolute;left:14px;top:32px;bottom:-6px;
  width:1px;background:var(--border);
}
.step-ic{
  position:relative;z-index:1;
  /* 25 -> 28，配合 STEP_ICON 从 17 放到 20 */
  width:28px;height:28px;flex:none;
  display:grid;place-items:center;
  border-radius:50%;
  background:var(--bg-main);
  color:var(--text-faint);
}
.tstep[data-state="run"] .step-ic{color:var(--text-strong);animation:softpulse 1.2s ease-in-out infinite;}
.tstep[data-kind="done"] .step-ic{color:var(--ok);}
.tstep[data-kind="error"] .step-ic{color:var(--danger);}
@keyframes softpulse{50%{opacity:.35;}}

/* 竖向对齐：以前这里是 padding-top:1px 把文字硬顶到行首，靠英文小写字母
   视觉重心低、看不出偏差蒙混过去。汉字换成思源黑体后就藏不住了：
   思源黑体的 ascent/descent 约 1.16em / 0.32em，比 Anthropic Sans 高出一截，
   行盒会长高、基线会下移；而汉字字面占到基线以上 0.88em，是一整块实心方块，
   中线比 28px 图标的中线高个两三像素立刻就看得见。
   现在改成：文字盒和图标盒等高（28px），各自在自己盒子里居中，
   两条中线天然重合。行盒高度随字体/字号变化由 align-items:center 自己吸收，
   不用再按字体一处处调 padding。
   图标盒尺寸没动，所以下面 .tstep::before 那条竖线的 top:32px 仍然成立。 */
.step-main{flex:1;min-width:0;padding-top:0;}
.step-label{
  display:inline-flex;align-items:center; /* inline 保持贴着文字取宽度，扫光才不会跑到空白上 */
  min-height:28px;                        /* 和 .step-ic 等高 */
  text-align:left;
  color:var(--text-muted);font-size:13.5px;line-height:1.5;
  padding:0;border-radius:var(--radius-sm);
  transition:color .15s;
  /* 和 .tg-head 同一套：英文 Anthropic Sans、汉字 CJK 回退，14px 关光学尺寸 */
  font-family:var(--font-latin), var(--font-sans);
  font-optical-sizing:none;
}
.step-label:hover{color:var(--text-strong);}

.step-detail{display:none;padding:6px 0 4px;}
.tstep[data-open="true"] .step-detail{display:block;}
.step-detail pre{
  font-family:var(--font-mono);font-size:12px;line-height:1.55;
  background:var(--bg-code);border:1px solid var(--border);
  border-radius:var(--radius-md);padding:10px 12px;
  margin:0 0 6px;max-height:300px;overflow:auto;white-space:pre-wrap;word-break:break-word;
  color:var(--text);
}
/* 思维链正文：读起来像自然语言，不是代码。英文正文字体 + 中文雅黑，
   字号略大、行距松一点；仍保留可滚动的最大高度。 */
.step-detail pre.think-pre{
  font-family:var(--font-latin-serif), "Microsoft YaHei", "微软雅黑", var(--font-sans);
  font-size:13px;line-height:1.7;
  color:var(--text-muted);
  max-height:340px;
}
/* 正文块往下接工具组时的间隔。上面 .tgroup 的 margin-bottom 管"组 -> 正文"，
   这条管"正文 -> 组"，两边都收才不会一头紧一头松。 */
.turn.ai > .md{margin-bottom:7px;}
.turn.ai > .md:last-child{margin-bottom:0;}
/* 正文块开头如果是标题，h1~h3 自带 22px 上外边距，会在组头下面顶出一段空白，
   看起来像是间距根本没改。首元素的上外边距一律清掉。 */
.turn.ai > .md > :first-child{margin-top:0;}

/* ---------- 一轮回答末尾的动作条 ----------
   回答的图标常显，只有时间在悬停这一行时淡入；保留时间占位避免布局跳动。
   用户气泡的动作条仍在悬停气泡或键盘聚焦时显示。 */
.turn-acts{
  display:flex;align-items:center;gap:0;
  margin:0 0 0 -5px;                /* -5px：抵掉按钮的内边距，图标左缘和正文对齐 */
  font-family:var(--font-sans);
  opacity:0;pointer-events:none;
  transition:opacity .14s var(--ease);
}
.turn.ai .turn-acts,
.turn.me:hover .turn-acts,
.turn-acts:focus-within{opacity:1;pointer-events:auto;}
.turn.ai .turn-acts{gap:0;}
.turn.ai .turn-acts .turn-time{
  margin-left:3px;
  font-size:11px;color:var(--text-muted);
  opacity:0;pointer-events:none;
  transition:opacity .14s var(--ease);
}
.turn.ai .turn-acts:hover .turn-time,
.turn.ai .turn-acts:has(.act-btn:focus-visible) .turn-time{opacity:1;pointer-events:auto;}

/* 用户那条靠右贴齐气泡右缘。负的右外边距和 AI 那条的负左外边距是一回事：
   抵掉最后一个按钮的内边距，让图标右缘和气泡右缘对齐。 */
.turn-acts.user-acts{
  align-self:flex-end;
  /* 右边留出一段，整排往左挪。不是负值了 —— 用户那条不需要和气泡右缘
     对齐（AI 那条要和正文左缘对齐才用负的左外边距）。 */
  margin:7px 4px 0 0;   /* 上外边距 2 -> 7，离气泡远一点 */
}
/* 用户动作条保留紧凑尺寸。 */
.turn.me .act-btn{width:26px;height:26px;}

/* .turn-acts 自己声明了 display:flex，优先级高过浏览器给 [hidden] 的
   display:none —— 所以编辑态里 bar.hidden = true 其实没让它消失。
   这条把它补回来。 */
.turn-acts[hidden]{display:none;}
/* 触屏没有 hover，一直显示，否则这排按钮永远摸不到 */
@media (hover:none){ .turn-acts{opacity:1;pointer-events:auto;} }

.act-btn{
  width:24px;height:24px;flex:none;
  display:grid;place-items:center;
  border-radius:var(--radius-sm);
  color:var(--text-faint);
  transition:background .15s,color .15s;
}
.act-btn:hover{background:var(--bg-hover);color:var(--text-strong);}
.act-btn:active{background:var(--bg-active);}
.turn.ai .act-btn{width:24px;height:24px;color:var(--text-muted);}
.turn.ai .act-btn:hover{color:var(--text-strong);}
.act-btn svg{display:block;}

/* Claude 星标：32px，#D97757。页脚预留动作条高度，收尾填按钮不挤星标。 */
.turn-foot{
  display:flex;flex-direction:column;align-items:flex-start;gap:0;
  margin:0;
}
.turn.ai > :is(.outbox,.filecard) + .turn-foot{margin-top:10px;}
.turn-foot .turn-acts,
.turn-foot .turn-acts-slot{
  margin:0 0 0 -5px;
  height:24px;min-height:24px;box-sizing:border-box;
}
/* 徽标是一个 32x32 的「窗口」，里面装的是一条 32x(32*帧数) 的竖排精灵，
   靠 CSS transform 一帧帧往上推（见下面的 @keyframes）。
   窗口必须 overflow:hidden + contain，否则整条会漏出来。
   margin-top 从 10 加到 20：动作条和星标之间要留得开一点，
   这一轮有产物文件时星标是贴在文件卡片下面的，太近会像是卡片的一部分。 */
.claude-mark,.compact-mark{
  display:block;overflow:hidden;
  width:32px;height:32px;flex:none;
  margin:20px 0 2px 0;
  pointer-events:none;
  color:#D97757;fill:#D97757;
  contain:strict;
}
.claude-mark .claude-svg,.compact-mark .claude-svg{
  display:block;width:32px;height:auto;
  fill:#D97757;
}

/* 逐帧推进。用 steps(n) 而不是 SMIL 的 calcMode="discrete"：
   · transform 动画能被提升到合成层，主线程在渲染正文/公式/高亮时也不掉帧；
   · 整条 path 只栅格化一次，之后每帧只是平移一个已有的纹理。
   steps(n) 取的是 0/n … (n-1)/n，所以终点写成「再多走一帧」的位移，
   实际停在最后一帧上，不会闪回第 0 帧。 */
@keyframes claude-sprite-run{
  from{transform:translate3d(0,0,0);}
  to{transform:translate3d(0,-480px,0);}     /* 15 帧 x 32px */
}
@keyframes claude-loop-run{
  from{transform:translate3d(0,0,0);}
  to{transform:translate3d(0,-256px,0);}     /* 8 帧 x 32px */
}
.claude-svg-sprite,
.claude-svg-loop{
  will-change:transform;
  backface-visibility:hidden;
  transform:translate3d(0,0,0);
}
.claude-svg-sprite{animation:claude-sprite-run 2s steps(15,end) infinite;}
.claude-svg-loop{animation:claude-loop-run .9s steps(8,end) infinite;}
@media (prefers-reduced-motion:reduce){
  .claude-svg-sprite,.claude-svg-loop{animation:none;}
}

.turn-time{
  position:relative;
  margin-left:3px;padding:1px 1px;
  font-family:var(--font-sans);
  font-size:11px;line-height:1.2;color:var(--text-faint);
  white-space:nowrap;cursor:default;
}
/* 悬停在时间上给出完整时刻。用 ::after + attr() 而不是 title 属性：
   原生 tooltip 要停 1~2 秒才弹，样式也跟不了主题。
   配色走 --tip-* 三个变量（见两个主题块）：亮色近黑底白字，
   暗色仍然是深色小块 + 一圈亮描边，**不是**反白。 */
.turn-time::after{
  content:attr(data-full);
  position:absolute;left:-6px;bottom:calc(100% + 7px);
  /* padding 和 line-height 一起收：默认 line-height 继承自正文（1.7），
     光减 padding 的话上下还是空的 —— 撑开框的是行高，不是内边距。
     这两个数是照着设计稿量出来的（框高约等于字高的 1.9 倍）。 */
  padding:2px 7px;border-radius:var(--radius-md);
  background:var(--tip-bg);color:var(--tip-fg);
  border:1px solid var(--tip-border);
  font-size:12px;font-weight:500;letter-spacing:.01em;line-height:1.25;
  white-space:nowrap;
  box-shadow:var(--shadow-pop);
  opacity:0;pointer-events:none;
  transition:opacity .12s;
}
.turn-time:hover::after{opacity:1;}
.user-acts .turn-time::after{left:auto;right:-6px;}

/* ---------- 编辑已发出的问题 ----------
   气泡原地换成一个输入框。宽度给到 78%（和气泡上限一致）而不是跟着
   内容走：编辑时手一打字框子就变宽变窄，光标位置会跟着跳。 */
.turn.me .edit-box{
  width:78%;
  display:flex;flex-direction:column;gap:10px;
}
.turn.me .edit-input{
  width:100%;
  resize:none;overflow:hidden;
  background:var(--bg-composer);
  color:var(--text-body);
  border:1px solid var(--border-strong);
  border-radius:11px;
  padding:10px 15px;
  font-size:14.8px;line-height:1.8;
  font-family:var(--font-latin), "Microsoft YaHei", "PingFang SC",
              "Hiragino Sans GB", Helvetica, Arial, sans-serif;
  outline:0;
  transition:border-color .12s, box-shadow .12s;
}
/* 聚焦环走 --accent 的话在暗色下会是橙色，和截图里的蓝不一样；
   这里单独给一个变量，两套主题各自定。 */
.turn.me .edit-input:focus{
  border-color:var(--edit-ring);
  box-shadow:0 0 0 1px var(--edit-ring);
}
.turn.me .edit-foot{
  display:flex;align-items:center;justify-content:flex-end;gap:10px;
}
/* ⓘ 挨着 Cancel 放，整组一起靠右（见截图），不要顶到最左边 */
.edit-hint{
  color:var(--text-faint);display:grid;place-items:center;cursor:help;
}
.edit-btn{
  padding:6px 14px;border-radius:var(--radius-lg);
  font-family:var(--font-sans);font-size:13.5px;font-weight:500;
  transition:background .12s,color .12s;
}
.edit-btn.ghost{color:var(--text-body);background:none;}
.edit-btn.ghost:hover{background:var(--bg-hover);}
.edit-btn.primary{
  color:var(--fg-avatar);background:var(--bg-avatar);
}
.edit-btn.primary:hover{filter:brightness(1.12);}

/* ---------- 成品文件卡 ---------- */
.filecard{
  --fc-bg:#FEFDFD;--fc-border:#D8D8D6;--fc-hover:#B9BCBF;
  --fc-sheet:linear-gradient(160deg,#FAFAF9,#EDEDEB 70%);
  --fc-sheet-border:#D2D2CF;--fc-ink:#73736F;
  --fc-button:#FEFDFD;--fc-button-hover:#F1F1EF;
  box-sizing:border-box;width:100%;max-width:500px;height:70px;
  display:flex;align-items:center;gap:18px;position:relative;overflow:hidden;
  border:1px solid var(--fc-border);border-radius:12px;
  padding:0 16px 0 19px;margin:8px 0 0;
  background:var(--fc-bg);font-family:var(--font-sans);
  box-shadow:0 1px 2px rgb(0 0 0 / .06);
  transition:background .16s,border-color .16s;
}
[data-theme="dark"] .filecard{
  --fc-bg:#1A1A19;--fc-border:#3B3B39;--fc-hover:#60605D;
  --fc-sheet:linear-gradient(160deg,#353533,#252524 70%);
  --fc-sheet-border:#565651;--fc-ink:#B4B4AF;
  --fc-button:#2B3033;--fc-button-hover:#383F44;
  box-shadow:none;
}
/* File types share the card and its layered-paper hover animation. */
.filecard[data-file-type="html"],.filecard[data-file-type="htm"]{
  --fc-sheet:linear-gradient(160deg,#FFF7FA,#F8E8EE 70%);
  --fc-sheet-border:#F2A7C3;--fc-ink:#A83260;
}
[data-theme="dark"] .filecard[data-file-type="html"],
[data-theme="dark"] .filecard[data-file-type="htm"]{
  --fc-bg:#1B1517;--fc-border:#493B40;--fc-hover:#75525F;
  --fc-sheet:linear-gradient(160deg,#4B2032,#350E20 70%);
  --fc-sheet-border:#80445C;--fc-ink:#DF729C;
}
.filecard[data-file-type="docx"]{
  --fc-sheet:linear-gradient(160deg,#F5F9FF,#E5F0FB 70%);
  --fc-sheet-border:#A8CAFF;--fc-ink:#2463AE;
}
[data-theme="dark"] .filecard[data-file-type="docx"]{
  --fc-bg:#14191C;--fc-border:#363D41;--fc-hover:#606A72;
  --fc-sheet:linear-gradient(160deg,#173451,#032142 70%);
  --fc-sheet-border:#305678;--fc-ink:#70AAEA;
}
.filecard:hover,.filecard:focus-within{border-color:var(--fc-hover);}
[data-theme="dark"] .filecard[data-file-type="docx"]:hover,
[data-theme="dark"] .filecard[data-file-type="docx"]:focus-within{background:#111B23;}
.fc-icon{
  width:54px;height:52px;flex:none;align-self:flex-start;margin-top:15px;
  position:relative;padding:0;border:0;background:none;color:var(--fc-ink);
  cursor:pointer;
}
.fc-icon::before,.fc-sheet{
  position:absolute;inset:0 0 auto;height:70px;border:1px solid var(--fc-sheet-border);
  border-radius:8px;background:var(--fc-sheet);
  box-shadow:0 0 0 1px rgb(255 255 255 / .08) inset,0 2px 12px rgb(31 92 155 / .10);
  transition:transform .18s,opacity .18s;
}
.fc-icon::before{content:"";opacity:0;transform-origin:bottom center;}
.fc-sheet{display:flex;align-items:center;flex-direction:column;padding-top:17px;}
.fc-sheet svg{flex:none;}
.fc-sheet-lines{width:21px;height:6px;margin-top:7px;opacity:0;
  background:linear-gradient(currentColor,currentColor) left top / 100% 1px no-repeat,
    linear-gradient(currentColor,currentColor) left bottom / 52% 1px no-repeat;
  transition:opacity .18s;}
.filecard:hover .fc-icon::before,.filecard:focus-within .fc-icon::before{
  opacity:.65;transform:translateX(-4px) rotate(-5deg);}
.filecard:hover .fc-sheet-lines,.filecard:focus-within .fc-sheet-lines{opacity:.4;}
.fc-meta{flex:1;min-width:0;padding:0;border:0;background:none;color:inherit;text-align:left;cursor:pointer;}
.fc-name{font-size:14px;font-weight:400;line-height:1.4;color:var(--text-strong);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.fc-sub{font-size:12.5px;line-height:1.4;color:var(--text-muted);}
.fc-btn{
  flex:none;height:32px;padding:0 11px;border-radius:8px;
  border:1px solid #E4E4E2;background:var(--fc-button);
  color:var(--text-strong);font-family:var(--font-sans);font-size:13px;font-weight:400;
  box-shadow:0 1px 2px rgb(0 0 0 / .08);cursor:pointer;
  transition:background .15s;
}
.fc-btn:hover{background:var(--fc-button-hover);}
[data-theme="dark"] .fc-btn{border-color:transparent;box-shadow:none;}
.fc-icon:focus-visible,.fc-btn:focus-visible,.ob-zip:focus-visible{
  outline:2px solid #70AAEA;outline-offset:2px;}

/* ---------- 本轮产物区（贴在一轮回答的最末尾） ----------
   卡片竖着排，打包按钮在左下角。按钮不做成右对齐的主按钮：
   它是"顺手拿走全部"的次要动作，主动作仍然是每张卡自己的 Download。 */
.outbox{width:100%;max-width:500px;margin:16px 0 0;font-family:var(--font-sans);}
.ob-list > .filecard:first-child{margin-top:0;}
.ob-foot{display:flex;align-items:center;margin-top:8px;}
.ob-zip{
  display:inline-flex;align-items:center;gap:7px;
  height:32px;padding:0 10px;border-radius:8px;
  border:1px solid #E4E4E2;background:#FEFDFD;
  color:var(--text-strong);font-family:var(--font-sans);font-size:13px;font-weight:400;
  box-shadow:0 1px 2px rgb(0 0 0 / .08);cursor:pointer;
  transition:background .15s;
}
.ob-zip:hover{background:#F1F1EF;}
[data-theme="dark"] .ob-zip{background:#2D2D2D;border-color:transparent;box-shadow:none;}
[data-theme="dark"] .ob-zip:hover{background:#383838;}
.ob-zip:disabled{opacity:.55;cursor:default;}
.ob-zip svg{flex:none;}
@media(max-width:480px){
  .filecard{gap:12px;padding-left:12px;padding-right:10px;}
  .fc-icon{width:44px;}
  .fc-btn{padding:0 9px;font-size:12px;}
}
@media(prefers-reduced-motion:reduce){
  .filecard,.fc-icon::before,.fc-sheet,.fc-sheet-lines{transition:none;}
}

/* 系统提示条 */
.compact-status{
  display:flex;align-items:center;gap:18px;
  padding:12px 0;margin:0 0 18px;color:var(--text-muted);
}
.compact-mark{margin:0;}
.compact-content{min-width:0;flex:1;}
.compact-label{
  font-family:var(--font-sans);font-size:14px;font-style:normal;
  line-height:1.5;text-wrap:pretty;color:var(--text);
}
.compact-progress{display:flex;align-items:center;gap:12px;margin-top:9px;max-width:300px;}
.compact-track{height:5px;flex:1;overflow:hidden;border-radius:999px;background:var(--bg-active);}
.compact-fill{display:block;height:100%;border-radius:inherit;background:var(--text-muted);transition:width .5s linear;}
.compact-percent{min-width:48px;font-size:13px;font-variant-numeric:tabular-nums;white-space:nowrap;}
@media(max-width:480px){
  .compact-status{gap:12px;}
  .compact-label{font-size:13px;}
}
@media(prefers-reduced-motion:reduce){.compact-fill{transition:none;}}

.note{
  border-left:2px solid var(--accent);
  padding:8px 12px;margin:0 0 14px;
  font-size:13px;color:var(--text-muted);background:var(--bg-hover);
  border-radius:0 var(--radius-sm) var(--radius-sm) 0;
}
.note b{color:var(--text-strong);font-weight:600;}
.err{
  border-left:2px solid var(--danger);
  padding:8px 12px;margin:0 0 14px;
  font-size:13.5px;color:var(--danger);background:var(--bg-hover);
  border-radius:0 var(--radius-sm) var(--radius-sm) 0;
}
/* 压缩失败的提示条。warn = 还会重试，err = 这一轮已经停下。
   两者要长得不一样：前者是"等等看"，后者是"去改配置"。 */
.note.warn{
  border-left:2px solid var(--warn,#b5651d);
  color:var(--warn,#b5651d);background:var(--bg-hover);
}
.note.err{
  border-left:2px solid var(--danger);
  color:var(--danger);background:var(--bg-hover);
}
.note.err small,.note.warn small{opacity:.75;}

/* 回答被中断：与 summary 使用同一套拉丁字体。卡片本身承载状态，
   Edit prompt / Try again 分别接到现有的编辑与重试流程。 */
.interrupt-card{
  width:100%;min-height:45px;margin:2px 0 10px;padding:6px 7px 6px 11px;
  display:grid;grid-template-columns:18px minmax(0,1fr) auto;align-items:center;gap:7px;
  border:1px solid #dededa;border-radius:11px;background:#fff;
  color:var(--text-strong);
  font-family:var(--font-latin), var(--font-sans);font-optical-sizing:none;
}
.interrupt-icon{display:grid;place-items:center;color:#66655f;}
.interrupt-copy{font-size:14px;line-height:1.3;font-weight:400;}
.retry-detail{display:block;margin-top:3px;font-size:12px;color:var(--text-muted);}
.retry-dots{display:inline-block;white-space:nowrap;}
.retry-dots span{display:inline-block;animation:retry-dot 1.2s ease-in-out infinite;}
.retry-dots span:nth-child(2){animation-delay:.2s;}
.retry-dots span:nth-child(3){animation-delay:.4s;}
@keyframes retry-dot{
  0%,60%,100%{opacity:.25;transform:translateY(0);}
  30%{opacity:1;transform:translateY(-2px);}
}
@media (prefers-reduced-motion:reduce){
  .retry-dots span{animation:none;}
}
.interrupt-actions{display:flex;align-items:center;gap:6px;}
.interrupt-actions[hidden]{display:none;}
.interrupt-btn{
  min-height:27px;padding:3px 9px;border:1px solid #dededa;border-radius:8px;
  background:#fff;color:var(--text-strong);
  font-family:inherit;font-size:13.5px;line-height:1.2;font-weight:400;
  box-shadow:0 1px 2px rgb(0 0 0 / .08);
  transition:background .14s,color .14s,border-color .14s,box-shadow .14s,transform .08s;
}
.interrupt-btn:hover{background:#f5f5f3;border-color:#d2d1cc;}
.interrupt-btn:active{background:#ecece9;box-shadow:inset 0 1px 2px rgb(0 0 0 / .10);transform:translateY(1px);}
.interrupt-btn:disabled{cursor:default;opacity:.58;transform:none;}
.interrupt-card[data-pending="true"] .interrupt-btn{pointer-events:none;}
.interrupt-card.continuation-status,
[data-theme="dark"] .interrupt-card.continuation-status{
  background:transparent;color:var(--text-secondary, #888);border-color:transparent;
}
[data-theme="dark"] .interrupt-card{
  border-color:#343433;background:#151515;color:#f5f4ee;
}
[data-theme="dark"] .interrupt-icon{color:#d8d7d1;}
[data-theme="dark"] .interrupt-btn{
  border-color:#30302f;background:#30302f;color:#f5f4ee;box-shadow:none;
}
[data-theme="dark"] .interrupt-btn:hover{background:#3a3a39;border-color:#3a3a39;}
[data-theme="dark"] .interrupt-btn:active{
  background:#242423;border-color:#242423;box-shadow:inset 0 1px 2px rgb(0 0 0 / .38);
}
@media (max-width:600px){
  .interrupt-card{grid-template-columns:18px minmax(0,1fr);padding:7px 9px;}
  .interrupt-actions{grid-column:1 / -1;justify-self:end;}
}
.interrupt-card.interrupt-card-stacked{
  grid-template-columns:18px minmax(0,1fr);align-items:start;
}
.interrupt-card-stacked .interrupt-actions{grid-column:2;justify-self:start;}

/* Final error card. It uses the same Latin face as summary/tip UI and replaces
   the old red/grey note blocks for failures that need user action. */
.error-card{
  width:min(100%,620px);margin:4px 0 14px;padding:16px 20px 14px 24px;
  border:1px solid #d99800;border-radius:14px;
  background:#fff7db;color:#3d2d00;
  font-family:var(--font-latin), var(--font-sans);font-optical-sizing:none;
}
.error-head{display:flex;align-items:center;gap:10px;color:#b57600;font-size:15px;font-weight:500;}
.error-icon{display:grid;place-items:center;flex:none;}
.error-help{margin:12px 0 0 27px;font-size:14px;line-height:1.5;font-weight:400;color:#493b18;}
.error-detail{margin:8px 0 0 27px;font-family:var(--font-mono);font-size:13px;line-height:1.5;color:#635327;overflow-wrap:anywhere;}
.error-retry{
  min-height:31px;margin:11px 0 0 27px;padding:5px 11px;
  display:inline-flex;align-items:center;gap:7px;
  border:1px solid rgb(128 83 0 / .18);border-radius:8px;
  background:rgb(128 83 0 / .13);color:#3d2d00;
  font-family:var(--font-latin), var(--font-sans);font-size:13.5px;line-height:1.2;font-weight:400;
  transition:background .14s,border-color .14s,box-shadow .14s,transform .08s,opacity .14s;
}
.error-retry:hover{background:rgb(128 83 0 / .20);border-color:rgb(128 83 0 / .27);}
.error-retry:active{background:rgb(128 83 0 / .28);box-shadow:inset 0 1px 2px rgb(80 50 0 / .20);transform:translateY(1px);}
.error-retry:disabled{cursor:default;opacity:.62;transform:none;}
.error-card [hidden]{display:none !important;}
.error-card[data-pending="true"] .error-retry svg{animation:error-retry-spin .7s linear infinite;}
@keyframes error-retry-spin{to{transform:rotate(360deg);}}
[data-theme="dark"] .error-card,
[data-theme="dark"] .upload-warning{border-color:#714300;background:#3b2100;color:#f5f4ee;}
[data-theme="dark"] .error-head,
[data-theme="dark"] .upload-warning,
[data-theme="dark"] .upload-warning-icon{color:#e8a400;}
[data-theme="dark"] .error-help{color:#f2eee5;}
[data-theme="dark"] .error-detail{color:#d9cdb8;}
[data-theme="dark"] .error-retry{border-color:#6e4b23;background:#5a3b1d;color:#f5f4ee;}
[data-theme="dark"] .error-retry:hover{border-color:#815a2d;background:#694824;}
[data-theme="dark"] .error-retry:active{background:#4b3017;box-shadow:inset 0 1px 2px rgb(0 0 0 / .35);}
@media (max-width:600px){
  .error-card{padding:14px 15px 13px;}
  .error-help,.error-detail,.error-retry{margin-left:0;}
}

.ckpt{
  border:1px dashed var(--border-strong);border-radius:var(--radius-lg);
  padding:10px 14px;margin:0 auto 26px;max-width:740px;
  font-size:13px;color:var(--text-muted);
}
.ckpt summary{cursor:pointer;color:var(--text-muted);}
.ckpt pre{white-space:pre-wrap;font-family:var(--font-mono);font-size:12px;
  color:var(--text);margin:8px 0 0;max-height:320px;overflow:auto;}
.ckpt a{color:var(--accent);font-size:12.5px;display:inline-block;margin-top:8px;}

/* ============================================================
   5. 浮层
   ============================================================ */
.menu{
  position:absolute;z-index:40;
  min-width:190px;padding:5px;
  background:var(--bg-pop);
  border:1px solid var(--border);
  border-radius:var(--radius-lg);
  box-shadow:var(--shadow-pop);
  opacity:0;transform:translateY(4px);pointer-events:none;
  transition:opacity .14s,transform .14s var(--ease);
}
.menu[data-open="true"]{opacity:1;transform:none;pointer-events:auto;}
.menu-item{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  width:100%;padding:7px 9px;border-radius:var(--radius-sm);
  font-size:13.5px;text-align:left;transition:background .12s;
}
.menu-item:hover{background:var(--bg-hover);}
.menu-item small{display:block;color:var(--text-muted);font-size:12px;}
.menu-item .check{color:var(--accent);opacity:0;}
.menu-item[aria-checked="true"] .check{opacity:1;}

.model-menu{
  position:fixed;z-index:300;width:296px;min-width:0;max-width:calc(100vw - 16px);
  max-height:calc(100dvh - 16px);overflow-y:auto;padding:4px;
  border:1px solid var(--bd-acct);border-radius:12px;background:var(--bg-acct);
  color:var(--text-strong);box-shadow:0 12px 30px #0002,0 2px 5px #0001;
  font-family:var(--font-latin),var(--font-sans);font-optical-sizing:none;
  transform:none;transition:none;
}
.model-menu:not([data-open="true"]){display:none;}
[data-theme="dark"] .model-menu{box-shadow:0 14px 30px #0006,0 2px 5px #0003;}
.model-menu .menu-item{
  min-height:32px;padding:6px 10px;border-radius:8px;gap:8px;
  color:inherit;font-family:inherit;font-size:14px;line-height:20px;font-weight:400;
}
.model-menu .model-option{min-height:50px;padding-block:6px;}
.model-menu .menu-item b{display:block;font-size:14px;line-height:20px;font-weight:400;}
.model-menu .menu-item small{font-size:13px;line-height:18px;font-weight:400;color:var(--text-muted);}
.model-menu .menu-item > span:first-child{min-width:0;overflow-wrap:anywhere;}
.model-menu .menu-item:hover,.model-menu .menu-item:focus-visible,
.model-menu .menu-item[aria-expanded="true"]{background:var(--bg-acct-hover);outline:none;}
.model-menu .menu-item:focus-visible{box-shadow:inset 0 0 0 1px var(--text-faint);}
.model-menu .check{flex:none;margin-left:auto;color:#287bd5;}
.model-arrow{flex:none;margin-left:auto;color:var(--text-muted);}
.model-current-effort{display:flex;align-items:center;gap:8px;margin-left:auto;color:var(--text-muted);font-size:13px;}
.model-current-effort + .model-arrow{margin-left:0;}
.model-warning{flex:none;color:#ba7900;}
[data-theme="dark"] .model-warning{color:#e8a300;}
.model-separator{height:1px;margin:4px 9px;background:var(--border);}
.model-submenu{z-index:301;width:320px;}
.model-submenu[data-kind="more"]{width:140px;}
.model-submenu .menu-item{justify-content:flex-start;}
.model-effort-note{margin:3px 10px 7px;font-size:13px;line-height:18px;color:var(--text-muted);}
.model-badge{flex:none;display:inline-flex;align-items:center;gap:4px;padding:0 5px;border-radius:4px;background:var(--bg-hover);color:var(--text-muted);font-size:10px;line-height:16px;}
.model-usage{background:#ffe3ad;color:#805000;}
[data-theme="dark"] .model-usage{background:#392300;color:#e8a300;}

/* Reference at 150% scale: 624px main menu / 450px submenu, 21px model names. */
.model-menu.has-restricted-models{width:416px;}
.model-submenu[data-kind="more"].has-restricted-models{width:300px;}
.model-title{display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.model-option-copy{flex:1;min-width:0;}
.model-access-badge{display:inline-flex;align-items:center;gap:4px;flex:none;white-space:nowrap;padding:0 4px;border-radius:4px;background:#f3f3f2;color:#5d5d59;font-size:10px;line-height:16px;font-weight:500;}
.model-access-badge svg{flex:none;}
.model-buy{flex:none;margin-left:auto;padding:0 4px;border-radius:4px;background:#cee3ff;color:#185a9f;font-size:10px;line-height:16px;font-weight:500;white-space:nowrap;}
.model-access-note{margin:8px 10px 5px;color:var(--text-muted);font-size:13px;line-height:17px;}
.model-access-note button{padding:0;border:0;background:none;color:inherit;font:inherit;text-decoration:underline;cursor:pointer;}
[data-theme="dark"] .model-access-badge{background:#30302e;color:#bcbab0;}
[data-theme="dark"] .model-buy{background:#09233e;color:#6aabed;}
/* 400 CSS px -> 600px in the 150% reference; type uses the same scale. */
.model-access-dialog{box-sizing:border-box;width:400px;max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px);margin:auto;padding:24px;border:1px solid #d3d3d3;border-radius:12px;background:#fff;color:#141413;box-shadow:0 12px 24px #0002;font:400 14px/20px var(--font-anthropic-sans);overflow-y:auto;}
.model-access-dialog::backdrop{background:rgba(0,0,0,.4);}
.model-access-dialog h2{margin:0;padding-right:28px;font:600 22px/28px var(--font-anthropic-sans);letter-spacing:-.3px;}
.model-access-dialog > p{margin:20px 0;font-size:14px;line-height:20px;}
.model-access-dialog ul{list-style:none;padding:0;margin:0 0 32px;color:#60605a;}
.model-access-dialog li{display:flex;align-items:flex-start;gap:8px;min-height:24px;line-height:24px;}
.model-access-dialog li::before{content:'';flex:none;width:14px;height:8px;margin:6px 2px 0 2px;border-left:1px solid currentColor;border-bottom:1px solid currentColor;transform:rotate(-45deg);}
.model-access-dialog button{font:inherit;cursor:pointer;}
.model-access-close{position:absolute;right:20px;top:20px;display:grid;place-items:center;width:24px;height:24px;border:0;border-radius:4px;background:none;color:inherit;padding:0;}
.model-access-close:hover{background:var(--bg-hover);}
.model-access-dialog .model-access-primary{display:block;width:100%;min-height:30px;padding:5px 12px;border:0;border-radius:7px;background:#10100f;color:#fff;font-weight:500;}
.model-access-dismiss{display:block;margin:16px auto 0;padding:0;border:0;background:none;color:inherit;text-decoration:underline;line-height:20px;}
.model-access-dialog button:focus-visible,.model-access-note button:focus-visible{outline:2px solid #287bd5;outline-offset:3px;}
[data-theme="dark"] .model-access-dialog{background:#20201f;color:#eee;border-color:#393938;box-shadow:0 12px 24px #0005;}
[data-theme="dark"] .model-access-dialog ul{color:#b7b6ab;}
[data-theme="dark"] .model-access-primary{background:#fff;color:#141413;}
[data-theme="dark"] .model-access-dialog::backdrop{background:rgba(0,0,0,.6);}

/* The reference's 600 x 207 physical pixels at 150% are 400 x 138 CSS px. */
.confirm-dialog{box-sizing:border-box;width:400px;max-width:calc(100vw - 32px);max-height:calc(100dvh - 32px);margin:auto;padding:24px;border:1px solid #d3d3d3;border-radius:12px;background:#fff;color:#141413;box-shadow:0 12px 24px #0002;font:400 14px/20px var(--font-anthropic-sans);overflow-y:auto;}
.confirm-dialog::backdrop{background:rgba(0,0,0,.4);}
.confirm-dialog h2{margin:0;font:500 16px/20px var(--font-anthropic-sans);}
.confirm-dialog > p{margin:4px 0 0;color:#60605a;font:400 14px/20px var(--font-anthropic-sans);overflow-wrap:anywhere;}
.confirm-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:12px;}
.confirm-actions button{box-sizing:border-box;min-height:32px;padding:5px 11px;border:1px solid #e0e0e0;border-radius:8px;background:#fff;color:#141413;box-shadow:0 1px 2px #0001;font:400 14px/20px var(--font-anthropic-sans);cursor:pointer;}
.confirm-actions button:hover{background:#f5f5f4;}
.confirm-actions .confirm-accept{background:#d73739;border-color:#d73739;color:#fff;font-weight:500;}
.confirm-actions .confirm-accept:hover{background:#c72c2e;border-color:#c72c2e;}
.confirm-actions button:focus{outline:1px solid #777;outline-offset:2px;}
.confirm-actions .confirm-accept:focus{outline-color:#d73739;box-shadow:0 0 0 4px #d7373914;}
[data-theme="dark"] .confirm-dialog{background:#20201f;color:#eee;border-color:#393938;box-shadow:0 12px 24px #0005;}
[data-theme="dark"] .confirm-dialog > p{color:#b7b6ab;}
[data-theme="dark"] .confirm-dialog::backdrop{background:rgba(0,0,0,.6);}
[data-theme="dark"] .confirm-actions button:not(.confirm-accept){background:#383837;border-color:#383837;color:#eee;box-shadow:none;}
[data-theme="dark"] .confirm-actions button:not(.confirm-accept):hover{background:#444443;}

.account-menu{
  min-width:272px;padding:5px;border-radius:var(--radius-lg);
  max-width:min(360px, calc(100vw - 16px));
  font-family:var(--font-anthropic-sans);
  background:var(--bg-acct);
  border-color:var(--bd-acct);
}
.account-menu .menu-row:hover{background:var(--bg-acct-hover);}
/* 菜单里所有灰字统一走 --fg-acct-muted。只在账户菜单里覆盖，
   模型菜单那边的灰字不受影响。 */
.account-menu .menu-email,
.account-menu .menu-row .hint,
.account-menu .menu-row .caret-ic{color:var(--fg-acct-muted);}

/* 历史对话的那个菜单。宽度比账户菜单窄一点：条目都是短词。 */
.item-menu{min-width:238px;}
.item-menu:not([data-open="true"]){display:none;}
.item-menu.chats-item-menu{position:fixed;min-width:188px;width:188px;max-width:calc(100vw - 16px);padding:4px;border-radius:12px;background:#fff;border-color:#d3d3d3;box-shadow:0 8px 24px #00000014,0 2px 5px #0000000d;}
.chats-item-menu .menu-row{min-height:32px;padding:5px 10px;border-radius:8px;font-size:14px;}
.chats-item-menu .menu-row .hint{padding-left:0;}
.chats-item-menu .menu-sep{margin:6px 10px;}
[data-theme="dark"] .item-menu.chats-item-menu{background:#20201f;border-color:#393938;box-shadow:0 8px 24px #0005;}
/* 删除是唯一不可逆的一项，单独标红 —— 让手在按下去之前多认一眼。
   暗色那两条选择器要重写一遍：上面 [data-theme="dark"] .account-menu .menu-row
   把整列压成纯白，特指度比这里高，不重写的话暗色下删除就是白的。 */
.menu-row.danger,
.menu-row.danger > svg:first-child{color:var(--danger);}
[data-theme="dark"] .account-menu .menu-row.danger,
[data-theme="dark"] .account-menu .menu-row.danger > svg:first-child{color:var(--danger);}
.item-menu .menu-row.danger:hover{background:var(--bg-danger-hover);}
[data-theme="dark"] .account-menu{color:#fff;}
[data-theme="dark"] .account-menu .menu-row,
[data-theme="dark"] .account-menu .menu-row > svg:first-child{color:#fff;}
.menu-email{padding:4px 9px 5px;font-size:13px;color:var(--text-muted);
  white-space:normal;overflow-wrap:anywhere;line-height:1.45;}
.menu-sep{height:1px;background:var(--border);margin:4px 0;}
.menu-row{
  position:relative;display:flex;align-items:center;gap:10px;
  width:100%;padding:6.5px 10px;border-radius:var(--radius-sm);
  /* 字重从 500 降到 400：这一列是导航项不是标题，500 在 14px 上偏壮，
     和菜单顶上那行灰色邮箱放一起显得头重脚轻。 */
  font-size:14px;font-weight:400;color:var(--text-strong);
  text-align:left;transition:background .12s;
}
.menu-row:hover{background:var(--bg-hover);}
.menu-row > svg:first-child{flex:none;color:var(--text-strong);opacity:.92;}
.menu-row .label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
/* 行尾的快捷键提示（Settings 的 Ctrl+⇧+,）。字号比正文小一档、颜色压灰，
   靠右贴边 —— 它是"顺带告诉你"，不该跟左边的标签抢注意力。
   white-space:nowrap 是必须的：里面有 + 号，窄一点就会从加号处折行。 */
.menu-row .hint{
  color:var(--text-muted);font-size:12px;letter-spacing:.02em;
  white-space:nowrap;flex:none;padding-left:12px;
}
.menu-row .caret-ic{display:flex;color:var(--text-muted);}

@media (max-width:520px){.account-menu{min-width:0;width:calc(100vw - 24px);}}

.scrim{
  position:fixed;inset:0;z-index:20;
  background:rgba(0,0,0,.4);
  opacity:0;pointer-events:none;
  transition:opacity .3s var(--ease);
}

/* 设置窗口里的 Motion 开关。关掉之后全站过渡与动画停下 ——
   和系统的 prefers-reduced-motion 是一个效果，只是这个由用户在应用内决定。
   不写 animation:none：有些等待指示器只有动起来才有意义，压成极短的时长
   （0.01ms）能让它们仍然"走完一轮"，而不是卡在第一帧上。 */
html[data-motion="off"] *,
html[data-motion="off"] *::before,
html[data-motion="off"] *::after{
  animation-duration:.01ms !important;
  animation-iteration-count:1 !important;
  transition-duration:.01ms !important;
  scroll-behavior:auto !important;
}

/* ============================================================
   设置窗口的遮罩
   ============================================================
   窗口本身在 settings.html 里，这一段只管"它浮在什么上面"。

   模糊用 backdrop-filter 挂在遮罩上，而不是给 .app 加 filter：
     · filter 会给 .app 建一个新的包含块，它里面所有 position:fixed 的东西
       （侧栏在窄屏下就是 fixed、还有右下角那个回到底部按钮）会当场错位；
     · backdrop-filter 只影响"画在这一层后面的像素"，DOM 一点不动。
   老浏览器不支持 backdrop-filter 的话，@supports 里那条回退让底色更实一点 ——
   模糊没了，但"后面那层不可点、被压暗"这件事仍然成立。 */
.settings-overlay{
  position:fixed;inset:0;z-index:62;
  display:none;
  /* 模糊只要一点点。14px 那一档等于把后面整个界面糊成一片色块，
     "我刚才在哪条对话上"这个信息全没了 —— 而弹窗是临时的，退出来还得接着看。
     4px 刚好够把后面推远一层、又认得出原来是什么。压暗也跟着收一档，
     真正把两层分开的是弹窗自己的阴影，不是把背景涂黑。 */
  background:rgba(20,19,18,.20);
  backdrop-filter:blur(4px);
  -webkit-backdrop-filter:blur(4px);
  animation:settings-fade .18s var(--ease);
}
[data-theme="dark"] .settings-overlay{background:rgba(0,0,0,.36);}
.settings-overlay[data-open="true"]{display:block;}
.settings-overlay > iframe{
  width:100%;height:100%;border:0;display:block;
  background:transparent;color-scheme:normal;
}
@keyframes settings-fade{from{opacity:0}to{opacity:1}}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .settings-overlay{background:rgba(20,19,18,.48);}
  [data-theme="dark"] .settings-overlay{background:rgba(0,0,0,.6);}
}
@media (prefers-reduced-motion:reduce){.settings-overlay{animation:none;}}

/* 对话框（登录 / 设置） */
.overlay{
  position:fixed;inset:0;z-index:60;
  display:none;place-items:center;padding:22px;
  background:rgba(20,19,18,.42);
}
.overlay[data-open="true"]{display:grid;}
.sheet{
  width:min(480px,100%);max-height:88vh;overflow:auto;
  background:var(--bg-pop);border:1px solid var(--border);
  border-radius:18px;box-shadow:var(--shadow-pop);
  padding:26px 26px 22px;
}
.sheet h3{font-family:var(--font-serif);font-size:24px;font-weight:400;
  letter-spacing:-.02em;color:var(--text-strong);margin:0 0 6px;}
.sheet .lead{color:var(--text-muted);font-size:13.5px;margin:0 0 20px;}
.field{margin-bottom:16px;}
.field label{display:block;margin-bottom:6px;font-size:13.5px;font-weight:500;color:var(--text-strong);}
.field .hint{color:var(--text-faint);font-size:12px;margin-top:5px;}
.inp{
  width:100%;padding:9px 12px;border-radius:var(--radius-md);
  border:1px solid var(--border-strong);background:var(--bg-composer);
  color:var(--text-strong);font-size:14px;outline:0;
  transition:border-color .15s;
}
.inp:focus{border-color:var(--text-faint);}
/* 长期档案的编辑框：等宽、可纵向拉伸、行高松一点，方便逐条读 */
textarea.inp{resize:vertical;line-height:1.55;min-height:120px;}
/* 弹窗内容多了之后要能滚，否则小屏上按钮被顶到视口外面点不着 */
.sheet{max-height:88vh;overflow:auto;}
.sheet-actions{display:flex;justify-content:flex-end;gap:8px;margin-top:4px;}
.btn{
  padding:8px 16px;border-radius:var(--radius-md);
  border:1px solid var(--border-strong);color:var(--text-strong);
  font-size:13.5px;font-weight:500;transition:background .15s;
}
.btn:hover{background:var(--bg-hover);}
.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff;}
.btn.primary:hover{filter:brightness(1.06);background:var(--accent);}

/* 登录 */
#gate{position:fixed;inset:0;z-index:70;display:grid;place-items:center;
  background:var(--bg-main);padding:24px;}
#gate[data-open="false"]{display:none;}
.gate-card{width:min(430px,100%);}
.gate-card .mark{display:flex;align-items:center;gap:12px;margin-bottom:22px;}
.gate-card h1{font-family:var(--font-serif);font-size:36px;font-weight:400;
  letter-spacing:-.02em;color:var(--text-strong);margin:0 0 8px;line-height:1.15;}
.gate-card p{color:var(--text-muted);font-size:14px;margin:0 0 22px;}
.gate-row{display:flex;gap:8px;}
.gate-note{margin-top:20px;padding-top:16px;border-top:1px solid var(--border);
  color:var(--text-faint);font-size:12.5px;}

.upload-warning{
  position:fixed;top:20px;right:20px;z-index:10000;
  display:flex;align-items:flex-start;gap:9px;box-sizing:border-box;
  width:max-content;max-width:min(400px,calc(100vw - 40px));
  padding:11px 13px;background:#f9dfa2;color:#74551c;
  border:1px solid #bb8e32;border-radius:10px;
  box-shadow:0 3px 12px rgba(107,77,20,.10);
  font-family:var(--font-latin), var(--font-sans);font-optical-sizing:none;
  font-size:13.5px;line-height:1.45;
}
.upload-warning[hidden]{display:none;}
.upload-warning-icon{width:18px;height:18px;flex:none;margin-top:1px;}
.upload-warning-text{min-width:0;overflow-wrap:anywhere;}
.upload-warning-close{
  display:flex;align-items:center;justify-content:center;flex:none;
  width:22px;height:22px;margin:-1px -3px 0 0;padding:3px;
  border:0;border-radius:4px;background:transparent;color:inherit;cursor:pointer;
}
.upload-warning-close svg{width:16px;height:16px;}
.upload-warning-close:hover{background:rgba(116,85,28,.1);}
[data-theme="dark"] .upload-warning-close:hover{background:#5a3b1d;}
.upload-warning-close:focus-visible{outline:2px solid currentColor;outline-offset:2px;}
@media(max-width:600px){
  .upload-warning{top:12px;right:12px;max-width:min(400px,calc(100vw - 24px));}
}

/* 拖拽 / toast */
#drop{
  --drop-blue:#2f91f7;
  position:fixed;inset:14px;z-index:65;display:none;place-items:center;
  box-sizing:border-box;overflow:hidden;pointer-events:none;
  background:rgba(16,18,20,.82);border:2px solid var(--drop-blue);
  border-radius:16px;box-shadow:0 0 30px rgba(47,145,247,.12);
  color:#66adfa;
  backdrop-filter:blur(12px);
  -webkit-backdrop-filter:blur(12px);
}
#drop[data-on="true"]{display:grid;}
#drop .drop-content{display:flex;flex-direction:column;align-items:center;gap:14px;}
#drop .drop-icons{display:flex;align-items:center;gap:15px;}
#drop .drop-icons svg{width:34px;height:34px;stroke:currentColor;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round;}
#drop .drop-icons svg:nth-child(1){transform:rotate(-13deg);}
#drop .drop-icons svg:nth-child(3){transform:rotate(13deg);}
#drop span{font-size:18px;font-weight:500;letter-spacing:.01em;color:currentColor;}
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  #drop{background:rgba(16,18,20,.96);}
}

/* ============================================================
   6. Debug tool（可整段删除，见 script 中同名标记）
   ============================================================ */
#dbg-launch{
  position:fixed;right:18px;bottom:18px;z-index:55;
  display:flex;align-items:center;gap:7px;
  padding:7px 13px;border-radius:999px;
  background:var(--bg-pop);border:1px solid var(--border-strong);
  box-shadow:var(--shadow-pop);
  color:var(--text-muted);font-size:12.5px;font-family:var(--font-mono);
}
#dbg-launch[hidden]{display:none;}
#dbg-launch:hover{color:var(--text-strong);}
#dbg-launch .dot{width:7px;height:7px;border-radius:50%;background:var(--text-faint);}
#dbg-launch[data-live="true"] .dot{background:var(--ok);}
#dbg-launch[data-live="down"] .dot{background:var(--danger);}

#dbg-panel{
  position:fixed;right:18px;top:62px;z-index:56;
  width:330px;max-width:calc(100vw - 36px);
  background:var(--bg-pop);border:1px solid var(--border-strong);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-pop);
  overflow:hidden;
}
#dbg-panel[hidden]{display:none;}
.dbg-head{
  display:flex;align-items:center;gap:8px;
  padding:9px 8px 9px 14px;border-bottom:1px solid var(--border);
}
.dbg-head .t{flex:1;font-family:var(--font-mono);font-size:11px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--text-muted);}
#dbg-panel[data-collapsed="true"] .dbg-body{display:none;}
#dbg-panel[data-collapsed="true"] .dbg-head{border-bottom:0;}
#dbg-panel[data-collapsed="true"] .dbg-chev{transform:rotate(180deg);}
.dbg-chev{transition:transform .18s var(--ease);}
/* 面板整体做成 flex 列，高度由视口决定 —— 原来 .dbg-body 一个 max-height:62vh
   加 overflow:auto，里面又嵌了一个 max-height:260px 的 .dbg-log，
   两层滚动区抢同一份空间：上面的状态块一多，留给日志的高度就被挤没了，
   看起来就像日志被上面那排按钮压住。改成只保留一个可伸缩的滚动区（日志）。*/
#dbg-panel{display:flex;flex-direction:column;max-height:calc(100vh - 80px);}
.dbg-body{
  padding:14px;display:flex;flex-direction:column;gap:14px;
  flex:1;min-height:0;overflow:auto;
}
/* 状态块和按钮行按内容占高，不参与压缩 —— 它们被压扁才是"挡住"的真正来源 */
.dbg-body > .dbg-block{flex:none;}
.dbg-block{display:flex;flex-direction:column;gap:6px;}
.dbg-connection{margin:0;padding-bottom:12px;border-bottom:1px solid var(--border);}
.dbg-connection label{font-size:12px;color:var(--text-muted);}
.dbg-connection .inp{width:100%;min-width:0;padding:7px 8px;font-size:12px;line-height:18px;border-radius:6px;}
.dbg-connection-hint{margin:2px 0;font-size:11px;line-height:16px;color:var(--text-faint);}
.dbg-connection-actions{display:flex;gap:8px;margin-top:3px;}
.dbg-connection-status{font-size:11px;line-height:16px;color:var(--text-muted);}
.dbg-connection-status:empty{display:none;}
.dbg-row{display:flex;justify-content:space-between;align-items:center;gap:8px;
  font-family:var(--font-mono);font-size:11px;color:var(--text-muted);}
.dbg-row b{color:var(--text-strong);font-weight:500;word-break:break-all;text-align:right;}
.dbg-eyebrow{font-family:var(--font-mono);font-size:10px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--text-faint);display:flex;
  justify-content:space-between;align-items:center;}
.dbg-bar{height:3px;border-radius:2px;background:var(--bg-hover);overflow:hidden;}
.dbg-bar i{display:block;height:100%;width:0;background:var(--ok);transition:width .8s linear;}
.dbg-bar[data-level="low"] i{background:var(--accent);}
.dbg-bar[data-level="dead"] i{background:var(--danger);}
.dbg-mini[data-on="true"]{color:var(--danger);border-color:var(--danger);}
.dbg-mini{
  padding:3px 9px;border-radius:var(--radius-sm);border:1px solid var(--border-strong);
  font-size:11.5px;color:var(--text-muted);
}
.dbg-mini:hover{background:var(--bg-hover);color:var(--text-strong);}
.dbg-mini:disabled{opacity:.45;cursor:default;}
/* 按钮行常驻在日志上方：日志滚动时按钮不跟着跑掉，也不会盖住内容
   —— 给足背景色和上下留白，避免半透明重叠看起来像"压住了" */
.dbg-actions{
  display:flex;gap:8px;flex:none;flex-wrap:wrap;
  position:sticky;top:-14px;z-index:2;
  background:var(--bg-pop);padding:8px 0 8px;
  border-bottom:1px solid var(--border);
}
.dbg-actions .dbg-mini{flex:1 1 calc(33.333% - 8px);text-align:center;}
.dbg-files{display:flex;flex-direction:column;gap:1px;max-height:180px;overflow:auto;flex:none;}
.dbg-files .file-link{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:5px 7px;border-radius:var(--radius-sm);
  font-family:var(--font-mono);font-size:11px;color:var(--text);
  text-align:left;transition:background .15s;
}
.dbg-files .file-link:hover{background:var(--bg-hover);}
.dbg-files .nm{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.dbg-files .sz{color:var(--text-faint);flex:none;}
.dbg-files .none{font-size:11px;color:var(--text-faint);font-family:var(--font-mono);}
.dbg-log{
  font-family:var(--font-mono);font-size:10.5px;line-height:1.55;
  color:var(--text-faint);
  /* 不再设 max-height：由 .dbg-body 统一滚动，日志想多长有多长。
     min-height 保证哪怕上面的状态块很多，日志也留得下几行可读区域。*/
  flex:1 1 auto;min-height:120px;
  padding-top:4px;
}
/* 不再 nowrap+ellipsis：这里最有用的恰恰是被省略号吃掉的那部分
   （intent 文本、每请求的 read/write）。换行显示，宁可占地方。 */
.dbg-log div{white-space:pre-wrap;word-break:break-word;padding:1px 0;}
.dbg-log .t{color:var(--text-faint);opacity:.55;}
.dbg-log .slow{color:var(--warn,#c98a2b);}      /* 耗时突出的一步 */
.dbg-log .err{color:var(--danger,#c0392b);}
.dbg-log .miss{color:var(--danger,#c0392b);}    /* 该命中却没命中的请求 */
.dbg-log .intent{color:var(--text);}
.dbg-log .rd{opacity:.75;}
/* 推理行：一轮只有一条，就地更新字数和耗时。压暗是刻意的 ——
   它是背景噪声，工具时间线才是主角；但耗时超过 30s 会被改成 .miss 提亮。 */
.dbg-log .think{opacity:.5;font-style:italic;}

/* ============================================================
   7. 响应式
   ============================================================ */
@media (max-width:1023px){
  .sidebar{position:fixed;inset:0 auto 0 0;z-index:30;box-shadow:var(--shadow-pop);}
  .app[data-sidebar="closed"] .sidebar{margin-left:calc(var(--sidebar-w) * -1);}
  .app[data-sidebar="open"] .scrim{opacity:1;pointer-events:auto;}
  .rail-btn{display:grid !important;}
  .greeting{font-size:40px;}
  /* 窄屏下内收没有意义，空间本来就紧 */
  :root{--col-max:740px;}
}
@media (max-width:767px){
  .greeting{font-size:36px;gap:6px;}
  .spark{width:26px;height:26px;}
  .feed{padding:6px 14px 8px;}
  .composer-dock{padding:0 24px 8px;}
  /* 窄屏框窄，圆角跟着收一档；宽屏的 18px 按到小尺寸上偏圆。
     边框粗细和阴影是全局的，这里不用再写。 */
  .composer{padding:8px 10px;border-radius:14px;}
  .composer-input{font-size:16px;}
  .composer-row{gap:6px;}
  .composer-footer{padding-inline:4px;}
  /* 模型名在宽屏是 14px，这里跟着整体收一档；不写的话 .model-btn b 的
     font-size:14px 会在 12.5px 的"Medium"旁边显得突兀 */
  .model-btn{font-size:12.5px;padding:5px 6px;}
  .model-btn b{font-size:13px;}
  .topbar{padding:10px 12px;min-height:48px;}
  .chat-title{max-width:40vw;}
  .turn.me .bubble{max-width:88%;}
  #dbg-panel{width:calc(100vw - 24px);right:12px;top:56px;}
}
@media (max-height:600px){
  .main[data-mode="empty"] .greet-wrap{padding-bottom:18px;}
  .greeting{font-size:34px;}
}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{transition-duration:.01ms !important;animation-duration:.01ms !important;}
}

/* ---- 登录页：邮件链接态 ---------------------------------------------- */
.gate-sent{margin-top:20px;padding:16px 18px;border:1px solid var(--border);
  border-radius:12px;background:var(--bg-subtle,rgba(0,0,0,.02));}
.gate-sent-title{font-size:14px;font-weight:500;margin-bottom:6px;}
.gate-sent-note{font-size:13px;line-height:1.6;color:var(--text-muted);margin:0 0 12px;}
.gate-devlink{display:block;font-size:12px;line-height:1.5;word-break:break-all;
  color:var(--accent,#c96442);margin:0 0 12px;}
.gate-dev{margin-top:20px;padding-top:16px;border-top:1px solid var(--border);}
.gate-dev .gate-row{margin-top:10px;}
.btn.sm{padding:5px 12px;font-size:13px;}
/* 侧边栏会话条目：只有标题一行。.recent-meta 那条规则连同它渲染的那行小字
   一起去掉了 —— 时间和条数现在只在 title 属性（悬停提示）里。 */
.recent-item .recent-title{display:block;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;}

/* 历史窗口：顶部的"加载更早的记录" */
.earlier{display:flex;justify-content:center;padding:12px 0 4px;}
.earlier .btn{font-size:12px;color:var(--text-muted);}


#dbg-launch[hidden]{display:none!important}
