/* ==========================================================================
   牌局顾问 · 问答界面
   ==========================================================================

   移动优先。使用者主要用手机扫码进来问问题，所以：

     1. 单列布局，没有侧栏——那些是开发/评审视角的东西，玩家不需要
     2. 高度用 100dvh 而不是 100vh：手机浏览器地址栏收放时，
        vh 不会跟着变，输入框会被顶到屏幕外
     3. 四边留 safe-area：刘海屏、圆角屏、底部手势条上不让内容被切
     4. 任何地方都不允许横向溢出（见文件末尾的溢出兜底）

   工具调用行的样式在 dsh-toolrow.css（移植自 DSH 的 ToolRow）；
   轮次时间线（.ar-*）也定义在那里，这里只补充页面级的外观。
   ========================================================================== */

:root {
  /* ---- 浅色主题：白底 + 蓝灰中性色 ----
     深色版的问题是"暗沉"——大面积低明度背景看久了压抑，
     而且牌面图是白底的，压在深色上反差过大、显得突兀。
     浅色下牌面图和白底融为一体，整套东西更干净。

     克制用色的理由：高级感来自【留白和层次】，不是颜色数量。
     所以主体一律中性色，只留一个暖金作强调——它同时也是扑克的红黑色之外
     唯一的品牌色。 */
  --bg: #ffffff;
  --bg-soft: #f7f8fa;
  --panel: #ffffff;
  --panel-2: #f2f4f7;
  /* 边框比深色主题更要紧：没有明暗差，层次全靠它 */
  --line: #e8eaed;
  --line-strong: #d8dbe0;
  --text: #16181d;
  --text-dim: #5a616b;
  --text-faint: #8b929c;
  /* 强调色换深一档：原来的 var(--accent) 在白底上对比不足，读不清 */
  --accent: #b8860b;
  --accent-2: #96690a;
  --red: #c0392b;
  --blue: #2f7d8c;
  --green: #1f8a5b;
  /* 浅色主题的阴影要更淡更散，否则会显得脏 */
  --shadow: 0 12px 40px rgba(16, 24, 40, .08);
  --r: 12px;
  /* 悬浮条的尺寸，消息区要按它留出上下空间 */
  --float-gap: 10px;
  --float-radius: 20px;
  --topbar-space: 74px;
  --composer-space: 96px;
  /* 深色主题那两个彩色光晕在白底上会变成脏斑，去掉 */
  --bg-glow: none;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  /* 防止 iOS 横屏/输入框聚焦时自动放大字号 */
  -webkit-text-size-adjust: 100%;
}

body {
  background: var(--bg-glow), var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Hiragino Sans GB",
               "Microsoft YaHei", "Helvetica Neue", Arial, sans-serif;
  font-size: 15px;
  -webkit-font-smoothing: antialiased;
  /* 输入框聚焦、滚动到头时的回弹会露出白边 */
  overscroll-behavior: none;
}

button, input, select { font-family: inherit; font-size: inherit; color: inherit; }

/* hidden 的语义修正：任何显式 display 都会盖过它 */
[hidden] { display: none !important; }

/* ============================== 整体布局 ============================== */

/* .app 只是一个铺满视口的定位上下文，**不再是滚动容器**。
   （它曾经是：入场动画靠它的 scrollTop 当进度。但入场层是 fixed 铺满的，
    而 fixed 元素不属于父容器的可滚动溢出区域——手指落在上面时浏览器认为
    "这里没有可滚动的东西"，所以移动端完全滑不动。见 chat.html 里的说明。）
   现在入场靠手势直接驱动，滚动只发生在 .chat 里，只有一层。 */
.app {
  position: fixed;
  inset: 0;
  overflow: hidden;
  width: 100%;
}

/* ---------- 入场：扑克牌盒 ---------- */

.intro {
  position: fixed;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5dvh;
  padding: calc(14px + env(safe-area-inset-top)) 20px calc(14px + env(safe-area-inset-bottom));
  will-change: opacity;
}

/* 牌与字直接摆在背景上，不画外框——
   用户那张草图里手绘的方框是【手机屏幕】的示意，不是要渲染的元素。 */
.deck {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: min(5dvh, 44px);
  width: 100%;
}

.deck-title {
  font-family: Georgia, 'Songti SC', 'Songti TC', serif;
  font-weight: 700;
  font-size: clamp(52px, 17vw, 96px);
  line-height: 1;
  color: var(--accent-2);
  letter-spacing: .14em;
  text-indent: .14em;          /* letter-spacing 会在末字后留白，用缩进抵消 */
  text-shadow: 0 6px 26px rgba(184, 134, 11, .30);
  will-change: transform;
}

.deck-cards {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  width: 100%;
  height: min(42dvh, 330px);
}

/* 六张牌全部绝对定位、以容器中心为原点。
   层级（z-index）由 JS 在加载时按 DOM 顺序赋值，这样"谁在谁上面"不用手写——
   六个都写死容易改乱，而且和 spread 的视觉顺序是两回事。 */
.deck-card {
  position: absolute;
  left: 50%;
  top: 50%;
  /* 注意 translateX(%) 是相对【元素自身宽度】的，不是容器宽度——
     按容器算位移会严重偏小（踩过：以为分开了，实际还叠着 88px）。
     这里位移都由 JS 写成 %，所以这个坑对每张牌都成立。 */
  transform: translate(-50%, -50%);
  height: auto;
  /* ⚠️ 六张牌尺寸必须完全一致。
     曾经把大小王做得比 K 大一圈（"主视觉大一点"），结果就是一张大卡
     插在五张小卡里，怎么调位置都不和谐——大小不一是"看着散"最直接的来源。
     视觉重心交给中轴位置与层级去表达，不靠尺寸。 */
  width: min(27vw, 112px);
  border-radius: 7px;
  background: #fff;
  /* 深色背景上白色牌面反差很大，阴影要柔一点、贴一点，
     否则每张牌都像浮在空中，六张叠起来更乱 */
  box-shadow: 0 10px 24px rgba(16, 24, 40, .10), 0 2px 6px rgba(16, 24, 40, .08);
  will-change: transform;
}

/* "左右滑动"提示 */
.scroll-hint {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  font-size: 12.5px; color: var(--text-faint);
  letter-spacing: .18em;
  will-change: opacity;
}
.hint-arrow { font-size: 17px; color: var(--accent); animation: hintBob 1.5s ease-in-out infinite; }
@keyframes hintBob { 0%, 100% { transform: translateY(0); opacity: .5 } 50% { transform: translateY(5px); opacity: 1 } }

/* ---------- 对话层：初始在视口下方 ---------- */

.chatwrap {
  position: fixed;
  inset: 0;
  z-index: 3;
  background: var(--bg-glow), var(--bg);   /* 不透明，否则上浮时会透出牌盒 */
  transform: translateY(100%);
  will-change: transform;
}

/* ============================== 顶栏 ============================== */

/* 悬浮胶囊：不给它画通栏分割线——那条线会把界面切成两块，很廉价。
   改成半透明 + 毛玻璃 + 圆角 + 阴影，消息从它下面滚过去。 */
.topbar {
  position: absolute;
  top: calc(var(--float-gap) + env(safe-area-inset-top));
  left: var(--float-gap);
  right: var(--float-gap);
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px 11px 9px 13px;
  border-radius: var(--float-radius);
  border: .5px solid rgba(16, 24, 40, .05);
  background: rgba(255, 255, 255, .82);
  -webkit-backdrop-filter: blur(22px) saturate(180%);
  backdrop-filter: blur(22px) saturate(180%);
  box-shadow: 0 6px 26px rgba(16, 24, 40, .10);
}

.brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.brand-mark {
  position: relative; flex: none;
  width: 26px; height: 30px;
  display: grid; place-items: center;
  color: var(--accent); font-size: 21px;
}
.brand-suit { position: absolute; left: 0; top: -4px; }
.brand-card-mini {
  position: absolute; right: -2px; bottom: -1px;
  width: 15px; height: 19px; border-radius: 3px;
  display: grid; place-items: center;
  background: #fdf6e3; color: #8a5a00;
  font: 800 10px Georgia, serif;
  box-shadow: 1px 2px 0 rgba(16, 24, 40, .06);
}
.brand-title {
  font-family: Georgia, 'Songti SC', serif;
  font-size: 16px; font-weight: 700; letter-spacing: .3px;
  /* ⚠️ 这里原来写死 #ffffff —— 深色主题下没问题，
     换成浅色主题后就是白字白底，整个标题直接消失。
     主题切换时最容易漏的就是这种"写死的文字色"。 */
  color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.topbar-right { display: flex; align-items: center; gap: 6px; flex: none; }

/* 回到开场的按钮：**只在对话层可见**。
   在开场页显示它没有意义（本来就在开场），还会让人以为点了会发生什么。
   用 :has() 联动入场屏的可见性，不用 JS 同步——入场进度一变，
   这个按钮的显隐自动跟上，不会出现"状态两处存、慢慢不同步"的老问题。 */
#btn-back {
  opacity: 0;
  pointer-events: none;
  transition: opacity .25s ease;
}
body:has(#intro[style*="visibility: hidden"]) #btn-back {
  opacity: 1;
  pointer-events: auto;
}

/* 触控目标不小于 34px——低于这个尺寸手指点不准 */
.icon-btn {
  flex: none;
  width: 34px; height: 34px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .95);
  border: 1px solid var(--line);
  border-radius: 9px;
  font-size: 15px; line-height: 1; cursor: pointer;
  transition: border-color .15s, color .15s;
  -webkit-tap-highlight-color: transparent;
}
.icon-btn:hover { border-color: var(--accent); color: var(--accent); }
.icon-btn:disabled { opacity: .4; cursor: default; }
/* 朗读开启时给个常亮的边框，顶栏没有文字标签可看 */
.icon-btn[data-on="1"] { border-color: var(--accent); color: var(--accent); background: rgba(184, 134, 11, .10); }

/* ============================== 对话区 ============================== */

/* 消息区铺满整个对话层，上下留出悬浮条的空间。
   这样消息是从顶栏/输入条【下面】滚过去的，不是被夹在两条横杠中间。 */
.chat {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;   /* 滚到头时不把滚动传给外层 */
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: calc(var(--topbar-space) + env(safe-area-inset-top)) 14px
           calc(var(--composer-space) + env(safe-area-inset-bottom));
}

/* ============================== 欢迎页 ============================== */

.welcome { margin: auto 0; text-align: center; padding: 8px 4px 20px; }
.welcome-lead { color: var(--text-dim); font-size: 14.5px; }

.chips {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 7px; margin-top: 20px;
}
.chip {
  font-size: 12.5px; color: var(--text-dim);
  background: rgba(255, 255, 255, .88);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 8px 13px;
  cursor: pointer; transition: .15s;
  -webkit-tap-highlight-color: transparent;
  max-width: 100%; overflow-wrap: anywhere;
}
.chip:hover, .chip:active {
  color: var(--accent-2); border-color: var(--accent);
  background: rgba(184, 134, 11, .09);
}

/* ============================== 消息 ============================== */

.msg { display: flex; flex-direction: column; width: 100%; min-width: 0; }
.msg.user { align-items: flex-end; }
.msg.ai { align-items: stretch; }

.bubble {
  border-radius: 15px;
  padding: 11px 14px;
  line-height: 1.75;
  font-size: 14.5px;
  /* 长英文、长 URL、连续数字都要能断行，否则会撑破气泡 */
  overflow-wrap: anywhere;
  word-break: break-word;
}
.msg.user .bubble {
  max-width: 84%;
  /* 深色主题靠"亮/暗"区分双方，浅色主题没有这个线索，
     只能靠底色把用户这一侧"做实"，否则两个白气泡分不出谁说的。 */
  background: #eef4f6;
  border: 1px solid #d7e5ea;
  border-bottom-right-radius: 5px;
}
.msg.ai .bubble {
  /* 助手这侧保持纯白：扁平的"白卡 + 细边"是这套浅色主题的基本形，
     再加投影会显得脏。层次交给边框和留白。 */
  background: var(--panel);
  border: 1px solid var(--line);
  border-bottom-left-radius: 5px;
}
.msg.user img.thumb { max-width: 100%; border-radius: 9px; margin-bottom: 6px; display: block; }

/* 反问 */
.bubble.clarify { border-color: rgba(184, 134, 11, .42); background: rgba(184, 134, 11, .07); }
.q-title { font-weight: 700; color: var(--accent-2); margin-bottom: 7px; }
.q-item { font-size: 13.5px; line-height: 1.7; }

/* ---------- 牌面图 ---------- */

/* 提牌的"特殊渲染"。
   像行内代码那样给个浅色底框，让它在整段文字里一眼可辨——
   读者扫一眼就知道"这里是具体某张牌/某个牌型"，不用逐字读。
   底色用强调金的低透明度，和牌面图的暖色是一套。 */
/* 提牌时的金色 chip。
   ⚠️ 这个 chip 必须是一个【不可断开】的整体。
   踩过的坑：气泡上有 `overflow-wrap: anywhere`（防长 URL 撑破），
   它会在 chip 内部任意位置断行——于是"红桃4"三个字留在上一行、
   它的牌面图被挤到下一行，读起来像牌名重复了一遍。

   `white-space: nowrap` 让整个 chip 要么整块留在本行、要么整块换到下一行。 */
.card-mention {
  /* 用 inline 而不是 inline-block：inline-block 是个不可断的整体，
     一张 13 张牌的顺子 chip 会整块冲出去（手机端溢出检测抓到过）。
     inline 让 chip 能在内部正常断行，同时下面几行保证它不会从
     "牌名"和"牌图"之间断开。 */
  display: inline;
  /* ⚠️ 这里**不能**给背景色/边框——牌图会从底色下面探出去。
     原因是 CSS 的一个坑：**line-height 不会撑高 inline 元素的背景盒**，
     它只影响行盒。所以底色始终是字体内容区那么高（15px 字号约 20px），
     而牌图是 22px，必然溢出 2~3px。
     我把 line-height 从 18px 提到 26px 想修它，量下来底色**一点没变**，
     只是把行撑开了（实测：底色 20px、牌图 22px、下方溢出 3.05px）。
     金底本来就是多余的装饰——牌图本身已经说明"这是一张牌"了，
     而它是这个溢出唯一的来源。去掉，问题就不存在了。
     颜色保留：牌名仍然用金色区分于正文。 */
  color: var(--accent-2);
  line-height: 22px;
  vertical-align: -5px;
}
/* ⚠️ 这里必须允许换行，不能写 nowrap。
   一张牌的 chip 确实不需要换行，但【多张牌】的 chip（比如
   "3-4-5-6-7-8-9-10-J-Q-K-A" 这种整条顺子）如果不允许换行，
   会直接撑出气泡外——手机端横向溢出检测抓到过这个回归。
   单张牌的情况由 chip 只占一行来保证，不需要靠 nowrap 兜。 */
.card-inline-wrap {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 2px; align-items: center;
  vertical-align: middle;
  max-width: 100%;
}
.card-fig { margin: 0; text-align: center; }
.card-fig figcaption { font-size: 10.5px; color: var(--text-faint); margin-top: 4px; }

.card-img {
  width: 46px; border-radius: 5px; background: #fff;
  border: 1px solid var(--line-strong); display: block;
}
/* 行高 25.375px。
   ⚠️ 这里原先写 18px，理由是"chip 总高不能超过行高，否则整段看着挤"。
   那个约束把优先级搞反了：**为了不撑高行盒，牺牲了"认得出是什么牌"**。
   18px 高 → 只有 12.4px 宽，渲染出来是一小坨红色，牌点糊成一团，
   五张并排夹在文字里，整段看起来像坏了（用户截图报上来的就是这个）。
   现在按"看得清"定尺寸：26px 高、约 18px 宽，牌点能认出来。
   含牌图的那几行会高出几像素——这是可接受的代价，比认不出强。 */
.card-inline {
  height: 22px; width: auto;
  vertical-align: -5px;
  margin: 0 2px 0 3px;
  border-radius: 3px; background: #fff;
  border: 1px solid var(--line-strong);
  box-shadow: 0 1px 3px rgba(16, 24, 40, .08);
}

/* 没被正文提到的牌，兜底排在下面；能换行 */
.cards-strip {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 10px;
}

/* 可点击放大 */
img[data-large] { cursor: zoom-in; -webkit-tap-highlight-color: transparent; }
img[data-large]:hover { border-color: var(--accent); }
.card-inline[data-large]:hover { box-shadow: 0 2px 8px rgba(184, 134, 11, .28); }

/* ---------- 引用与策略 ---------- */

/* 引用条文的折叠容器。
   做成一行低调的"来源"提示，而不是一堆占满屏幕的卡片——
   条文是依据不是回答，展开是用户主动要的行为。 */
.citations-fold { margin-top: 10px; }
.citations-summary {
  display: flex; align-items: center; gap: 7px;
  padding: 7px 11px;
  font-size: 12px; color: var(--text-dim);
  background: rgba(247, 248, 250, .8);
  border: 1px solid var(--line);
  border-radius: 8px;
  cursor: pointer;
  list-style: none;                 /* 去掉默认三角，用自己的 chevron */
  user-select: none;
  transition: background .15s ease, border-color .15s ease;
}
.citations-summary::-webkit-details-marker { display: none; }
.citations-summary:hover { background: rgba(242, 244, 247, .95); border-color: var(--line-strong); }
.citations-summary .dsht-chevron { margin-left: auto; transition: transform .15s ease; }
.citations-fold[open] .citations-summary .dsht-chevron { transform: rotate(90deg); }
.citations-fold[open] .citations-summary { border-radius: 8px 8px 0 0; }
.cite-label { letter-spacing: .02em; }

.citations { display: flex; flex-direction: column; gap: 7px; margin-top: 10px; }
/* 折叠容器里的那一份紧跟标题，不需要额外上边距 */
.citations-fold .citations { margin-top: 6px; }
.citation {
  font-size: 12.5px; line-height: 1.7; color: var(--text-dim);
  background: rgba(255, 255, 255, .86);
  border: 1px solid var(--line);
  border-left: 3px solid var(--blue);
  border-radius: 8px;
  padding: 9px 11px;
  overflow-wrap: anywhere;
}
.citation b { color: var(--accent-2); }

/* ---------- 元信息 ---------- */

.meta-line { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.pill {
  font-size: 10.5px; line-height: 18px;
  padding: 0 9px; border-radius: 999px;
  background: rgba(255, 255, 255, .95);
  border: 1px solid var(--line);
  color: var(--text-faint);
  white-space: nowrap;
}
.pill.good { color: var(--green); border-color: rgba(31, 138, 91, .30); }
.pill.warn { color: var(--accent); border-color: rgba(184, 134, 11, .36); }

/* 记忆更新时的系统提示：一行小字，不占地方 */
.sys-note {
  align-self: center;
  font-size: 11.5px; color: var(--text-faint);
  background: rgba(255, 255, 255, .8);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px 12px;
  max-width: 100%; overflow-wrap: anywhere;
  text-align: center;
}

/* ============================== 输入区 ============================== */

/* 输入条同样是悬浮胶囊，去掉通栏顶边线 */
.composer {
  position: absolute;
  bottom: calc(var(--float-gap) + env(safe-area-inset-bottom));
  left: var(--float-gap);
  right: var(--float-gap);
  z-index: 5;
  padding: 6px 6px 6px 8px;
  border-radius: var(--float-radius);
  border: .5px solid rgba(16, 24, 40, .05);
  background: rgba(255, 255, 255, .82);
  -webkit-backdrop-filter: blur(22px) saturate(180%);
  backdrop-filter: blur(22px) saturate(180%);
  box-shadow: 0 8px 30px rgba(16, 24, 40, .10);
}

/* 胶囊内部不再画第二层框——两层边框叠在一起很脏 */
.composer-row {
  display: flex; align-items: center; gap: 6px;
  background: transparent;
  border: 0;
  padding: 0;
}
/* 输入框必须能收缩，否则会把这个行撑宽 */
.composer-row #input {
  flex: 1 1 auto; min-width: 0;
  background: transparent; border: 0; outline: none;
  padding: 10px 6px;
  font-size: 16px;   /* 低于 16px 时 iOS 聚焦会自动放大页面，把布局顶乱 */
}
.composer-row #input::placeholder { color: var(--text-faint); }

.btn {
  font-size: 13px; cursor: pointer; border-radius: 10px;
  border: 1px solid var(--line-strong); background: var(--bg-soft); color: var(--text);
  padding: 9px 14px;
  -webkit-tap-highlight-color: transparent;
  white-space: nowrap; flex: none;
}
.btn-primary {
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: #ffffff; border-color: transparent;
  font-weight: 700;
  box-shadow: 0 7px 18px rgba(184, 134, 11, .16);
}
/* 两种"不能发"都要看得出来：
   :disabled        —— 发送中，真禁用（防重复发送）
   [aria-disabled]  —— 内容还是空的，只是外观置灰，点了仍然会有提示
   用属性选择器而不是让 JS 去加 class，省掉一次状态同步的机会 */
.btn-primary:disabled,
.btn-primary[aria-disabled="true"] { opacity: .5; cursor: default; box-shadow: none; }

.btn-ghost { background: transparent; border-color: transparent; color: var(--text-dim); }

.composer-hint { font-size: 10.5px; color: var(--text-faint); margin-top: 6px; padding-left: 8px; }

/* 待发送图片预览 */
.attach-preview { position: relative; display: inline-block; margin-bottom: 8px; }
.attach-preview img { max-height: 76px; max-width: 100%; border-radius: 9px; display: block; border: 1px solid var(--line); }
.attach-remove {
  position: absolute; top: -7px; right: -7px;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--red); color: #fff; border: 2px solid var(--bg-soft);
  font-size: 13px; line-height: 1; cursor: pointer; padding: 0;
}

/* ============================== 牌面放大 ============================== */

.lightbox {
  position: fixed; inset: 0; z-index: 999;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .72);
  backdrop-filter: blur(3px);
  cursor: zoom-out;
  animation: lb-in .14s ease-out;
}
@keyframes lb-in { from { opacity: 0 } to { opacity: 1 } }

.lightbox figure {
  margin: 0; padding: 16px;
  display: flex; flex-direction: column; align-items: center;
  max-width: 100%; max-height: 100%;
}
.lightbox img {
  /* 竖长条的牌按视口高度定尺寸；同时限宽，横屏也不会溢出 */
  height: min(74vh, 74dvh, 720px);
  width: auto; max-width: 88vw;
  border-radius: 12px; background: #fff;
  box-shadow: 0 24px 60px rgba(16, 24, 40, .16);
  animation: lb-pop .16s ease-out;
}
@keyframes lb-pop { from { transform: scale(.94) } to { transform: scale(1) } }

.lightbox figcaption {
  margin-top: 12px; font-size: 13px; color: var(--text);
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 10px;
}
.lb-hint { font-size: 11px; color: var(--text-faint); }

body.lightbox-open { overflow: hidden; }

/* ============================== 大屏微调 ============================== */

/* 手机上不显示滚动条；桌面端给一条细的 */
@media (min-width: 720px) {
  ::-webkit-scrollbar { width: 9px; }
  ::-webkit-scrollbar-thumb { background: #d8dbe0; border-radius: 5px; }
  ::-webkit-scrollbar-thumb:hover { background: #c2c7cf; }
  ::-webkit-scrollbar-track { background: transparent; }

  /* 大屏把对话收窄居中，一行太长不好读 */
  .chat { padding: 24px max(16px, calc((100% - 720px) / 2)); gap: 20px; }
  .composer { padding-left: max(12px, calc((100% - 720px) / 2)); padding-right: max(12px, calc((100% - 720px) / 2)); }
}

/* 很窄的屏幕（iPhone SE 一代 320px）：再压一压 */
@media (max-width: 360px) {
  .brand-title { font-size: 14px; }
  .icon-btn { width: 32px; height: 32px; }
  .bubble { font-size: 14px; padding: 10px 12px; }
  .msg.user .bubble { max-width: 90%; }
  /* 窄屏上牌图反而要小一点（原来这条写的 23px 比默认的 18px 还大，是反的） */
  .card-inline { height: 22px; }
  .chip { font-size: 12px; padding: 7px 11px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ==========================================================================
   横向溢出兜底
   ==========================================================================
   手机上最烦的就是"整页能左右拖"。上面每处都单独防了（输入框 min-width:0、
   气泡 overflow-wrap、牌图 flex-wrap、选择框 max-width），这里再加一道总闸：
   任何直接子元素都不许超过容器宽度。

   故意不用 `* { max-width: 100% }` —— 那会把绝对定位和 flex 布局一起搞坏。 */
.app > *, .chatwrap > * { max-width: 100vw; }
.chat > *, .msg > *, .bubble > * { min-width: 0; }
img, svg, video { max-width: 100%; }

/* ==========================================================================
   失败提示
   失败不该只甩一行原始报错——要给"发生了什么 + 该怎么办 + 一个重试按钮"。
   ========================================================================== */

.ar-fail {
  margin: 10px 0 0;
  padding: 11px 13px;
  border-radius: 10px;
  background: rgba(192, 57, 43, .06);
  border: 1px solid rgba(192, 57, 43, .30);
  display: flex; flex-direction: column; align-items: flex-start; gap: 5px;
}
.fail-title { font-size: 13.5px; font-weight: 700; color: var(--red); }
.fail-hint { font-size: 12.5px; line-height: 1.65; color: var(--text-dim); }

.fail-detail { font-size: 11.5px; color: var(--text-faint); }
.fail-detail summary { cursor: pointer; }
.fail-detail code {
  display: block; margin-top: 5px; padding: 6px 8px;
  background: rgba(16, 24, 40, .07); border-radius: 6px;
  font-size: 11px; line-height: 1.5;
  overflow-wrap: anywhere; white-space: pre-wrap;
}

.fail-retry {
  margin-top: 3px;
  padding: 7px 18px;
  background: rgba(192, 57, 43, .10);
  border-color: rgba(192, 57, 43, .45);
  color: #f5c6c0;
  font-weight: 700;
}
.fail-retry:hover { background: rgba(192, 57, 43, .28); }

/* 服务端的进行中提示（模型重试之类），语气是"说明"不是"报错" */
.ar-notice {
  margin: 8px 0 0;
  padding: 7px 11px;
  border-radius: 8px;
  font-size: 12px; line-height: 1.6;
  color: var(--accent-2);
  background: rgba(184, 134, 11, .08);
  border: 1px solid rgba(184, 134, 11, .24);
}

/* 结束会话是破坏性操作，二次确认时用警示色 */
.icon-btn-danger {
  border-color: var(--red) !important;
  color: var(--red) !important;
  background: rgba(192, 57, 43, .08) !important;
  font-size: 12px;
  font-weight: 700;
}

/* ==========================================================================
   操作面板（仿 iOS 的底部 action sheet）
   ========================================================================== */

.sheet-mask {
  position: absolute; inset: 0; z-index: 20;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: 10px;
  padding-bottom: calc(10px + env(safe-area-inset-bottom));
  background: rgba(16, 24, 40, .18);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  animation: sheet-fade .16s ease-out;
}
@keyframes sheet-fade { from { opacity: 0 } to { opacity: 1 } }

.sheet {
  display: flex; flex-direction: column;
  gap: 8px;
  animation: sheet-rise .22s cubic-bezier(.22, 1, .36, 1);
}
@keyframes sheet-rise { from { transform: translateY(14px); opacity: .5 } to { transform: none; opacity: 1 } }

.sheet-item {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 14px 16px;
  border-radius: 16px;
  border: .5px solid rgba(16, 24, 40, .05);
  background: rgba(247, 248, 250, .95);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  color: var(--text);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform .12s, background .12s;
  text-align: center;
}
.sheet-item:active { transform: scale(.98); background: rgba(238, 241, 245, .98); }

.sheet-title { font-size: 15.5px; font-weight: 600; }
.sheet-sub { font-size: 12px; color: var(--text-faint); line-height: 1.5; }

.sheet-item.danger .sheet-title { color: var(--red); }

.sheet-item.cancel {
  margin-top: 2px;
  font-size: 15.5px; font-weight: 600;
  padding: 15px 16px;
  background: rgba(255, 255, 255, .96);
}
