/* ai-chat-composer.css
   ==================================
   Composer Pill
   - pill: visual container
   - attachments: draft previews (big)
   - row: fixed 48px input line
   ================================== */

/* =========================
   🚀 CRITICAL: First Paint Anti-FOUC
   ========================= */
.composer-initializing,
.composer-initializing *,
.composer-initializing *::before,
.composer-initializing *::after {
  transition: none !important;
  animation: none !important;
}

/* =========================
   Globals
   ========================= */
:root{
  --input-offset: 56px;   /* 左侧 + / 右侧 send 需要的留白 */
}

/* =========================
   Input wrapper (only width + centering)
   ========================= */
.input-wrapper{
  display: flex;
  width: 85%;
  max-width: 700px;
  padding: 10px 0;
  margin: 0 auto;
}

/* =========================
   Composer pill (the real "input box")
   ========================= */
.composer-pill{
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;

  border: 1px solid var(--color-border);
  border-radius: var(--composer-pill-radius);
  corner-shape: round;
  background: var(--color-bg-panel);

  box-shadow: var(--composer-pill-shadow);
  transition: box-shadow 0.3s ease-in-out;
}

.composer-pill:focus-within{
  box-shadow: 0 2px 8px rgba(32, 33, 36, 0.35);
}

/* =========================
   Attachments row (draft previews inside pill)
   - ChatGPT-like: bigger thumbnails
   ========================= */
.composer-attachments{
  display: none;
  gap: 7px;

  /* pill 内部，与 + 按钮对齐 */
  padding: 7px 7px 6px 7px;

  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;

}
/* Hidden horizontal strip inside the pill (the attachments row, the chips area): scrolls sideways, shows no bar.
   One class, one rule - the pill's single deliberate exception to .duo-scroll; the scrollbar gate counts private rules. */
.composer-strip { scrollbar-width: none; -ms-overflow-style: none; }
.composer-strip::-webkit-scrollbar {
  height: 0;
  width: 0;
  display: none;
}

.composer-attachments.show{
  display: flex;
}

/* ✅ Bigger chip */
.attachment-chip{
  position: relative;
  width: 52px;
  height: 52px;

  border-radius: 18px;
  /* 注：原本这里是 overflow: hidden 用于裁切图片圆角，但会把 tooltip ::before 也裁掉。
     改用 img 自己的 border-radius: inherit 来裁圆角，chip 留 overflow: visible 让 tooltip 能溢出。 */

  background: #f3f3f3;
  flex: 0 0 auto;
  cursor: pointer; /* 鼠标变手指（图片 + 文件 chip 共用） */
}

.attachment-chip img{
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: inherit; corner-shape: inherit; /* 接管原本由 chip overflow:hidden 提供的圆角裁切 */
  transition: opacity 0.15s ease;
}
/* ── 图片 chip hover：图片轻微变暗（CLAUDE.md 5.3 规则 6：禁止抬升/阴影，只用原地效果） ── */
html:not([data-input="touch"]) .attachment-chip:hover img{
  opacity: 0.82;
}
.attachment-chip:active img {
  opacity: 0.82;
}

/* ✅ Single image: larger thumbnail */
.composer-attachments.is-1 .attachment-chip{
  width: 150px;
  height: 150px;
  border-radius: calc(18px * var(--corner-k));
}

/* The remove mark inside the 18px chip button keeps its own 8px: it is a mark, not one of the two icon sizes */
.attachment-remove svg { width: 8px; height: 8px; }
/* ✅ X: black bg + white text (clear) */
.attachment-remove{
  position: absolute;
  top: 7px;
  right: 7px;

  width: 18px;
  height: 18px;
  border-radius: 999px;
  corner-shape: round;
  padding: 0;

  border: none;
  background: #000;
  color: #fff;

  font-size: 0;
  line-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;

  cursor: pointer;
  opacity: 1;

  transition:
    opacity .12s ease,
    transform .12s ease;
}

/* ✅ Edit button: black bg, next to remove button (first image only) */
.attachment-edit{
  position: absolute;
  top: 7px;
  right: 29px; /* 7px + 18px + 4px gap */

  width: 18px;
  height: 18px;
  border-radius: 999px;
  corner-shape: round;
  padding: 0;

  border: none;
  background: #000;
  color: #fff;

  font-size: 0;
  line-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;

  cursor: pointer;
  opacity: 1;

  transition:
    opacity .12s ease,
    transform .12s ease;
}

.attachment-edit svg{
  width: 12px;
  height: 12px;
  display: block;
}
html:not([data-input="touch"]) .attachment-edit:hover{
  opacity: 1;
}

/* ✅ X icon position adjustment */
.attachment-remove-icon{
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 0;
}
html:not([data-input="touch"]) .attachment-remove:hover{
  opacity: 1;
}

/* =========================
   Composer row (the typing line)
   - min 48px, expands with textarea
   ========================= */
.composer-row{
  position: relative;
  display: flex;
  align-items: flex-end;

  min-height: 48px;
}

/* =========================
   Textarea (base)
   - Base style is shared
   - The *row* version locks 48px and centers text
   ========================= */
.chat-input{
  box-sizing: border-box;
  width: 100%;

  /* 左右留 offset：左给 +，右给 send */
  padding-left: var(--input-offset);
  padding-right: var(--input-offset);

  border: none;
  outline: none;
  background: transparent;
  color: #000;

  font-size: 14px;
  resize: none;
}

/* ✅ Expandable textarea (min 48px, grows up to 245px via JS) */
.composer-row .chat-input{
  min-height: 48px;

  padding-top: 14px;
  padding-bottom: 14px;

  line-height: 1.4;
  overflow-y: hidden;  /* JS controls this based on scrollHeight */
}

/* scrollbar：composer 输入框专属特化（有意例外，不走 .duo-scroll 模板）——
   8px + box-shadow inset 轨道把滚动条藏进圆角输入背景 + 实色 thumb，是刻意的视觉需求 */
.chat-input::-webkit-scrollbar{ width: 8px; }
.chat-input::-webkit-scrollbar-track{
  background: var(--color-bg-panel);
  box-shadow: inset 0px 49px 0 0 var(--color-bg-panel);
}
.chat-input::-webkit-scrollbar-thumb{
  background-color: #ececec;
  border-radius: calc(4px * var(--corner-k));
}
.chat-input::-webkit-scrollbar-button{ display: block; }

/* =========================
   Typing placeholder (inside row)
   ========================= */
.typing-placeholder{
  position: absolute;
  left: var(--input-offset);
  bottom: 13px;

  font-size: 14px;
  color: #888;
  pointer-events: none;
  /* Decoration, same rule as a native placeholder: iOS long-press selection ignores
     pointer-events and could grab this text (Copy menu over the composer). */
  -webkit-user-select: none;
  user-select: none;

  white-space: nowrap;
  overflow: hidden;
}

/* =========================
   Send button (inside pill) — FIXED UX
   ========================= */
.chat-button{
  position: absolute;
  right: 7px;
  bottom: 7px;

  width: 34px;
  height: 34px;

  background: transparent;
  border-radius: 999px;
  corner-shape: round;
  border: none;

  display: flex;
  align-items: center;
  justify-content: center;

  cursor: pointer;

  /* ✅ 不再用 filter + 位移制造"别扭感" */
  transition: opacity .16s ease;
}

/* ✅ 默认：空输入时弱一点（灰），像“不可发送” */
.chat-button .send-bg{ fill: #a8a8a8; }

/* ✅ 有输入：变黑（可发送） */
.chat-button.has-text .send-bg{ fill: #000; }
/* ✅ Hover：空输入时变深一点（更合理：鼠标放上去才变深/变亮） */
html:not([data-input="touch"]) .chat-button:hover .send-bg{ fill: #8c8c8c; }
html:not([data-input="touch"]) .chat-button.has-text:hover .send-bg{ fill: #111; }

/* ✅ Generating/Stop：保持强态（黑），并禁用 hover 效果 */
.chat-button.is-generating .send-bg{ fill: #000; }
html:not([data-input="touch"]) .chat-button.is-generating:hover .send-bg{ fill: #000; }

/* ✅ 中止叠加层：圆角方块 ■，与纸飞机同色显示在黑圆底上。
   默认隐藏；生成中且输入为空(.is-stop)时显示并隐藏纸飞机（替换旧的 rotate 90° “一横”） */
.chat-button-stop{
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  color: #fff;
  pointer-events: none;
}
/* 多加一层 .chat-button 提高优先级：否则与下方 .chat-button svg{width:34px} 同优先级、
   且那条在后面会赢，把停止方块撑成 34px 满按钮白块。rect 满画布(0-24) → 可见方块=svg=4px（比原~5px 小 20%，取整）*/
.chat-button .chat-button-stop svg{ width: 12px; height: 12px; display: block; }
.chat-button.is-stop .send-plane{ opacity: 0; }
.chat-button.is-stop .chat-button-stop{ display: flex; }
/* ✅ agent 中止：柔和中性灰圆底（比生成态纯黑更协调、不刺眼）+ 白方块 */
.chat-button.is-stop .send-bg{ fill: #8c8c8c; }

/* SVG 显示 34x34（视觉圆为 34） */
.chat-button svg{
  width: 34px;
  height: 34px;
  display: block;
}
.chat-button .send-bg{
  rx: 17;
  ry: 17;
}

/* =========================
   Minor keeps
   ========================= */
.logo-svg-1{
  height: 0.74em;
  width: auto;
  transform: translateY(-0.4px);
}

.loading{
  font-size: 16px;
  color: #555;
}

/* =========================
   Mobile Keyboard / Floating Composer
   ========================= */
@media (max-width: 768px), (max-height: 500px) {
  /* Remove top border from the pill on mobile (merged from ai-chat-mobile-keyboard.css) */
  .composer-pill { border-top: none; }
  /* pill 铺满 bar:桌面的 85%/700px 上限在手机上就是那圈多出来的边 */
  .input-wrapper { width: 100%; max-width: none; }

  /* 1. Make the composer bar float at the bottom */
  .composer-bar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    z-index: 20; /* Ensure it's above chat messages */
    background-color: var(--color-bg-panel);

    /* Add padding for iOS Home Indicator */
    padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px));
    /* Phone main input: pill sits 5px inside the bubble line (owner 2026-08-27: 1rem read too wide).
       The pull-up select card (.plus-menu) anchors to the pill left edge, so it follows by itself. */
    padding-left: calc(1rem + 5px);
    padding-right: calc(1rem + 5px);
    border-top: 1px solid var(--color-bg-panel);
  }

  /* ✅ Welcome page: composer stays in flow so it centers with welcome text
     键盘弹出时 100dvh（在 ai-chat-base.css .ai-design-section）自动收缩，
     justify-content:center 重新居中到可见区域，不需要额外 fixed */
  .chat-container:not(.has-messages) .composer-bar {
    position: relative;
    bottom: auto;
    left: auto;
    right: auto;
    width: auto;
    z-index: auto;
    background-color: transparent;
    padding-bottom: 0;
    border-top: none;
  }

  /* ✅ Project view composer: NOT fixed, stays inline like desktop */
  .project-composer-bar.composer-bar {
    position: relative;
    bottom: auto;
    left: auto;
    right: auto;
    width: auto;
    z-index: auto;
    background-color: transparent;
    padding-bottom: 0;
    border-top: none;
  }

  /* ✅ Images editor composer: NOT fixed, stays inline */
  .images-composer-bar.composer-bar {
    position: relative;
    bottom: auto;
    left: auto;
    right: auto;
    width: auto;
    z-index: auto;
    background-color: transparent;
    padding-bottom: 0;
    border-top: none;
  }

  /* 2. Add padding to message list so content isn't hidden behind composer */
  /* Estimated composer height ~100px + safe area */
  /* ★只留给【输入框贴屏幕底】的那个列表 = 主聊天(.chat-container 里那个)。
     会议室/项目页上面刚把自己的 composer 改回 relative、排进文档流,再留这一截就是纯占位;
     而 padding 是压不掉的(flex 只能压内容盒)—— 在定高的 sheet 里它会把输入框整个顶出屏幕
     (owner 2026-08-10 手机横屏实拍:sheet 294 装 56+204+69=329,输入框冲出 35px 且滚不动)。
     "取消 fixed"与"取消留位"必须成对,别再让它们分家。 */
  /* 156 = the old 120 + 36: the pill grew from one 48px line to 40 + 36 + 8 (two tiers), the breathing room stays */
  .chat-container .chat-messages {
    padding-bottom: calc(156px + env(safe-area-inset-bottom, 0px));
  }
}

/* =========================
   Plus Menu Divider & Check
   ========================= */
.plus-menu__divider {
  height: 1px;
  background: #e5e5e5;
  margin: 6px -6px;   /* full-bleed: cancels the menu's 6px padding */
}

.plus-menu__item {
  position: relative;
}

.plus-menu__check {
  display: none;
  position: absolute;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  color: #C9B27C;
  line-height: 0;
}

.plus-menu__item.active .plus-menu__check {
  display: flex;
  align-items: center;
}

/* ✅ 选中状态：文字和图标变色（通过 color + currentColor 继承） */
.plus-menu__item.active .plus-menu__icon,
.plus-menu__item.active .plus-menu__label {
  color: #C9B27C;
}

/* =========================
   Judgement Mode: menu button selected (green)
   ========================= */
#menuJudgementBtn.active .plus-menu__icon,
#menuJudgementBtn.active .plus-menu__label {
  color: #059669;
}

#menuJudgementBtn.active .plus-menu__icon svg {
  fill: #059669;
}

#menuJudgementBtn.active .plus-menu__check {
  color: #059669;
}

#menuJudgementBtn.active .plus-menu__check svg {
  stroke: #059669;
}

/* project composer */
#projectMenuJudgementBtn.active .plus-menu__icon,
#projectMenuJudgementBtn.active .plus-menu__label {
  color: #059669;
}

#projectMenuJudgementBtn.active .plus-menu__icon svg {
  fill: #059669;
}

#projectMenuJudgementBtn.active .plus-menu__check {
  color: #059669;
}

#projectMenuJudgementBtn.active .plus-menu__check svg {
  stroke: #059669;
}

/* =========================
   Agent Mode: menu button selected (violet)
   ========================= */
#menuAgentBtn.active .plus-menu__icon,
#menuAgentBtn.active .plus-menu__label {
  color: #7c3aed;
}

#menuAgentBtn.active .plus-menu__icon svg {
  fill: #7c3aed;
}

#menuAgentBtn.active .plus-menu__check {
  color: #7c3aed;
}

#menuAgentBtn.active .plus-menu__check svg {
  stroke: #7c3aed;
}

/* project composer */
#projectMenuAgentBtn.active .plus-menu__icon,
#projectMenuAgentBtn.active .plus-menu__label {
  color: #7c3aed;
}

#projectMenuAgentBtn.active .plus-menu__icon svg {
  fill: #7c3aed;
}

#projectMenuAgentBtn.active .plus-menu__check {
  color: #7c3aed;
}

#projectMenuAgentBtn.active .plus-menu__check svg {
  stroke: #7c3aed;
}

/* =========================
   Judgement Mode Chip (base styles)
   ========================= */
.judgement-mode-chip {
  display: none;
  align-items: center;
  gap: 8px;
  background: transparent;
  color: #059669;
  cursor: pointer;
  transition: all 0.15s ease;
}

.judgement-mode-chip.active {
  display: inline-flex;
}
html:not([data-input="touch"]) .judgement-mode-chip:hover{
  background: #ecfdf5;
}

.judgement-mode-chip__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  position: relative;
  cursor: pointer;
  border-radius: 50%;
  corner-shape: round;
  transition: background 0.1s ease;
}

.judgement-mode-chip__icon svg {
  width: 24px;
  height: 24px;
}

.judgement-mode-chip__icon-judge {
  display: flex;
  align-items: center;
  justify-content: center;
}

.judgement-mode-chip__icon-close {
  display: none;
  align-items: center;
  justify-content: center;
}

/* ★单一真源:四个模式 chip(Image/Search/判断/Agent)删除 × 图标尺寸(仅桌面 hover 显示;手机无 hover=不显 ×)。
   带父级 __icon 抬高特异性(0,2,1)→ 永远压过给模式图标的 .X__icon svg{24}(0,1,1),不受排序影响 —— 改这一处即全变 */
.image-mode-chip__icon .image-mode-chip__icon-close svg,
.search-mode-chip__icon .search-mode-chip__icon-close svg,
.judgement-mode-chip__icon .judgement-mode-chip__icon-close svg,
.agent-mode-chip__icon .agent-mode-chip__icon-close svg {
  width: 12px;
  height: 12px;
}
/* ★ hover 换成 × 只在真 hover 设备(触屏点一下会误触发 :hover → 手机冒出 ×);触屏靠点胶囊关闭,不显 × */
html:not([data-input="touch"]) .judgement-mode-chip:hover .judgement-mode-chip__icon-judge{ display: none; }
html:not([data-input="touch"]) .judgement-mode-chip:hover .judgement-mode-chip__icon-close{ display: flex; }
html:not([data-input="touch"]) .judgement-mode-chip:hover .judgement-mode-chip__icon{ background: rgba(5, 150, 105, 0.25); }

.judgement-mode-chip__label {
  font-weight: 500;
  white-space: nowrap;
}

/* =========================
   Agent Mode Chip (base styles) — violet
   ========================= */
.agent-mode-chip {
  display: none;
  align-items: center;
  gap: 8px;
  background: transparent;
  color: #7c3aed;
  cursor: pointer;
  transition: all 0.15s ease;
}

.agent-mode-chip.active {
  display: inline-flex;
}
html:not([data-input="touch"]) .agent-mode-chip:hover{
  background: #f5f3ff;
}

.agent-mode-chip__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  position: relative;
  cursor: pointer;
  border-radius: 50%;
  corner-shape: round;
  transition: background 0.1s ease;
}

.agent-mode-chip__icon svg {
  width: 24px;
  height: 24px;
}

.agent-mode-chip__icon-agent {
  display: flex;
  align-items: center;
  justify-content: center;
}

.agent-mode-chip__icon-close {
  display: none;
  align-items: center;
  justify-content: center;
}
html:not([data-input="touch"]) .agent-mode-chip:hover .agent-mode-chip__icon-agent{ display: none; }
html:not([data-input="touch"]) .agent-mode-chip:hover .agent-mode-chip__icon-close{ display: flex; }
html:not([data-input="touch"]) .agent-mode-chip:hover .agent-mode-chip__icon{ background: rgba(124, 58, 237, 0.25); }

.agent-mode-chip__label {
  font-weight: 500;
  white-space: nowrap;
}

/* =========================
   Image Mode Chip (base styles)
   ========================= */
.image-mode-chip {
  /* 默认隐藏 */
  display: none;
  align-items: center;
  gap: 8px;

  background: transparent;

  color: #C9B27C;

  cursor: pointer;
  transition: all 0.15s ease;
}

/* ✅ 激活时显示 */
.image-mode-chip.active {
  display: inline-flex;
}
html:not([data-input="touch"]) .image-mode-chip:hover{
  background: #FAF6ED;
}

/* ✅ 图标容器 */
.image-mode-chip__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  position: relative;
  cursor: pointer;
  border-radius: 50%;
  corner-shape: round;
  transition: background 0.1s ease;
}

.image-mode-chip__icon svg {
  width: 24px;
  height: 24px;
  stroke: currentColor;
  fill: none;
}

/* ✅ 图标切换：默认显示 image，hover 显示 close */
.image-mode-chip__icon-image {
  display: flex;
  align-items: center;
  justify-content: center;
}

.image-mode-chip__icon-close {
  display: none;
  align-items: center;
  justify-content: center;
}
/* ✅ Hover 时切换图标 */
html:not([data-input="touch"]) .image-mode-chip:hover .image-mode-chip__icon-image{ display: none; }
html:not([data-input="touch"]) .image-mode-chip:hover .image-mode-chip__icon-close{ display: flex; }
html:not([data-input="touch"]) .image-mode-chip:hover .image-mode-chip__icon{ background: rgba(201, 178, 124, 0.25); }

/* ✅ 文字 */
.image-mode-chip__label {
  font-weight: 500;
  white-space: nowrap;
}

/* =========================
   Two tiers, always (owner 2026-09-06): the text on top, the controls below.
   - Top: textarea, full width
   - Bottom: + button, the mode chip(s), send button
   The rows the markup layer clones for image notes (composer-pill > composer-row > plus-button | chat-input | plus-button)
   carry no .composer-tools-row, so the anatomy itself is the switch: those keep the one-line layout above.
   ========================= */
.composer-row:has(.composer-tools-row) {
  display: flex;
  flex-direction: column;
  min-height: auto;
  padding-bottom: 8px;
}

/* Textarea: full width, its own side padding (no room has to be kept for the buttons any more) */
.composer-row:has(.composer-tools-row) .chat-input {
  order: 1;
  padding-left: 16px;
  padding-right: 16px;
  padding-bottom: 8px;
  /* The resting height of the box, and the ONLY place it is stated: the textarea helper no longer stamps its own
     copy, so what is written here is what the first painted frame shows. 40 was never on screen - JS made it 48. */
  min-height: 48px;
}

.composer-row:has(.composer-tools-row) .typing-placeholder {
  left: 16px;
  bottom: auto;
  top: 14px;
}

/* Controls tier: the pill family's height (= the + circle, 34px); + and send are both 34, so they centre by themselves */
.composer-row:has(.composer-tools-row) .composer-tools-row {
  display: flex;
  align-items: center;
  align-self: stretch;
  gap: 8px;   /* + to pill and pill to pill (owner 2026-09-06: wider than the chips' inner 4) */
  order: 2;
  height: var(--tier-pill-h);
  padding: 0 7px;
}

.composer-row:has(.composer-tools-row) .composer-tools-row .plus-button {
  position: static;
  flex-shrink: 0;
}

/* Send: a flow item at the end of the controls tier (owner 2026-09-06) - it was absolute and the chips ran under it on a phone.
   relative, not static: it still queues in the flow, and it stays the positioned ancestor its own overlay needs -
   .chat-button-stop is inset:0 inside it, and under static that square spread across the whole pill instead. */
.composer-row:has(.composer-tools-row) .chat-button { position: relative; inset: auto; flex-shrink: 0; }

/* =========================
   Controls-tier pill family (owner 2026-09-06): the model pick and every mode chip (image / search / judgement /
   agent) are one pill - the + circle's height (34px = .composer-row .plus-button in ai-chat-plus-upload.css), a
   hairline border, one font, the same on every screen. Each chip keeps its own colours; only the geometry lives here.
   ========================= */
.composer-tools-row { --tier-pill-h: 34px; }
.composer-model, .composer-model-host { display: flex; align-items: center; }
.composer-model .settings-lang-trigger,
.image-mode-chip, .search-mode-chip, .judgement-mode-chip, .agent-mode-chip {
  box-sizing: border-box;
  height: var(--tier-pill-h);
  border: 1px solid var(--color-border);
  border-radius: calc(var(--tier-pill-h) / 2);
  corner-shape: round;
  font-size: 14px;
}
/* icon on the left: left pad = (pill - 18px icon - the two 1px borders) / 2, so the icon is 8px from the outer edge on three sides; the text side gets 12 */
.image-mode-chip, .search-mode-chip, .judgement-mode-chip, .agent-mode-chip { padding: 0 12px 0 calc((var(--tier-pill-h) - 18px - 2px) / 2); }
/* No chevron on the pill (owner 2026-09-06: narrower) - the dropdown builder always emits one, so it is hidden here for the
   mounted pills and left out of the static markup; with nothing on either side the padding is symmetric */
.composer-model .settings-lang-trigger { padding: 0 12px; color: var(--color-text); }
.composer-model .settings-lang-chevron { display: none; }
html:not([data-input="touch"]) .composer-model .settings-lang-trigger:hover,
.composer-model .settings-lang-trigger:active { background: var(--color-bg-hover); }
/* Dictation button (owner 2026-09-06): the + circle's twin, a flow item just before send */
.composer-row:has(.composer-tools-row) .composer-mic { position: static; flex-shrink: 0; }
/* Chips area between + and the two circles: takes the rest of the tier and scrolls sideways when the chips do not fit.
   A hidden strip like the attachments row: both wear .composer-strip (the one rule above). */
.composer-chips { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 8px; overflow-x: auto; }
.composer-chips > * { flex-shrink: 0; }
/* Phone: the mode chips are icon-only circles (the name is the icon's tooltip); the model pill keeps its short word */
@media (max-width: 768px), (max-height: 500px) {
  .image-mode-chip__label, .search-mode-chip__label, .judgement-mode-chip__label, .agent-mode-chip__label { display: none; }
  .image-mode-chip, .search-mode-chip, .judgement-mode-chip, .agent-mode-chip { padding: 0 calc((var(--tier-pill-h) - 18px - 2px) / 2); gap: 0; }
}
/* Dictation strip (owner 2026-09-06): while the microphone is open it covers the controls tier - cancel, the live
   waveform, accept - so the composer does not grow and the row underneath stays where it was. The two ends are the
   tier's own circles: the + button's box on the left, the send button on the right. */
.composer-dictation {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 7px;
  /* the composer's own face, so nothing of the tier reads through it */
  background: var(--color-bg-panel);
  /* the tier has no radius of its own, so inheriting it left square corners sitting 3.8px outside the composer's own
     curve at the bottom (measured 2026-09-06). The strip's bottom corners follow that curve instead. */
  border-radius: 0 0 16px 16px;
  corner-shape: inherit;
  /* above the microphone: a flex item with a z-index paints as if it were positioned even while it is static, and the
     microphone carries 20 - without this the red ring shows through the strip (measured 2026-09-06) */
  z-index: 21;
}
.composer-row:has(.composer-tools-row) .composer-tools-row { position: relative; }
/* the wave keeps its distance from both buttons (owner 2026-09-06: it ran into them) */
.composer-dictation-wave { flex: 1 1 auto; min-width: 0; height: 28px; margin: 0 8px; color: var(--color-text); }
/* Both ends are flow items of the strip. The selector has to reach three levels: .composer-row .plus-button pins
   every + circle to the row corner and lives in a sheet that loads after this one, so a two-level rule here loses the
   tie and the cancel button leaves the flow - which is what made the wave start underneath it (measured 2026-09-06). */
.composer-row .composer-dictation .composer-dictation-cancel,
.composer-row .composer-dictation .composer-dictation-accept { position: static; flex-shrink: 0; }
/* Accept is the filled twin of the + outline: same 34px circle, the page's own two colours the other way round, so it
   follows the theme instead of carrying a colour of its own. (.chat-button is transparent - the send button's disc is
   painted inside its icon, so reusing that class alone left a bare tick floating.) */
.composer-dictation-accept {
  width: 34px;
  height: 34px;
  border-radius: 999px;
  corner-shape: round;
  background: var(--color-text);
  color: var(--color-bg-panel);
}
/* Cancel is the quiet twin: the solid the site's subtle surface composites to over the strip, so it reads as a button
   in both themes instead of vanishing into a panel-coloured strip. */
.composer-dictation-cancel { background: #f0f0f0; }
.dark-mode .composer-dictation-cancel { background: #3f3f3f; }
.composer-dictation-accept svg { width: 20px; height: 20px; }
.composer-dictation-cancel svg { width: 14px; height: 14px; }
.composer-mic.is-recording { border-color: var(--color-danger); }
.composer-mic.is-recording .plus-icon { color: var(--color-danger); }
.composer-mic.is-busy { opacity: var(--dim); pointer-events: none; }

/* Two lines per option: name over its one-line description, the check spanning both */
.composer-model-menu .settings-lang-option {
  display: grid;
  grid-template-columns: 1fr auto;
  column-gap: 16px;
  row-gap: 2px;
}
.composer-model-menu .settings-lang-check { grid-column: 2; grid-row: 1 / span 2; }
.composer-model-menu .settings-model-desc { grid-column: 1; font-size: 12px; color: var(--color-text-secondary); }
/* Effort and More models (owner 2026-09-06): two rows at the foot of the menu, each opening a flyout beside it (the
   Claude-app shape: no page swap, no back header, nothing on the pill). A flyout wears the menu face; ai-chat-model-pick.js
   places it level with its row - right of the menu, left when the right has no room, over the menu on a narrow screen. */
.composer-model-menu .composer-model-nav { display: flex; align-items: center; gap: 8px; }
.composer-model-nav .settings-lang-label { flex: 1 1 auto; }
.composer-model-nav__value { font-size: 12px; color: var(--color-text-secondary); }
.composer-model-nav__chevron { display: flex; align-items: center; line-height: 0; }
.composer-model-flyout { min-width: 220px; max-width: 320px; }
.composer-model-flyout__desc { padding: 6px 16px 8px; font-size: 12px; line-height: 1.4; color: var(--color-text-secondary); }
/* flyout rows are one line: name, an optional tag, the check at the far edge */
.composer-model-flyout .settings-lang-option { display: flex; gap: 8px; }
.composer-model-flyout .settings-lang-check { margin-left: auto; }
.composer-model-badge { font-size: 11px; line-height: 1; padding: 3px 6px; border-radius: calc(6px * var(--corner-k)); background: var(--color-bg-hover); color: var(--color-text-secondary); white-space: nowrap; }
/* vendor heading over its models on the More models flyout */
.composer-model-group { padding: 10px 16px 4px; font-size: 12px; color: var(--color-text-secondary); }
/* the cost-band word (same span as Room settings' shelf) sits at the check; the studio's own padding does not apply here */
.composer-model-flyout .settings-model-price { padding: 0; }
.composer-model-flyout .settings-model-price + .settings-lang-check { margin-left: 0; }
/* Phone sheet (owner 2026-09-06, the Claude-app shape): content-high like the bench picker; cards, rows, entries and
   labels are the project settings source (the modal wears project-settings-cards). Local here: the shell's spare close
   button (the head has its own), the body's vertical padding (the cards carry the side margins), the entry row's value
   hugging its chevron, and the sub-sheet's one line of description. */
@media (max-width: 768px), (max-height: 500px) {
  .composer-model-sheet.duo-sheet { height: auto; max-height: var(--duo-sheet-h-tall); }
}
.composer-model-sheet .project-modal-close { display: none; }
.composer-model-sheet .duo-sheet-body { padding: 20px 0 40px; }
.composer-model-sheet-nav .settings-row-label { flex: 1 1 auto; text-align: left; }
/* the name takes the free width so a same-line word (a model's cost band, an entry's value) sits at the check */
.composer-model-sheet-row .settings-row-label-group { flex: 1 1 auto; }
.composer-model-sheet-row .settings-row-value, .composer-model-sheet-nav .settings-row-value { margin-right: 8px; }
.composer-model-sheet-desc { margin: 0 20px 12px; }
/* Plus menu: sits just above the controls tier, where the + button now is */
.composer-row:has(.composer-tools-row) .plus-menu {
  bottom: 44px;
}

/* ✅ Mobile adjustments */
@media (max-width: 768px), (max-height: 500px) {
  .composer-row:has(.composer-tools-row) .chat-input {
    padding-left: 14px;
    padding-right: 14px;
  }

  .composer-row.image-mode-active .typing-placeholder,
  .composer-row.search-mode-active .typing-placeholder,
  .composer-row.judgement-mode-active .typing-placeholder,
  .composer-row.agent-mode-active .typing-placeholder {
    left: 14px;
  }
}

/* =========================
   Finalized State (Read-only)
   ========================= */
.finalized-badge {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: 500;
  color: rgba(0, 0, 0, 0.45);
  padding: 4px 0;
  letter-spacing: 0.02em;
}

.composer-bar.is-finalized .composer-pill {
  background: #f5f5f5;
  border-color: #e0e0e0;
  pointer-events: none;
  opacity: var(--dim);
}

.composer-bar.is-finalized .chat-input {
  background: transparent;
  color: var(--color-text-tertiary);
  cursor: not-allowed;
}

.composer-bar.is-finalized .plus-button,
.composer-bar.is-finalized .chat-button {
  opacity: var(--dim);
  pointer-events: none;
}

.composer-bar.is-finalized .typing-placeholder {
  display: none;
}

/* =========================
   Dark mode
   ========================= */
.dark-mode .composer-pill { border-color: rgba(255,255,255,0.1); box-shadow: 0 1px 6px rgba(0,0,0,0.4); }
.dark-mode .composer-pill:focus-within { box-shadow: 0 2px 8px rgba(0,0,0,0.5); }
/* =========================
   ✅ File attachment chips — shared base (PDF/DOC/Sheet/Audio/Video/PPT/Archive/Code)
   ========================= */

/* Chip 基础布局 */
.attachment-chip-pdf, .attachment-chip-doc, .attachment-chip-spreadsheet,
.attachment-chip-audio, .attachment-chip-video, .attachment-chip-ppt,
.attachment-chip-archive, .attachment-chip-code {
  width: auto;
  height: auto;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 36px 7px 7px;
  border-radius: 18px;
  corner-shape: round;
  background: var(--color-bg-card);
  transition: background 0.15s ease;
  cursor: pointer; /* hover 时鼠标变手指，配合 title 完整文件名 tooltip */
}
/* ── 文字/文件卡片 hover（CLAUDE.md 5.3 守卫：hover 必须配 active） ── */
html:not([data-input="touch"]) .attachment-chip-pdf:hover,
html:not([data-input="touch"]) .attachment-chip-doc:hover,
html:not([data-input="touch"]) .attachment-chip-spreadsheet:hover,
html:not([data-input="touch"]) .attachment-chip-audio:hover,
html:not([data-input="touch"]) .attachment-chip-video:hover,
html:not([data-input="touch"]) .attachment-chip-ppt:hover,
html:not([data-input="touch"]) .attachment-chip-archive:hover,
html:not([data-input="touch"]) .attachment-chip-code:hover{
  background: rgba(0, 0, 0, 0.10);
}
.attachment-chip-pdf:active, .attachment-chip-doc:active, .attachment-chip-spreadsheet:active,
.attachment-chip-audio:active, .attachment-chip-video:active, .attachment-chip-ppt:active,
.attachment-chip-archive:active, .attachment-chip-code:active {
  background: rgba(0, 0, 0, 0.10);
}

/* 注：自定义 tooltip 不能用 ::before（被 .composer-attachments 的 overflow-y:hidden 裁掉），
   改用 JS 在 <body> 渲染单例 tooltip（见 ui-chat-attachments.js 中 _initTooltip）。
   样式见全局 .attachment-tooltip 规则（在本文件末尾或单独定义）。 */
.attachment-tooltip {
  position: fixed;
  background: #333;
  color: #fff;
  padding: 6px 10px;
  border-radius: calc(8px * var(--corner-k));
  font-size: 12px;
  line-height: 1.3;
  white-space: nowrap;
  max-width: 320px;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
  z-index: 99999;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s ease;
  box-shadow: 0 4px 12px rgba(0,0,0,0.18);
}
.attachment-tooltip.is-visible {
  opacity: 1;
  visibility: visible;
}
/* 暗色：纯黑底（注意 tooltip 在 body 下，用 .dark-mode-active 而非 .dark-mode） */
.dark-mode-active .attachment-tooltip {
  background: #000;
  box-shadow: 0 4px 12px rgba(0,0,0,0.5);
}
.composer-attachments.is-1 .attachment-chip-pdf,
.composer-attachments.is-1 .attachment-chip-doc,
.composer-attachments.is-1 .attachment-chip-spreadsheet,
.composer-attachments.is-1 .attachment-chip-audio,
.composer-attachments.is-1 .attachment-chip-video,
.composer-attachments.is-1 .attachment-chip-ppt,
.composer-attachments.is-1 .attachment-chip-archive,
.composer-attachments.is-1 .attachment-chip-code {
  width: auto;
  height: auto;
  border-radius: 18px;
  corner-shape: round;
}

/* 图标基础布局 */
.attachment-pdf-icon, .attachment-doc-icon, .attachment-spreadsheet-icon,
.attachment-audio-icon, .attachment-video-icon, .attachment-ppt-icon,
.attachment-archive-icon, .attachment-code-icon {
  width: 40px;
  height: 40px;
  border-radius: calc(10px * var(--corner-k));
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  color: #fff;
}
.attachment-pdf-icon svg, .attachment-doc-icon svg, .attachment-spreadsheet-icon svg,
.attachment-audio-icon svg, .attachment-video-icon svg, .attachment-ppt-icon svg,
.attachment-archive-icon svg, .attachment-code-icon svg { width: 18px; height: 18px; }
/* PDF 用官方 Adobe 标志：svg 满铺方块（与消息气泡一致），覆盖上面的 18px */
.attachment-pdf-icon svg { width: 100%; height: 100%; display: block; }

/* 图标颜色（唯一差异） */
.attachment-pdf-icon { background: #fa0f00; }   /* 官方 Adobe 红，与气泡一致 */
.attachment-doc-icon { background: #2B579A; }
.attachment-spreadsheet-icon { background: #217346; }
.attachment-audio-icon { background: #F59E0B; }
.attachment-video-icon { background: #7C3AED; }
.attachment-ppt-icon { background: #D24726; }
.attachment-archive-icon { background: #C2410C; }
.attachment-code-icon { background: #334155; }

/* 文件名 */
.attachment-pdf-name, .attachment-doc-name, .attachment-spreadsheet-name,
.attachment-audio-name, .attachment-video-name, .attachment-ppt-name,
.attachment-archive-name, .attachment-code-name {
  font-size: 12px;
  font-weight: 500;
  line-height: 1.3;
  color: var(--color-text);
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 类型标签 */
.attachment-pdf-sub, .attachment-doc-sub, .attachment-spreadsheet-sub,
.attachment-audio-sub, .attachment-video-sub, .attachment-ppt-sub,
.attachment-archive-sub, .attachment-code-sub {
  font-size: 11px;
  font-weight: 400;
  color: var(--color-text-secondary);
}

/* 删除按钮定位 */
.attachment-chip-pdf .attachment-remove, .attachment-chip-doc .attachment-remove,
.attachment-chip-spreadsheet .attachment-remove, .attachment-chip-audio .attachment-remove,
.attachment-chip-video .attachment-remove, .attachment-chip-ppt .attachment-remove,
.attachment-chip-archive .attachment-remove, .attachment-chip-code .attachment-remove {
  top: 7px;
  right: 7px;
  transform: none;
  background: #000;
}
/* 发送按钮处理中状态：禁用 */
.chat-button.is-processing {
  pointer-events: none;
  opacity: var(--dim);
}

.dark-mode .attachment-chip { background: transparent; }
.dark-mode .attachment-chip-pdf, .dark-mode .attachment-chip-doc,
.dark-mode .attachment-chip-spreadsheet, .dark-mode .attachment-chip-audio,
.dark-mode .attachment-chip-video, .dark-mode .attachment-chip-ppt,
.dark-mode .attachment-chip-archive, .dark-mode .attachment-chip-code {
  background: #000;
}
/* 暗色 hover（与亮色对应） */
html:not([data-input="touch"]) .dark-mode .attachment-chip-pdf:hover,
html:not([data-input="touch"]) .dark-mode .attachment-chip-doc:hover,
html:not([data-input="touch"]) .dark-mode .attachment-chip-spreadsheet:hover,
html:not([data-input="touch"]) .dark-mode .attachment-chip-audio:hover,
html:not([data-input="touch"]) .dark-mode .attachment-chip-video:hover,
html:not([data-input="touch"]) .dark-mode .attachment-chip-ppt:hover,
html:not([data-input="touch"]) .dark-mode .attachment-chip-archive:hover,
html:not([data-input="touch"]) .dark-mode .attachment-chip-code:hover{
  background: #1f1f1f;
}
.dark-mode .attachment-chip-pdf:active,
.dark-mode .attachment-chip-doc:active,
.dark-mode .attachment-chip-spreadsheet:active,
.dark-mode .attachment-chip-audio:active,
.dark-mode .attachment-chip-video:active,
.dark-mode .attachment-chip-ppt:active,
.dark-mode .attachment-chip-archive:active,
.dark-mode .attachment-chip-code:active {
  background: #1f1f1f;
}
.dark-mode .attachment-chip-pdf .attachment-remove, .dark-mode .attachment-chip-doc .attachment-remove,
.dark-mode .attachment-chip-spreadsheet .attachment-remove, .dark-mode .attachment-chip-audio .attachment-remove,
.dark-mode .attachment-chip-video .attachment-remove, .dark-mode .attachment-chip-ppt .attachment-remove,
.dark-mode .attachment-chip-archive .attachment-remove, .dark-mode .attachment-chip-code .attachment-remove {
  background: #555;
}
.dark-mode .chat-input { color: #e5e5e5; }
.dark-mode .chat-input::-webkit-scrollbar-thumb { background-color: rgba(255,255,255,0.15); }
.dark-mode .typing-placeholder { color: rgba(255,255,255,0.35); }
.dark-mode .chat-button .send-bg { fill: #555; }
.dark-mode .chat-button.has-text .send-bg { fill: #fff; }
html:not([data-input="touch"]) .dark-mode .chat-button:hover .send-bg{ fill: #777; }
html:not([data-input="touch"]) .dark-mode .chat-button.has-text:hover .send-bg{ fill: #eee; }
.dark-mode .chat-button.is-generating .send-bg { fill: #fff; }
/* ✅ agent 中止（暗色）：柔和中性灰圆底 + 浅色方块 */
.dark-mode .chat-button.is-stop .send-bg { fill: #6a6a6a; }
.dark-mode .chat-button-stop { color: #e8e8e8; }
.dark-mode .loading { color: rgba(255,255,255,0.5); }
.dark-mode .plus-menu__divider { background: rgba(255,255,255,0.08); }
.dark-mode .finalized-badge { color: rgba(255,255,255,0.45); }
.dark-mode .composer-bar.is-finalized .composer-pill { background: #1a1a1a; border-color: var(--color-border); }
html:not([data-input="touch"]) .dark-mode .image-mode-chip:hover{ background: rgba(201,178,124,0.15); }
.dark-mode .judgement-mode-chip { color: #6ee7b7; }
html:not([data-input="touch"]) .dark-mode .judgement-mode-chip:hover{ background: rgba(5,150,105,0.15); }
html:not([data-input="touch"]) .dark-mode .judgement-mode-chip:hover .judgement-mode-chip__icon{ background: rgba(110,231,183,0.25); }
.dark-mode #menuJudgementBtn.active .plus-menu__icon,
.dark-mode #menuJudgementBtn.active .plus-menu__label { color: #6ee7b7; }
.dark-mode #menuJudgementBtn.active .plus-menu__icon svg { fill: #6ee7b7; }
.dark-mode #menuJudgementBtn.active .plus-menu__check svg { stroke: #6ee7b7; }
.dark-mode #projectMenuJudgementBtn.active .plus-menu__icon,
.dark-mode #projectMenuJudgementBtn.active .plus-menu__label { color: #6ee7b7; }
.dark-mode #projectMenuJudgementBtn.active .plus-menu__icon svg { fill: #6ee7b7; }
.dark-mode #projectMenuJudgementBtn.active .plus-menu__check svg { stroke: #6ee7b7; }
.dark-mode .agent-mode-chip { color: #c4b5fd; }
html:not([data-input="touch"]) .dark-mode .agent-mode-chip:hover{ background: rgba(124,58,237,0.15); }
html:not([data-input="touch"]) .dark-mode .agent-mode-chip:hover .agent-mode-chip__icon{ background: rgba(196,181,253,0.25); }
.dark-mode #menuAgentBtn.active .plus-menu__icon,
.dark-mode #menuAgentBtn.active .plus-menu__label { color: #c4b5fd; }
.dark-mode #menuAgentBtn.active .plus-menu__icon svg { fill: #c4b5fd; }
.dark-mode #menuAgentBtn.active .plus-menu__check svg { stroke: #c4b5fd; }
.dark-mode #projectMenuAgentBtn.active .plus-menu__icon,
.dark-mode #projectMenuAgentBtn.active .plus-menu__label { color: #c4b5fd; }
.dark-mode #projectMenuAgentBtn.active .plus-menu__icon svg { fill: #c4b5fd; }
.dark-mode #projectMenuAgentBtn.active .plus-menu__check svg { stroke: #c4b5fd; }
@media (max-width: 768px), (max-height: 500px) {
  .dark-mode .composer-bar { background-color: #212121; border-top-color: #212121; }
}

/* =========================
   Mobile: file-type chips — square card, left-aligned
   ========================= */
@media (max-width: 768px), (max-height: 500px) {
  /* 附件行靠左对齐 */
  .composer-attachments {
    justify-content: flex-start;
  }

  /* 多图时图片大小与文件卡片一致 */
  .attachment-chip {
    width: 100px;
    height: 100px;
  }

  /* 文件类型 chip：竖向方形卡片（图标在上，文件名在下） */
  .attachment-chip-pdf, .attachment-chip-doc, .attachment-chip-spreadsheet,
  .attachment-chip-audio, .attachment-chip-video, .attachment-chip-ppt,
  .attachment-chip-archive, .attachment-chip-code {
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    width: 100px;
    height: 100px;
    padding: 7px 8px 8px;
    gap: 6px;
    text-align: center;
  }

  /* is-1 单文件也方形 */
  .composer-attachments.is-1 .attachment-chip-pdf,
  .composer-attachments.is-1 .attachment-chip-doc,
  .composer-attachments.is-1 .attachment-chip-spreadsheet,
  .composer-attachments.is-1 .attachment-chip-audio,
  .composer-attachments.is-1 .attachment-chip-video,
  .composer-attachments.is-1 .attachment-chip-ppt,
  .composer-attachments.is-1 .attachment-chip-archive,
  .composer-attachments.is-1 .attachment-chip-code {
    width: 100px;
    height: 100px;
  }

  /* 文件名：居中截断 */
  .attachment-pdf-name, .attachment-doc-name, .attachment-spreadsheet-name,
  .attachment-audio-name, .attachment-video-name, .attachment-ppt-name,
  .attachment-archive-name, .attachment-code-name {
    max-width: 80px;
    font-size: 11px;
    text-align: center;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    white-space: normal;
    word-break: break-all;
  }

  /* 文件信息列居中 */
  .attachment-chip-pdf > div, .attachment-chip-doc > div, .attachment-chip-spreadsheet > div,
  .attachment-chip-audio > div, .attachment-chip-video > div, .attachment-chip-ppt > div,
  .attachment-chip-archive > div, .attachment-chip-code > div {
    align-items: center;
  }

  /* 删除按钮：所有卡片统一右上角 7px */
  .attachment-chip .attachment-remove {
    top: 7px;
    right: 7px;
    transform: none;
  }
}

/* =========================
   Shared chat banner
   ========================= */
.shared-chat-banner {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 16px;
  font-size: 13px;
  color: rgba(0,0,0,0.5);
  font-family: "Flair", "Jost Fallback", "PingFang SC", "Microsoft YaHei", sans-serif;
  text-align: center;
  line-height: 1.4;
}
.dark-mode .shared-chat-banner { color: rgba(255,255,255,0.45); }
@media (max-width: 768px), (max-height: 500px) {
  .shared-chat-banner { font-size: 11px; padding: 6px 20px; }
}

/* =========================
   Branch divider
   ========================= */
.branch-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px 0;
  width: 85%;
  max-width: 700px;
  margin: 0 auto;
}
.branch-divider::before,
.branch-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: rgba(0,0,0,0.1);
}
.branch-divider-text {
  font-size: 12px;
  color: var(--color-text-secondary);
  white-space: nowrap;
  font-family: "Flair", "Jost Fallback", "PingFang SC", "Microsoft YaHei", sans-serif;
}
.branch-divider-link {
  color: rgba(0,0,0,0.55);
  text-decoration: underline;
  text-underline-offset: 2px;
}
html:not([data-input="touch"]) .branch-divider-link:hover{ color: rgba(0,0,0,0.8); }
.branch-divider-link:active { color: rgba(0,0,0,0.8); }
.dark-mode .branch-divider::before,
.dark-mode .branch-divider::after { background: rgba(255,255,255,0.1); }
.dark-mode .branch-divider-text { color: rgba(255,255,255,0.35); }
.dark-mode .branch-divider-link { color: rgba(255,255,255,0.5); }
html:not([data-input="touch"]) .dark-mode .branch-divider-link:hover{ color: rgba(255,255,255,0.75); }
.dark-mode .branch-divider-link:active { color: rgba(255,255,255,0.75); }

/* ✅ 桌面：主 composer 改绝对浮层，让 .chat-messages 铺满全高 → 右侧原生滚动条贯穿整个页面(不被输入框在流中截断)。
   composer 右侧让开滚动条宽度(--duo-sbw，JS 实测)，避免又盖住滚动条；chatMessages 补底部 padding，内容不被浮层遮。 */
@media (min-width: 769px) and (min-height: 501px) {
  .chat-container.has-messages { position: relative; }
  .chat-container.has-messages > .composer-bar {
    position: absolute;
    left: 0;
    right: var(--duo-sbw, 16px);
    bottom: 0;
    z-index: 20;
    background-color: var(--color-bg-page);   /* 亮色：与聊天区(#fff)一致 */
  }
  /* 暗色下聊天区被 .dark-mode .ai-design-section 覆盖成 #212121(≠ --color-bg-page #1a1a1a)，composer 同步 */
  .dark-mode .chat-container.has-messages > .composer-bar { background-color: #212121; }
  /* 168 = the old 132 + 36 (two-tier pill, same reason as the phone value) */
  .chat-container.has-messages > .chat-messages {
    padding-bottom: 168px;
  }
}
