/**
 * Leaflet.AIChat.css —— 「AI 影像分析」对话窗样式（配套 Leaflet.AIChat.js）
 *
 * 设计令牌全部挂在 `.ac-root` 上（与 `ImageViewer.css` 的 `.iv-container` 同一套做法：
 * 浮层自包含、不污染宿主页）。三栏：左历史会话 / 中对话 / 右照片列表。
 *
 * ⚠️ 三条项目铁律（见 MEMORY.md）：
 *   1. **别用 CSS `content` 生成几何字符**（`·  ▸  ▾`）：这些码位不在中文字体常规字集里，
 *      缺字回退 = 豆腐块，且只在手机上暴露。分隔用 `border-left`，箭头用 `border` 三角。
 *   2. emoji（❌ 👈 👉 ✅）**必须显式给 emoji 字体栈**（`--ac-emoji-font`）——
 *      本文件里所有 emoji 承载元素都吃这个令牌，不许各自写死（否则墨迹大小不一）。
 *      ⚠️ 2026-09-17 订正：以前的说法「U+274C 在 iOS 上会回退到单色字形→变黑」**不成立**
 *      （用户实测同一字符在悬浮窗上正常）。真凶是 `backdrop-filter` 把子内容拽进模糊链
 *      → iOS 渲染成黑色剪影（详见 `ImageViewer.css` 的 `.iv-gallery-side`）。
 *      **结论：本文件一律不用 backdrop-filter** —— 面板内全是文字/emoji/数字占位，
 *      正是最容易被它弄黑的内容。要层次感就用不透明度分层的背景。
 *      同时源码里的 ❌ 已带 U+FE0F 变体选择符（规范级要求走 emoji 呈现）。
 *   3. 原生控件（勾选框）一律 `accent-color: auto` 跟随系统：⚠️ `accent-color` **可继承**，
 *      「跟随系统」必须显式写 `auto`，靠不写会被祖先带跑。
 *
 * 层叠：`.ac-root` z-index 13000 —— 高于 ImageViewer(10000+)，因为本窗可从查看器里打开。
 */

.ac-root {
  /* 面 */
  --ac-bg: #0b0d11;
  --ac-side-bg: rgba(255, 255, 255, 0.025);
  --ac-surface: rgba(255, 255, 255, 0.06);
  --ac-surface-hover: rgba(255, 255, 255, 0.13);
  --ac-surface-active: rgba(255, 255, 255, 0.2);
  /* 线 */
  --ac-line: rgba(255, 255, 255, 0.12);
  --ac-line-strong: rgba(255, 255, 255, 0.28);
  /* 字 */
  --ac-fg: #e8eef6;
  --ac-fg-dim: #93a4b8;
  --ac-fg-dim2: #6f8098;
  /* 强调 / 语义 */
  --ac-accent: #3ea6ff;
  --ac-accent-soft: rgba(62, 166, 255, 0.18);
  --ac-accent-dim: rgba(62, 166, 255, 0.16);
  --ac-accent-fg: #cfe8ff;
  --ac-danger: #ff5c5c;
  --ac-ok: #52c41a;
  --ac-warn: #e0a33a;
  /* ⚠️ emoji 字形字体栈（本窗唯一来源）—— 理由见文件头注释 2 */
  --ac-emoji-font: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji",
    "Segoe UI Symbol", sans-serif;
  --ac-radius: 8px;

  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 13000;
  display: none;
  background: rgba(0, 0, 0, 0.62);
  /* 字体栈与宿主页一致，但 emoji 由令牌单独点名 */
  font-family: "Microsoft YaHei", "PingFang SC", -apple-system, sans-serif;
  font-size: 13px;
  color: var(--ac-fg);
  -webkit-font-smoothing: antialiased;
}
.ac-root.ac-open {
  display: block;
}

/* ── 外壳 ── */
.ac-shell {
  position: absolute;
  top: 18px;
  right: 18px;
  bottom: 18px;
  left: 18px;
  display: flex;
  overflow: hidden;
  background: var(--ac-bg);
  border: 1px solid var(--ac-line);
  border-radius: 10px;
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.6);
}

/* ── 通用按钮 ── */
.ac-btn {
  border: 1px solid var(--ac-line);
  background: var(--ac-surface);
  color: var(--ac-fg);
  border-radius: var(--ac-radius);
  padding: 6px 10px;
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.ac-btn:hover:not(:disabled) {
  background: var(--ac-surface-hover);
}
.ac-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.ac-btn-ghost {
  background: transparent;
}
.ac-btn-primary {
  background: var(--ac-accent);
  border-color: var(--ac-accent);
  color: #04121f;
  font-weight: 600;
  padding: 6px 18px;
}
.ac-btn-primary:hover:not(:disabled) {
  background: #5cb4ff;
  border-color: #5cb4ff;
}
.ac-btn-danger {
  color: var(--ac-danger);
  border-color: rgba(255, 92, 92, 0.45);
  background: rgba(255, 92, 92, 0.1);
}
.ac-btn-danger:hover:not(:disabled) {
  background: rgba(255, 92, 92, 0.2);
}
/* 原生 button 里的 emoji 要显式 flex 居中（emoji 不吃 line-height 居中） */
.ac-close,
.ac-chip-rm,
.ac-sess-del,
.ac-photos-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--ac-emoji-font);
}
/* 焦点环只用系统自绘的（深色底上浏览器会给高对比白环） */
.ac-root :focus-visible {
  outline: -webkit-focus-ring-color auto;
  outline-offset: 1px;
}

/* ═══════════════════════════════════════
   左栏：历史会话
   ═══════════════════════════════════════ */
.ac-side {
  display: flex;
  flex-direction: column;
  flex: 0 0 204px;
  min-width: 0;
  background: var(--ac-side-bg);
  border-right: 1px solid var(--ac-line);
}
.ac-side-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 10px 8px;
  border-bottom: 1px solid var(--ac-line);
}
.ac-side-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--ac-fg-dim);
  letter-spacing: 0.5px;
}
/* ── 左栏开合键（2026-09-17）：与右栏 `.ac-photos-toggle` 同款，只是方向镜像 ── */
.ac-side-toggle {
  flex: 0 0 auto;
  width: 26px;
  height: 22px;
  border: 0;
  background: transparent;
  color: var(--ac-fg-dim);
  font-family: var(--ac-emoji-font);
  font-size: 13px;
  line-height: 1;
  border-radius: 4px;
  padding: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ac-side-toggle:hover {
  background: var(--ac-surface-hover);
  color: var(--ac-fg);
}
/* ── 左栏收起态（2026-09-18 改）：不再是「空把手」，收成 56px 的**小卡列** ──
   旧版：会话列表和 Key 区整条 `display:none`，收起后只剩 👈 与 ➕ —— 用户收起后
   完全看不见有哪几个对话，也看不见 Key 配没配，只能再点开确认。
   新版：每个会话压成一张 40×40 小卡（中间是**序号**「第几个对话」，有图就用该
   会话的首图缩略图打底），栏底常驻一个 🔑（已设置/未设置靠底盘色区分）。
   宽度：40(卡) + 2×7(padding) ≈ 54 → 取 56px 留一点余量给滚动条。 */
.ac-side.ac-collapsed {
  flex-basis: 56px;
}
/* 收起后隐藏的是「文字态」，不是整个列表 —— 列表改成小卡列。
   ⚠️ 只藏 `.ac-keybar`，**不藏 `.ac-keyrow`**：keyrow 本来默认就是 `display:none`，
      在这里再藏一次（选择器权重 0,3,0）会压过 `.ac-keybox-editing .ac-keyrow`
      的 `display:block`（0,2,0）→ 编辑态再也打不开输入框。 */
.ac-side.ac-collapsed .ac-side-title,
.ac-side.ac-collapsed .ac-keybar {
  display: none;
}
.ac-side.ac-collapsed .ac-sess-list {
  padding: 6px 7px 8px;
}
.ac-side.ac-collapsed .ac-sess {
  background: transparent;
  display: block;
  margin-bottom: 6px;
}
.ac-side.ac-collapsed .ac-sess:hover {
  background: transparent;
}
.ac-side.ac-collapsed .ac-sess-main,
.ac-side.ac-collapsed .ac-sess-del {
  display: none;
}
.ac-side.ac-collapsed .ac-sess-mini {
  display: flex;
}
/* 会话小卡：序号居中压在缩略图上（缩略图压暗，保证序号在任何底色上都能读） */
.ac-sess-mini {
  display: none;
  position: relative;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin: 0 auto;
  padding: 0;
  border: 1px solid var(--ac-line);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.05);
  overflow: hidden;
  cursor: pointer;
  font-family: inherit;
  color: var(--ac-fg);
}
.ac-sess-mini:hover {
  border-color: var(--ac-line-strong);
}
.ac-sess-mini-img {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0.5;
}
/* 取不到 / 加载失败 → 藏图留底（不显示破图图标，同全项目口径） */
.ac-sess-mini-notb .ac-sess-mini-img {
  display: none;
}
.ac-sess-mini-n {
  position: relative;
  z-index: 1;
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.95), 0 0 2px rgba(0, 0, 0, 0.95);
}
.ac-sess-cur .ac-sess-mini {
  border-color: var(--ac-accent);
  box-shadow: 0 0 0 1px var(--ac-accent) inset;
}
/* 48px 塞不下并排的两个键 → 栏头竖排 */
.ac-side.ac-collapsed .ac-side-head {
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
  gap: 8px;
  padding: 9px 4px;
}
.ac-new {
  flex: 0 0 auto;
}
/* 折叠后「新对话」退化成单个 ➕（用户 2026-09-17：「折叠后一个加号即可」，照 DeepSeek） */
.ac-new-mini {
  width: 28px;
  height: 26px;
  padding: 0;
  font-family: var(--ac-emoji-font);
  font-size: 13px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ac-sess-list {
  flex: 1;
  overflow-y: auto;
  padding: 6px;
}
.ac-sess {
  display: flex;
  align-items: stretch;
  gap: 2px;
  border-radius: var(--ac-radius);
  margin-bottom: 2px;
}
.ac-sess:hover {
  background: var(--ac-surface);
}
.ac-sess-cur {
  background: var(--ac-accent-soft);
}
.ac-sess-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  align-items: flex-start;
  border: 0;
  background: transparent;
  color: inherit;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  padding: 7px 8px;
  border-radius: var(--ac-radius);
}
.ac-sess-title {
  font-size: 12.5px;
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ac-sess-cur .ac-sess-title {
  color: var(--ac-accent-fg);
}
.ac-sess-sub {
  font-size: 11px;
  color: var(--ac-fg-dim2);
}
.ac-sess-del {
  flex: 0 0 auto;
  width: 26px;
  border: 0;
  background: transparent;
  color: var(--ac-fg-dim2);
  font-size: 11px;
  cursor: pointer;
  border-radius: var(--ac-radius);
}
.ac-sess-del:hover {
  background: rgba(255, 92, 92, 0.18);
  color: var(--ac-danger);
}

/* ═══════════════════════════════════════
   中栏：对话
   ═══════════════════════════════════════ */
.ac-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.ac-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--ac-line);
  flex: 0 0 auto;
}
.ac-head-title {
  font-size: 14px;
  font-weight: 600;
}
.ac-head-model {
  font-size: 11px;
  color: var(--ac-accent-fg);
  background: var(--ac-accent-soft);
  border: 1px solid rgba(62, 166, 255, 0.35);
  border-radius: 10px;
  padding: 1px 8px;
}
.ac-close {
  margin-left: auto;
  width: 30px;
  height: 26px;
  border: 0;
  background: transparent;
  color: var(--ac-fg-dim);
  font-size: 15px;
  border-radius: var(--ac-radius);
  cursor: pointer;
}
.ac-close:hover {
  background: var(--ac-surface-hover);
  color: var(--ac-fg);
}

/* ── Key 区（2026-09-17 改到左栏底部）──
   默认**收起**：只显示脱敏摘要（`sk-1234****abcd`）+ 删 Key 按钮；点摘要才展开
   password 输入框（输入即自动落盘，回车或失焦收起）。
   为什么收起：Key 常驻在视线中央，投屏演示时即便打着圆点也显眼；且这一栏的主角是
   「历史对话」，Key 不该抢它的位置。 */
.ac-keybox {
  flex: 0 0 auto;
  border-top: 1px solid var(--ac-line);
  background: rgba(255, 255, 255, 0.02);
  padding: 8px;
}
.ac-keybar {
  display: flex;
  align-items: center;
  gap: 6px;
}
.ac-keysum {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--ac-radius);
  color: var(--ac-fg-dim);
  font-family: inherit;
  font-size: 11.5px;
  padding: 5px 7px;
  cursor: pointer;
  text-align: left;
}
.ac-keysum:hover {
  background: var(--ac-surface-hover);
  color: var(--ac-fg);
}
/* 🔑 图标：emoji 必须走 emoji 字体栈（理由见文件头），否则 iOS 上可能是单色字形 */
.ac-keysum-ico {
  flex: 0 0 auto;
  font-family: var(--ac-emoji-font);
  font-size: 13px;
  line-height: 1;
}
.ac-keysum-tx {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ac-keybox-set .ac-keysum-tx {
  color: var(--ac-ok);
}
.ac-keybox-unset .ac-keysum-tx {
  color: var(--ac-warn, #e0a33a);
}
/* 删 Key：红色 emoji（🗑️）。⚠️ emoji 不吃 `color`，所以「红」不能靠 `color` 给 ——
   靠字形自带的红调 + 悬停时的红底/红边表达危险语义（与 `.ac-btn-danger` 同色系）。
   emoji 必须走 emoji 字体栈，理由见文件头；字号按「emoji 比同号文字大一圈」压到 12px。 */
.ac-keydel {
  flex: 0 0 auto;
  font-family: var(--ac-emoji-font);
  font-size: 12px;
  line-height: 1;
  padding: 4px 7px;
}
.ac-keydel:disabled {
  opacity: 0.4;
}
/* 展开态：只显示输入框（摘要行隐藏，避免同一个 key 出现两处） */
.ac-keyrow {
  display: none;
}
.ac-keybox-editing .ac-keybar {
  display: none;
}
.ac-keybox-editing .ac-keyrow {
  display: block;
}
.ac-key {
  width: 100%;
  box-sizing: border-box;
  background: var(--ac-surface);
  border: 1px solid var(--ac-line);
  border-radius: var(--ac-radius);
  color: var(--ac-fg);
  font-family: inherit;
  font-size: 12px;
  padding: 5px 9px;
}
.ac-key::placeholder {
  color: var(--ac-fg-dim2);
}
.ac-key:hover {
  border-color: var(--ac-line-strong);
}
/* ── 折叠态栏底的 🔑（2026-09-18）──
   收起后 Key 的文字摘要看不见了，用一个 key emoji 顶上：语义是「Key 在不在」，
   点它 = 展开左栏并直接进编辑态。
   ⚠️ emoji **不吃 `color`** —— 「已设置/未设置」的差别只能做在底盘和描边上
   （与 `.ac-keydel` 同一个坑，见其上方注释）。 */
.ac-key-mini {
  display: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 32px;
  margin: 0 auto;
  padding: 0;
  border: 1px solid var(--ac-line);
  border-radius: 7px;
  background: transparent;
  font-family: var(--ac-emoji-font);
  /* 「emoji 比同号文字大一圈」→ 15px 已够（与左下角入口同档） */
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
.ac-keybox-set .ac-key-mini {
  border-color: rgba(82, 196, 26, 0.55);
  background: rgba(82, 196, 26, 0.12);
}
.ac-keybox-unset .ac-key-mini {
  border-color: rgba(224, 163, 58, 0.55);
  background: rgba(224, 163, 58, 0.12);
}
.ac-key-mini:hover {
  border-color: var(--ac-line-strong);
}
.ac-side.ac-collapsed .ac-key-mini {
  display: flex;
}

/* ── 消息区 ── */
.ac-msgs {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 14px 16px 6px;
  scroll-behavior: smooth;
}
.ac-msg {
  display: flex;
  gap: 9px;
  margin-bottom: 14px;
}
/* DeepSeek 图标（`dsIcon()` 产物）：地图左下角入口、悬浮窗 AI 按钮、对话头像共用同一个字形。
   颜色一律 `currentColor` —— 它要落在三种底色上（Leaflet 白底、悬浮窗白底、对话深色气泡），
   写死一个颜色必然有一处看不清；尺寸由 SVG 的 `width`/`height` 属性给。 */
.ac-dsico {
  display: block;
  flex: 0 0 auto;
}
.ac-avatar {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  background: var(--ac-surface-active);
  color: var(--ac-fg-dim);
}
.ac-msg-assistant .ac-avatar {
  background: var(--ac-accent-soft);
  /* 2026-09-18：助手头像里的「AI」两个字换成 DeepSeek 图标。
     品牌蓝在 `--ac-accent-soft` 蓝底盘上的对比度约 3.4:1（图形元素的门槛是 3:1）。
     ⚠️ 深色主题下别用更暗的品牌色变体 —— 那会掉到门槛以下。 */
  color: #4d6bfe;
}
.ac-bubble {
  flex: 1 1 auto;
  min-width: 0;
}
.ac-text {
  font-size: 13px;
  line-height: 1.72;
  word-break: break-word;
}
.ac-msg-user .ac-text {
  white-space: pre-wrap;
  background: var(--ac-surface);
  border: 1px solid var(--ac-line);
  border-radius: var(--ac-radius);
  padding: 8px 11px;
}
/* 极简 Markdown 渲染结果 */
.ac-text p {
  margin: 0 0 7px;
}
.ac-text p:last-child {
  margin-bottom: 0;
}
.ac-h {
  font-weight: 600;
  color: var(--ac-fg);
  margin: 10px 0 5px;
}
.ac-h3 {
  font-size: 14.5px;
}
.ac-h4,
.ac-h5 {
  font-size: 13.5px;
}
.ac-ul,
.ac-ol {
  margin: 0 0 7px;
  padding-left: 20px;
}
.ac-ul li,
.ac-ol li {
  margin-bottom: 3px;
}
.ac-code {
  font-family: Consolas, "Courier New", monospace;
  font-size: 12px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 4px;
  padding: 1px 5px;
}

/* ── 围栏代码块（2026-09-18）──
   模型输出的代码/JSON 是常态，纯 `<pre>` 既没语言提示也复制不了。
   结构：`.ac-pre` = 语言标签行 + 正文；正文自己横向滚动（**不要**让整个气泡滚）。 */
.ac-pre {
  margin: 8px 0;
  border: 1px solid var(--ac-line);
  border-radius: 6px;
  overflow: hidden;
  background: #0e1116;
}
.ac-pre-hd {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  background: rgba(255, 255, 255, 0.05);
  border-bottom: 1px solid var(--ac-line);
}
.ac-pre-lang {
  flex: 1 1 auto;
  min-width: 0;
  font-family: Consolas, "Courier New", monospace;
  font-size: 11px;
  color: var(--ac-fg-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ac-pre-copy {
  flex: 0 0 auto;
  border: 1px solid var(--ac-line);
  background: transparent;
  color: var(--ac-fg-dim);
  font-family: inherit;
  font-size: 11px;
  line-height: 1.5;
  padding: 2px 8px;
  border-radius: 4px;
  cursor: pointer;
}
.ac-pre-copy:hover {
  background: var(--ac-surface-hover);
  color: var(--ac-fg);
}
.ac-pre-copy.ac-copied {
  color: var(--ac-ok);
  border-color: rgba(82, 196, 26, 0.55);
}
.ac-pre-bd {
  margin: 0;
  padding: 8px 10px;
  overflow-x: auto;
  font-family: Consolas, "Courier New", monospace;
  font-size: 12px;
  line-height: 1.55;
  color: #c9d1d9;
  /* ⚠️ 必须 `pre`（不是 `pre-wrap`）：代码缩进是语义，折行会让它读不出结构 */
  white-space: pre;
}
/* 代码块里不再叠行内 code 的灰底（那是给正文里的反引号用的） */
.ac-pre-bd code {
  font-family: inherit;
  font-size: inherit;
  background: none;
  padding: 0;
  border-radius: 0;
}
.ac-pre-bd::-webkit-scrollbar {
  height: 8px;
}
.ac-pre-bd::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.16);
  border-radius: 4px;
}
/* 极简高亮配色（GitHub dark 系，与面板底色一致） */
.ac-tk-c {
  color: #8b949e;
  font-style: italic;
}
.ac-tk-s {
  color: #a5d6ff;
}
.ac-tk-n {
  color: #79c0ff;
}
.ac-tk-k {
  color: #ff7b72;
}
.ac-tk-b {
  color: #79c0ff;
}
.ac-tk-f {
  color: #d2a8ff;
}
.ac-tk-add {
  color: #7ee787;
}
.ac-tk-del {
  color: #ffa198;
}
.ac-tk-m {
  color: #d2a8ff;
}

/* ── 表格 ── */
.ac-tblwrap {
  margin: 8px 0;
  overflow-x: auto;
}
.ac-tbl {
  border-collapse: collapse;
  font-size: 12.5px;
  line-height: 1.5;
}
.ac-tbl th,
.ac-tbl td {
  border: 1px solid var(--ac-line);
  padding: 4px 8px;
}
.ac-tbl th {
  background: rgba(255, 255, 255, 0.06);
  font-weight: 600;
}
.ac-tbl-l {
  text-align: left;
}
.ac-tbl-c {
  text-align: center;
}
.ac-tbl-r {
  text-align: right;
}

/* ── 引用 / 分隔线 / 任务列表 / 链接 ── */
.ac-bq {
  margin: 8px 0;
  padding: 1px 0 1px 10px;
  /* 引用条用 border 画，**不用 `content` 生成 `▍`**（见文件头铁律 1） */
  border-left: 3px solid var(--ac-line-strong);
  color: var(--ac-fg-dim);
}
.ac-bq .ac-p {
  margin-bottom: 4px;
}
.ac-hr {
  border: 0;
  border-top: 1px solid var(--ac-line);
  margin: 12px 0;
}
/* 任务列表：只读勾选框用真 `<input disabled>`（语义正确、屏幕阅读器可读），
   ⚠️ `accent-color` **可继承**，这里显式 `auto` 跟随系统（铁律 3） */
.ac-task {
  display: flex;
  align-items: flex-start;
  gap: 6px;
}
.ac-taskck {
  flex: 0 0 auto;
  margin: 3px 0 0;
  accent-color: auto;
}
.ac-tasktx {
  min-width: 0;
}
/* 深浅底色下原生 checkbox 的「勾了 / 没勾」几乎分不出来（都是个小方块）→
   给已完成项的文字补删除线 + 压暗。⚠️ **不动 checkbox 本身**：原生控件一律
   跟随系统（铁律 3），要区分就区分文字。 */
.ac-task-done .ac-tasktx {
  color: var(--ac-fg-dim2);
  text-decoration: line-through;
}
.ac-link {
  /* ⚠️ 不用 `--ac-accent-fg`（#cfe8ff）：在深色底上它跟正文几乎同色，
     链接就失去「可点」的可辨识性了。这里用饱和度更高的蓝。 */
  color: #7cc4ff;
  text-decoration: underline;
  text-underline-offset: 2px;
  word-break: break-all;
}
.ac-link:hover {
  color: #fff;
}
.ac-msg-user .ac-bubble-photos {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-bottom: 6px;
}
.ac-bphoto {
  position: relative;
  width: 62px;
  height: 46px;
  border-radius: 5px;
  overflow: hidden;
  background: var(--ac-surface);
  border: 1px solid var(--ac-line);
}
.ac-bphoto img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* 无缩略图（或历史会话里的 URL 已失效）→ 数字占位，**不显示破图图标** */
.ac-bphoto-ph {
  display: none;
  position: absolute;
  inset: 0;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  font-weight: 600;
  color: var(--ac-fg-dim);
  font-variant-numeric: tabular-nums;
  background: rgba(255, 255, 255, 0.05);
}
.ac-bphoto-nothumb .ac-bphoto-ph {
  display: flex;
}
.ac-bphoto-nothumb img {
  visibility: hidden;
}
.ac-bphoto-n {
  position: absolute;
  right: 2px;
  bottom: 2px;
  font-size: 10px;
  line-height: 1;
  padding: 2px 4px;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.68);
  color: #fff;
}
/* 思维链折叠块（对齐 deepseek 官方 chat 的「已深度思考」，默认收起） */
.ac-reason {
  border-left: 2px solid var(--ac-line-strong);
  margin: 2px 0 8px;
  padding-left: 10px;
}
.ac-reason-sum {
  cursor: pointer;
  font-size: 12px;
  color: var(--ac-fg-dim);
  list-style: none;
}
.ac-reason-sum::-webkit-details-marker {
  display: none;
}
.ac-reason-sum::before {
  /* 折叠指示用 border 三角，**不用字符**（见文件头铁律 1） */
  content: "";
  display: inline-block;
  width: 0;
  height: 0;
  margin-right: 6px;
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  border-left: 5px solid var(--ac-fg-dim2);
  transition: transform 0.15s;
  vertical-align: middle;
}
.ac-reason[open] .ac-reason-sum::before {
  transform: rotate(90deg);
}
.ac-reason-body {
  font-size: 12px;
  line-height: 1.7;
  color: var(--ac-fg-dim);
  white-space: pre-wrap;
  max-height: 220px;
  overflow-y: auto;
  margin-top: 6px;
  padding-right: 6px;
}
.ac-typing {
  color: var(--ac-fg-dim);
  font-size: 12.5px;
}
.ac-typing::after {
  content: "";
  display: inline-block;
  width: 6px;
  height: 12px;
  margin-left: 3px;
  background: var(--ac-accent);
  vertical-align: -2px;
  animation: ac-blink 1s steps(2, start) infinite;
}
@keyframes ac-blink {
  to {
    visibility: hidden;
  }
}
.ac-err {
  font-size: 12.5px;
  line-height: 1.6;
  color: #ffb0b0;
  background: rgba(255, 92, 92, 0.12);
  border: 1px solid rgba(255, 92, 92, 0.4);
  border-radius: var(--ac-radius);
  padding: 8px 11px;
}
/**
 * 「Key 不可用」的**指路**块（跟 `.ac-err` 那条错误并列显示）。
 * 用琥珀色而不是红色：红色那条说的是「这次失败了」，这条说的是「怎么修」——
 * 两个都是一样的红，用户只会看见一大片错误、读不出哪句要他动手。
 */
.ac-err-help {
  font-size: 12.5px;
  line-height: 1.6;
  color: #ffd79a;
  background: rgba(255, 190, 92, 0.12);
  border: 1px solid rgba(255, 190, 92, 0.42);
  border-radius: var(--ac-radius);
  padding: 8px 11px;
  margin-top: 6px;
}
.ac-welcome,
.ac-empty {
  font-size: 12px;
  line-height: 1.7;
  color: var(--ac-fg-dim2);
  padding: 8px 2px;
}
.ac-welcome {
  line-height: 2;
}

/* ── composer ── */
.ac-composer {
  flex: 0 0 auto;
  border-top: 1px solid var(--ac-line);
  padding: 8px 12px 10px;
}
.ac-picked {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: 7px;
  min-height: 20px;
}
.ac-picked-empty {
  font-size: 11.5px;
  color: var(--ac-fg-dim2);
}
.ac-chip {
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--ac-surface);
  border: 1px solid var(--ac-line);
  border-radius: 6px;
  padding: 3px 5px 3px 3px;
  max-width: 210px;
}
.ac-chip-img {
  width: 40px;
  height: 30px;
  object-fit: cover;
  border-radius: 4px;
  display: block;
  flex: 0 0 auto;
  background: rgba(0, 0, 0, 0.3);
}
/* 无缩略图 → 数字占位（同右栏口径：候选池序号），不显示破图图标 */
.ac-chip-ph {
  display: none;
  flex: 0 0 auto;
  width: 40px;
  height: 30px;
  border-radius: 4px;
  align-items: center;
  justify-content: center;
  font-size: 13px;
  font-weight: 600;
  color: var(--ac-fg-dim);
  font-variant-numeric: tabular-nums;
  background: rgba(255, 255, 255, 0.05);
  border: 1px dashed var(--ac-line-strong);
}
.ac-chip-nothumb .ac-chip-ph {
  display: flex;
}
.ac-chip-nothumb .ac-chip-img {
  display: none;
}
.ac-chip-order {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--ac-accent);
  color: #04121f;
  font-size: 10px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ac-chip-meta {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1 1 auto;
}
.ac-chip-name {
  font-size: 11.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ac-chip-sub {
  font-size: 10.5px;
  color: var(--ac-fg-dim2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ac-chip-rm {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  border: 0;
  background: transparent;
  color: var(--ac-fg-dim2);
  font-size: 10px;
  border-radius: 4px;
  cursor: pointer;
}
.ac-chip-rm:hover {
  background: rgba(255, 92, 92, 0.2);
  color: var(--ac-danger);
}
.ac-attach {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 6px;
}
.ac-geo {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-size: 11.5px;
  color: var(--ac-fg-dim);
}
.ac-geo input {
  /* ⚠️ 原生勾选框：跟随系统配色，必须显式 auto（accent-color 可继承） */
  accent-color: auto;
  width: 13px;
  height: 13px;
  margin: 0;
  cursor: pointer;
}
.ac-geo-tx {
  line-height: 1.4;
}
.ac-pickcount {
  margin-left: auto;
  font-size: 11.5px;
  color: var(--ac-fg-dim);
  flex: 0 0 auto;
}
.ac-inputrow {
  display: flex;
  align-items: flex-end;
  gap: 8px;
}
.ac-input {
  flex: 1 1 auto;
  min-width: 0;
  box-sizing: border-box;
  /* 2026-09-17 改成「DeepSeek 式」自动增高（用户点名要这个）：
     初始只占**一行多**（46px），随输入往上长，到 176px 转内部滚动条，不把对话流压没。
     · `resize: none` —— 高度由 `_autoGrowInput()` 接管，留着手柄会互相打架；
     · `overflow-y: auto` 常开（未到顶时内容不溢出 → 不会出现滚动条）；
     · ⚠️ `min-height` / `max-height` 必须与 JS 的 `AC_INPUT_MIN_H` / `AC_INPUT_MAX_H`
       同值，否则 JS 设的高度会被 CSS 静默截断（表现为「长不高」或「早就滚动」）。 */
  resize: none;
  min-height: 46px;
  max-height: 176px;
  overflow-y: auto;
  background: var(--ac-surface);
  border: 1px solid var(--ac-line);
  border-radius: var(--ac-radius);
  color: var(--ac-fg);
  font-family: inherit;
  font-size: 12.5px;
  line-height: 1.6;
  padding: 7px 10px;
}
.ac-input::placeholder {
  color: var(--ac-fg-dim2);
}
.ac-input:hover {
  border-color: var(--ac-line-strong);
}
.ac-send {
  flex: 0 0 auto;
}
.ac-send.loading {
  opacity: 0.7;
}

/* ═══════════════════════════════════════
   右栏：照片列表
   ═══════════════════════════════════════ */
.ac-photos {
  display: flex;
  flex-direction: column;
  flex: 0 0 268px;
  min-width: 0;
  background: var(--ac-side-bg);
  border-left: 1px solid var(--ac-line);
  transition: flex-basis 0.2s;
}
.ac-photos-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  padding: 10px 10px 8px;
  border-bottom: 1px solid var(--ac-line);
  flex: 0 0 auto;
}
.ac-photos-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--ac-fg-dim);
  letter-spacing: 0.5px;
  white-space: nowrap;
}
.ac-photos-toggle {
  flex: 0 0 auto;
  width: 26px;
  height: 22px;
  border: 0;
  background: transparent;
  color: var(--ac-fg-dim);
  font-size: 13px;
  border-radius: 4px;
  cursor: pointer;
}
.ac-photos-toggle:hover {
  background: var(--ac-surface-hover);
  color: var(--ac-fg);
}
/* ── 窄屏「照片列表二级页」专用件（2026-09-18）──
   三个都**只在窄屏出现**，桌面端一律 `display:none`：
     · `.ac-pickbtn`    入口按钮（在 composer 的 attach 行）
     · `.ac-sheet-close` 二级页栏头的 ❌ 返回
     · `.ac-sheet-count`  二级页栏头的「已选 n/5」
   桌面端右栏常驻，这三样都是多余的：入口重复、❌ 无页可返回、计数在 composer 上已有。 */
.ac-pickbtn,
.ac-sheet-close,
.ac-sheet-count {
  display: none;
}
/* 视图切换：按时间 / 按文件夹 / 异常组 */
.ac-modebar {
  display: flex;
  gap: 4px;
  padding: 6px 8px;
  border-bottom: 1px solid var(--ac-line);
  flex: 0 0 auto;
}
.ac-mode {
  flex: 1 1 0;
  min-width: 0;
  background: transparent;
  border: 1px solid var(--ac-line);
  border-radius: 5px;
  color: var(--ac-fg-dim);
  font-family: inherit;
  font-size: 11.5px;
  padding: 4px 2px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ac-mode:hover:not(:disabled) {
  background: var(--ac-surface-hover);
  color: var(--ac-fg);
}
.ac-mode:disabled {
  opacity: 0.42;
  cursor: not-allowed;
}
.ac-mode.ac-mode-on {
  background: var(--ac-accent-dim, rgba(62, 166, 255, 0.16));
  border-color: var(--ac-accent);
  color: var(--ac-fg);
}
/* ── 视图栏（2026-09-18 二次修订）──
   最终只有三个视图（按点位 / 按时间 / 按文件夹），一行放得下 → 不需要 `flex-wrap`。
   （中间曾短暂有过第四个「隐藏异常组」开关，需要换成两行；用户明确右栏不要
   「异常组」这一类之后开关已撤，换行规则一并删掉。） */
.ac-photo-list {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 6px 8px 10px;
}
.ac-day {
  margin-bottom: 8px;
}
.ac-dayhead {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 2px;
  cursor: pointer;
  user-select: none;
  font-size: 11.5px;
  color: var(--ac-fg-dim);
  border-bottom: 1px solid var(--ac-line);
  margin-bottom: 5px;
  /* ⚠️ 必须 nowrap：分组名（尤其「按文件夹」的目录名）一长，张数就会被挤到第二行。 */
  flex-wrap: nowrap;
}
/* 分组名（日期 / 目录名）：**占满剩余宽度后省略**，保证「N 张」永远在同一行右端。
   目录名长起来能到几十个字符（`20240612_P4_正射_飞马D2000_南浦溪`），
   不省略的话它会把 `margin-left:auto` 的张数挤出容器的换行点。
   ⚠️ 三件套缺一不可：`min-width:0`（flex 项默认 min-width:auto 会撑破）、
   `overflow:hidden`、`text-overflow:ellipsis`；`white-space:nowrap` 由继承/本条保证。
   完整目录路径没有丢 —— 分组头上有 `title`（`_renderGroups` 里 `dh.title = g.dir`）。 */
.ac-daydate {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ac-dayhead::before,
.ac-bandhead::before {
  /* 折叠箭头 = border 三角（不用字符，见文件头铁律 1） */
  content: "";
  width: 0;
  height: 0;
  border-left: 4px solid var(--ac-fg-dim2);
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transform: rotate(90deg);
  transition: transform 0.15s;
}
.ac-day.collapsed .ac-dayhead::before,
.ac-band.collapsed .ac-bandhead::before {
  transform: rotate(0deg);
}
.ac-day.collapsed .ac-thumbs {
  display: none;
}
.ac-daycount {
  margin-left: auto;
  color: var(--ac-fg-dim2);
  font-size: 10.5px;
  /* 张数是**固定短文本**，永远不参与压缩/换行 —— 被挤掉的就是它 */
  flex: 0 0 auto;
  white-space: nowrap;
}
.ac-thumbs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}
.ac-thumb {
  position: relative;
  padding: 0;
  border: 1px solid var(--ac-line);
  background: rgba(0, 0, 0, 0.35);
  border-radius: 5px;
  aspect-ratio: 4 / 3;
  cursor: pointer;
  overflow: hidden;
  font-family: inherit;
}
.ac-thumb:hover {
  border-color: var(--ac-line-strong);
}
/* 已选：橙色描边（与查看器里「当前这张」同色系，一眼看出已加入分析） */
.ac-thumb.ac-picked {
  border-color: #ff9d2e;
  box-shadow: 0 0 0 1px #ff9d2e inset;
}
.ac-thumb-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* ── 无缩略图 → 数字占位（2026-09-17）──
   ⚠️ 需求：不要显示浏览器的破图图标。取不到缩略图源（或加载失败）时藏掉 `<img>`，
   露出「候选池第几张」的数字 —— 让用户仍能指认「我要的是第 7 张」，而不是看到
   满屏一模一样的破图。斜纹底是为了一眼看出「这是占位、不是照片」。 */
.ac-thumb-ph {
  display: none;
  position: absolute;
  inset: 0;
  align-items: center;
  justify-content: center;
  font-size: 17px;
  font-weight: 600;
  color: rgba(226, 238, 250, 0.8);
  font-variant-numeric: tabular-nums;
  background-color: rgba(255, 255, 255, 0.05);
  background-image: repeating-linear-gradient(
    45deg,
    rgba(255, 255, 255, 0.05) 0 6px,
    transparent 6px 12px
  );
}
.ac-thumb-nothumb .ac-thumb-ph {
  display: flex;
}
.ac-thumb-nothumb .ac-thumb-img {
  display: none;
}
.ac-thumb-order {
  position: absolute;
  left: 2px;
  top: 2px;
  min-width: 14px;
  height: 14px;
  padding: 0 3px;
  border-radius: 7px;
  background: #ff9d2e;
  color: #241100;
  font-size: 10px;
  font-weight: 700;
  line-height: 14px;
  text-align: center;
}
.ac-thumb-order:empty {
  display: none;
}
/* 缩略图角标：正射俯拍（有坐标，只是航向无意义） vs 定位异常（无可用坐标） */
.ac-thumb-tag {
  position: absolute;
  right: 2px;
  bottom: 2px;
  padding: 1px 3px;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.72);
  font-size: 9px;
  line-height: 1.3;
}
.ac-thumb-tag-nogeo {
  color: #ffd591;
}
.ac-thumb-tag-nadir {
  color: #b7eb8f;
}

/* ═══════════════════════════════════════
   「按点位」视图（2026-09-18）
   结构：视点头（原点是谁）→ 距离档 `.ac-band` → 档内的日期分组（跨天才出 `.ac-day`）
   为什么档头不复用 `.ac-dayhead`：档头是**主层级**（距离），日期是小标题（次级）；
   两者同款的话缩进与粗细都分不出高低。
   ═══════════════════════════════════════ */
.ac-pthead {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 2px 6px;
  border-bottom: 1px solid var(--ac-line);
  margin-bottom: 8px;
  font-size: 11px;
  color: var(--ac-fg-dim);
}
.ac-pthead-src {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.ac-pthead-sub {
  flex: 0 0 auto;
  color: var(--ac-fg-dim2);
  font-size: 10.5px;
}
.ac-band {
  margin-bottom: 9px;
}
.ac-bandhead {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 2px;
  cursor: pointer;
  user-select: none;
  font-size: 11.5px;
  color: var(--ac-fg);
  border-bottom: 1px solid var(--ac-line-strong);
  margin-bottom: 5px;
  flex-wrap: nowrap; /* 同 `.ac-dayhead`：档名 + 张数必须同占一行 */
}
.ac-bandlabel {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ac-bandcount {
  margin-left: auto;
  color: var(--ac-fg-dim2);
  font-size: 10.5px;
  font-variant-numeric: tabular-nums;
  flex: 0 0 auto;
  white-space: nowrap;
}
.ac-band.collapsed .ac-bandbody {
  display: none;
}
/* 档内的日期小标题缩进一档 —— 层级靠位置说，不靠字号（字号已经压到 11.5px 了） */
.ac-bandbody .ac-day {
  margin-left: 4px;
}
/* 距原点角标：左下角。左上角是「已选序号」、右下角是「正射 / 无位置」，只剩这里。
   tabular-nums 让一列格子的数字对齐（45 / 1156 混排时不会左右跳）。 */
.ac-thumb-dist {
  position: absolute;
  left: 2px;
  bottom: 2px;
  padding: 1px 3px;
  border-radius: 3px;
  background: rgba(0, 0, 0, 0.72);
  color: #bae0ff;
  font-size: 9px;
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
}
/* ── 收起态（2026-09-17 改）：**一列缩略图窄栏**，口径照抄照片查看器的手机端窄轨 ──
   旧版收起后整个列表 `display:none`、只剩 44px 的栏头 —— 用户收起就看不见照片了，
   与「收起 = 让出宽度但还能扫图」的预期相反。
   现在：宽度收到 108px，缩略图从 3 列网格改成**单列**（`.ac-thumbs` 1fr），
   栏头只留开合按钮（标题隐藏），视图切换竖排 —— 与 `.iv-gallery-side` 的窄轨一致。 */
.ac-photos.ac-collapsed {
  flex-basis: 108px;
}
.ac-photos.ac-collapsed .ac-photos-title {
  display: none;
}
.ac-photos.ac-collapsed .ac-photos-head {
  justify-content: center;
  padding: 8px 4px 6px;
}
/* 单列：与照片查看器窄轨同一观感（一张一行，纵向滑动扫图） */
.ac-photos.ac-collapsed .ac-thumbs {
  grid-template-columns: 1fr;
}
/* 视图切换竖排，字号压一档才塞得进 108px */
.ac-photos.ac-collapsed .ac-modebar {
  flex-direction: column;
  gap: 3px;
  padding: 5px 6px;
}
/* ⚠️ 竖排后主轴变成**纵向**，`flex: 1 1 0` 的 basis=0 会落在**高度**上 →
   按钮被压成 8px（实测），文字全被裁掉。必须显式改回按内容定高。 */
.ac-photos.ac-collapsed .ac-mode {
  flex: 0 0 auto;
  font-size: 10.5px;
  padding: 2px 1px;
}
.ac-photos.ac-collapsed .ac-photo-list {
  padding: 5px 6px 10px;
}

/* ═══════════════════════════════════════
   地图左下角入口（L.Control.AIChatEntry）
   与左上角坐标、右上角照片筛选、右下角图层控件并列的第四个角。
   外观**复用 Leaflet 原生 `leaflet-bar`**（白底方块、自带圆角/阴影/hover），
   尺寸**跟随右下角图层控件**：36×36 / `leaflet-touch` 下 44×44（2026-09-24 用户要求，见下），
   这里只做两件事：把图标居中、给它 DeepSeek 品牌色。
   2026-09-18：字形从 🤖 换成 **DeepSeek 官方图标**（`dsIcon()` 内联 SVG）。
   ⚠️ 本控件挂在 `.ac-root` **外面** → 取不到 `.ac-root` 上的 `--ac-*` 令牌，
      所以颜色必须就地写死（引 `var(--ac-ds)` 会静默失效）。
   ⚠️ 不再需要 emoji 字体栈与「emoji 比同号文字大一圈」的字号补偿 ——
      SVG 的尺寸由 `width`/`height` 属性决定，跟 `font-size` 无关（那条铁律只对字形成立）。
   ═══════════════════════════════════════ */
.ac-entry .ac-entry-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  color: #4d6bfe; /* DeepSeek 品牌色：白底方块上对比度 4.4:1，够看 */
  text-decoration: none;
  cursor: pointer;
  /* ── 尺寸对齐右下角图层控件（2026-09-24 用户要求）─────────────────
     目标 = `.leaflet-control-layers-toggle` 的**内容**尺寸：36px / `leaflet-touch` 下 44px。
     ⚠️⚠️ 不要写死成某一个值：Leaflet 原生就是**两档**（`assets/leaflet.css`
        `.leaflet-control-layers-toggle{36}` + `.leaflet-touch ...{44}`），
        跟随它才叫「一样大」满屏一致 —— 触屏 Win 上 `L.Browser.touch` 为真、
        `leaflet-touch` 常驻 ⇒ 那台机器上图层控件本来就是 44，只写 36 反而更小。
     ⚠️ 特异性：`.ac-entry .ac-entry-btn`(0,2,0) > `.leaflet-bar a`(0,1,1)；
        下面 `leaflet-touch` 那条 (0,3,0) > `.leaflet-touch .leaflet-bar a`(0,2,1)。两条都压得住原生。
     ⚠️ 只改**内容**尺寸：`.leaflet-touch .leaflet-bar` 自己有 2px 边框（原生规则），
        所以触屏下本控件外框 = 44+4 = 48，与图层控件的 48 一致（别自己去补 border，会变 4px）。 */
  width: 36px;
  height: 36px;
}
/* 字形跟着方块等比放大（原 17px 配 30px 方块；方块变大后不跟着改会显得漂在中间）。
   24px / 44px = 0.55，与原生图层图标（26px / 44px）观感一致。 */
.ac-entry .ac-entry-btn svg {
  width: 20px;
  height: 20px;
}
.leaflet-touch .ac-entry .ac-entry-btn {
  width: 44px;
  height: 44px;
}
.leaflet-touch .ac-entry .ac-entry-btn svg {
  width: 24px;
  height: 24px;
}
.ac-entry .ac-entry-btn:hover {
  background: #f4f4f4;
  color: #3a55e0;
}

/* ── 灰态：概略层（当前视口只有「共 N 张」聚合点）不可 AI 分析 ──
   2026-09-24 用户要求：原来是「按钮亮着、点了才弹提示」，改成**先灰掉、不可点**。
   判据同筛选面板的「⚠️ 放大地图后可筛选」（同一个 `_aggCells`，见 AIChat 的 `syncAggOff`）。
   颜色走中性灰：底仍是 Leaflet 原生方块的 `#f4f4f4`，只把 DeepSeek 蓝褪成灰，
   这样「灰了」一眼可见、却不会被误读成「这个控件坏了/被删了」。
   ⚠️ `.ac-entry .ac-entry-btn:hover`（0,3,0）与首条灰态规则同特异性 —— 靠**写在后面**赢；
      主动写一条 (0,4,0) 的 `:hover` 兜底，免得将来有人挪动本段位置就漏出蓝 hover。 */
.ac-entry .ac-entry-btn.ac-entry-off,
.ac-entry .ac-entry-btn.ac-entry-off:hover {
  color: #c4c8ce;
  background: #f4f4f4;
  cursor: not-allowed;
}

/* ── 灰态常驻气泡「放大到具体照片后可 AI 分析」（2026-09-24）──
   用户要求：「提示明显一点」。原先这条说明只写在 `a.title` 里 —— 原生 tooltip 要 hover
   一秒才出现、黑底小字、样式完全不可控，手机上没有 hover ⇒ 等于没有提示。
   这里把它做成**看得见的**小气泡，跟灰态同步出现/消失；`title` 按用户要求保留给鼠标复核。
   ⚠️ 位置一律相对（`left: 0` + `bottom: calc(100% + 8px)`），**不写绝对 px**：
      `.ac-entry` 桌面 36px / `leaflet-touch` 下 44px，写死必歪（同 `.fr-tips` 那条红线）。
   ⚠️⚠️ **必须挂按钮「上方」**，不能挂右侧：左下角那条**底部带**在桌面/手机都被占满 ——
      按钮距底 12..42、`#beianBar`（fixed、bottom:6、手机上要折 2 行）从底边往上铺、
      `.fr-tips` 的左下气泡又在距底 50 往上。挂右侧只有距底 25..50 那 25px 缝隙，
      气泡高 28px 根本塞不下（实测过：右侧方案与备案条直接相交，`probe-firstrun-ai` C1k FAIL）。
   ⚠️ 上方被 `.fr-tips` 占着 ⇒ 两者**互斥**：`index.html` 弹提示时给 `body` 挂 `fr-tips-on`，
      这里把气泡收起来（见文件末尾那条规则）。首访先看「左下角是 AI 解析」，收起后气泡再来。
   ⚠️ `pointer-events: none`：这是常驻浮层，绝不能抢地图拖拽，也不能挡住按钮本体。
   ⚠️ 三角用 `border` 画，**不用 CSS `content` 拼 `▸`**（缺字回退＝豆腐块，项目红线）。 */
.ac-entry {
  position: relative;
}
.ac-entry .ac-entry-hint {
  position: absolute;
  left: 0;
  bottom: calc(100% + 8px);
  box-sizing: border-box;
  padding: 5px 9px;
  background: #fff;
  color: #41464e; /* 白底上 9.4:1，比原生 title 的黑底白字稍软，但仍远高于 AA */
  font-family: "Microsoft YaHei", "PingFang SC", -apple-system, sans-serif;
  font-size: 12px;
  line-height: 16px;
  white-space: nowrap;
  border: 1px solid #d5d9e0;
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
  /* 隐藏态：不占位、不吃事件、不能挡住地图（`visibility` 而非 `display`，
     这样 `transition` 才有效果 —— `display` 切换会直接跳变） */
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px); /* 从下往上 4px 淡入 */
  pointer-events: none;
  transition:
    opacity 0.18s ease,
    transform 0.18s ease,
    visibility 0.18s;
}
/* 指向按钮的小三角（贴在气泡下缘外，x 由 JS 现算 —— 见 `--ac-hint-arrow-x`） */
.ac-entry .ac-entry-hint::before {
  content: "";
  position: absolute;
  left: var(--ac-hint-arrow-x, 10px);
  bottom: -5px;
  width: 0;
  height: 0;
  border: 5px solid transparent;
  border-bottom-width: 0;
  border-top-color: #fff;
}
/* 灰态才现身。⚠️ 用 `~`（按钮是 hint 的前兄弟，DOM 顺序由 `onAdd` 保证）——
   条件直接读按钮上的 `.ac-entry-off`，不另加一层 JS 状态，避免两处不同步。 */
.ac-entry .ac-entry-btn.ac-entry-off ~ .ac-entry-hint {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
/* 首次提示还在屏上时让位（两条都挂按钮上方、同位置）。
   ⚠️ 选择器必须比上面那条 (0,4,0) 更具体才压得住 —— 这里 (0,5,0)。 */
body.fr-tips-on .ac-entry .ac-entry-btn.ac-entry-off ~ .ac-entry-hint {
  opacity: 0;
  visibility: hidden;
  transform: translateY(4px);
}
@media (prefers-reduced-motion: reduce) {
  .ac-entry .ac-entry-hint {
    transition: none;
  }
}

/* ═══════════════════════════════════════
   缩略图放大预览浮层（2026-09-18）
   右栏 `.ac-thumb` 与对话里的 `.ac-bphoto` / `.ac-chip` 悬停（或键盘聚焦）时弹出。
   ⚠️⚠️ 浮层挂 `document.body`、**不在 `.ac-root` 内**：
     ① `.ac-shell` 是 `overflow: hidden`，放进去一放大就被裁掉；
     ② 因此**取不到 `--ac-*` 令牌**（同 `.ac-entry` 的坑），颜色一律就地写死。
   z-index 必须高于 `.ac-root` 的 13000。
   `pointer-events: none`：浮层跟在指针旁边，若能命中指针就会自己把 hover 顶掉。
   ═══════════════════════════════════════ */
.ac-zoom {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 13100;
  display: none;
  box-sizing: border-box;
  max-width: 340px;
  padding: 5px 5px 0;
  background: rgba(12, 14, 18, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.6);
  pointer-events: none;
  font-family: "Microsoft YaHei", "PingFang SC", -apple-system, sans-serif;
  color: #e8eef6;
}
.ac-zoom.ac-zoom-on {
  display: block;
}
.ac-zoom-img {
  display: block;
  width: auto;
  height: auto;
  max-width: 328px;
  max-height: 250px;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.05);
}
/* 没有可用源时不弹浮层（`_zoomShow` 直接 return），这里只是兜底不让它冒出来 */
.ac-zoom-ph {
  display: none;
}
.ac-zoom-cap {
  max-width: 328px;
  padding: 5px 2px 4px;
  font-size: 11.5px;
  line-height: 1.4;
  color: #b9c6d6;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── Toast ── */
.ac-toast {
  position: absolute;
  left: 50%;
  bottom: 92px;
  transform: translateX(-50%);
  background: rgba(20, 22, 28, 0.96);
  border: 1px solid var(--ac-line-strong);
  color: var(--ac-fg);
  font-size: 12px;
  padding: 7px 14px;
  border-radius: 16px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
  opacity: 1;
  transition: opacity 0.25s;
  pointer-events: none;
  z-index: 3;
}
.ac-toast-out {
  opacity: 0;
}

/* ── 滚动条（深色细滚动条，避免默认亮色条破坏观感） ── */
.ac-msgs::-webkit-scrollbar,
.ac-sess-list::-webkit-scrollbar,
.ac-photo-list::-webkit-scrollbar,
.ac-reason-body::-webkit-scrollbar,
.ac-input::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
.ac-msgs::-webkit-scrollbar-thumb,
.ac-sess-list::-webkit-scrollbar-thumb,
.ac-photo-list::-webkit-scrollbar-thumb,
.ac-reason-body::-webkit-scrollbar-thumb,
.ac-input::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.16);
  border-radius: 4px;
}
.ac-msgs::-webkit-scrollbar-thumb:hover,
.ac-photo-list::-webkit-scrollbar-thumb:hover {
  background: rgba(255, 255, 255, 0.28);
}
.ac-msgs::-webkit-scrollbar-track,
.ac-photo-list::-webkit-scrollbar-track {
  background: transparent;
}

/* ═══════════════════════════════════════
   窄屏（≤900px）：竖排 + 照片列表做成**二级页**
   2026-09-18 用户要求「AI对话手机界面可以简化一下，选取照片的做成二级打开」。
   旧形态是**底部横排胶片条**（占 36% 高、缩略图 74px 宽、日期头挤在胶片中间）——
   手机上一屏本来就窄，对话区被压掉三分之一，挑图时每屏只看得到 4 张；
   而且它和「收起成 34px 栏头」两态混在一起（既占位、又不敢真收起）。
   新形态：
     · 对话页只留 composer 上的「🖼️ 选照片」入口（带 aria-expanded），列表**不占位**；
     · 点它 → 列表整屏推上来（`.ac-photos.ac-sheet-open`），栏头带「已选 n/5」+ ❌ 返回；
     · 缩略图**沿用桌面的 3 列网格**（不再另写胶片条规则）—— 全屏高度足够纵向滚动，
       3 列比 1 行 4 张更好点、也看得清。
   ⚠️ 判据只有 `.ac-sheet-open` 一个类：桌面端没有它的样式 → 类挂着也毫无影响
      （不需要媒体查询和 JS 判断同步，少一处「两边不一致」的隐患）。
   ═══════════════════════════════════════ */
@media (max-width: 900px) {
  .ac-shell {
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    border: 0;
    border-radius: 0;
  }
  /* ⚠️ 2026-09-17：Key 区搬到左栏底部后，这里**不能再整条隐藏左栏** ——
     否则窄屏下用户根本没有填 Key 的地方（界面直接不可用）。改成「只保留 Key 那一条」：
     栏头与会话列表隐藏，左栏退化成顶部的 Key 条。 */
  .ac-side {
    flex: 0 0 auto;
    border-right: 0;
    border-bottom: 1px solid var(--ac-line);
  }
  .ac-side-head,
  .ac-sess-list {
    display: none;
  }
  /* ⚠️ 窄屏下左栏本来就已经退化成「Key 条」，再折叠会连 Key 都藏掉 → 强制还原。
     折叠是**桌面端**为了让出横向空间而存在的操作，窄屏没有这个诉求。 */
  .ac-side.ac-collapsed {
    flex-basis: auto;
  }
  .ac-side.ac-collapsed .ac-keybox {
    display: block;
  }
  /* ⚠️ 折叠态的小卡列（`.ac-side.ac-collapsed .ac-sess-list`）优先级高于上面那条
     `.ac-sess-list { display: none }`，窄屏必须再显式压一次，否则窄屏会出现
     「Key 条 + 一排会话小卡」的错位形态。 */
  .ac-side.ac-collapsed .ac-sess-list,
  .ac-side.ac-collapsed .ac-key-mini {
    display: none;
  }
  /* 折叠态藏掉的摘要行也要还回来 —— 窄屏下 Key 只剩这一条入口。
     ⚠️ 必须排除编辑态：`.ac-side.ac-collapsed .ac-keybar`(0,3,0) 会压过
        `.ac-keybox-editing .ac-keybar{display:none}`(0,2,0) → 编辑时输入框和摘要行
        会同屏出现（实测踩到，见探针 S4b）。`:not()` 让这条只在非编辑态生效。 */
  .ac-side.ac-collapsed .ac-keybox:not(.ac-keybox-editing) .ac-keybar {
    display: flex;
  }
  .ac-keybox {
    border-top: 0;
    padding: 6px 8px;
  }
  .ac-shell {
    flex-direction: column;
  }
  /* ② 照片列表 = 二级页：默认完全不占位 */
  .ac-photos {
    display: none;
  }
  /* 打开态：整屏覆盖（`.ac-shell` 在窄屏已是 `inset:0`，所以这一层就是全屏）。
     底色用**不透明**的 `--ac-bg`：它是二级页，下层对话不该透出来（否则像半透明弹层）。 */
  .ac-photos.ac-sheet-open {
    display: flex;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 30;
    border: 0;
    background: var(--ac-bg);
  }
  /* 二级页的栏头：标题 + 已选计数（`margin-left:auto` 把它推到 ❌ 左侧）+ ❌ 返回 */
  .ac-photos.ac-sheet-open .ac-photos-head {
    padding: calc(8px + env(safe-area-inset-top, 0px)) 10px 8px;
  }
  .ac-sheet-count {
    display: inline;
    margin-left: auto;
    font-size: 11.5px;
    color: var(--ac-fg-dim);
  }
  .ac-sheet-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    min-width: 34px;
    height: 30px;
    padding: 0;
    font-family: var(--ac-emoji-font);
    font-size: 15px;
  }
  /* 桌面那枚「收起/展开」在窄屏没有意义：二级页自带 ❌，没有「收窄成 108px」这个形态。
     ⚠️ 与 `.ac-sheet-close` 的显示规则同优先级（都是 0,2,0），靠**源码顺序**分胜负 ——
     这条必须写在上面那条**之后**。好在两者不共存（`.ac-photos-toggle` 与
     `.ac-sheet-close` 是两个不同按钮），不存在互相覆盖。 */
  .ac-photos-toggle {
    display: none;
  }
  /* 入口按钮（只在窄屏出现）：桌面右栏常驻，再来一个入口是重复 */
  .ac-pickbtn {
    display: inline-flex;
    align-items: center;
    margin-left: auto;
    font-family: var(--ac-emoji-font);
  }
  /* ⚠️ 入口占了「推到最右」的 `margin-left:auto`，窄屏的计数就贴在它右边 */
  .ac-pickcount {
    margin-left: 0;
  }
  /* 位置开关的括注（「屋顶俯拍 / 定位异常照片建议取消」）在手机上占一整行 → 省掉 */
  .ac-geo-hint {
    display: none;
  }
  .ac-main {
    min-height: 0;
  }
  .ac-photo-list {
    padding: 6px 8px calc(10px + env(safe-area-inset-bottom, 0px));
  }
}

/* ═══════════════════════════════════════
   导出为图片（2026-09-18）
   ═══════════════════════════════════════ */

/* ── 头部按钮：📷 导出当前对话 ──
   与 `.ac-close` 同样是 emoji 图标按钮 → `display:flex` 居中（铁律 1：原生 button 里的
   emoji 不 flex 居中就会偏下）。⚠️ **不吃 `margin-left:auto`**：那个 auto 留给右侧的
   关闭键，它会把关闭键连同这个按钮一起推到最右边，两个按钮自然靠拢。 */
.ac-export-btn {
  flex: 0 0 auto;
  width: 30px;
  height: 26px;
  border: 0;
  background: transparent;
  color: var(--ac-fg-dim);
  font-family: var(--ac-emoji-font);
  font-size: 14px;
  border-radius: var(--ac-radius);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ac-export-btn:hover {
  background: var(--ac-surface-hover);
  color: var(--ac-fg);
}
/* 没有可导出的内容时是真 `disabled`（点击无响应），所以视觉上必须给出区分 */
.ac-export-btn:disabled {
  color: var(--ac-fg-dim2);
  opacity: 0.55;
  cursor: default;
  background: transparent;
}
.ac-exporting {
  color: var(--ac-accent);
}

/* ── 导出卡片本体 ──
   ⚠️⚠️ 三个前提，缺一个导出件就崩：
     ① 它**不在 `.ac-root` 内** → 下面这份 `--ac-*` 只是**兜底**；真实值由 JS 用
        `getComputedStyle` 从面板上抄过来、以行内样式覆盖（换肤自动跟随）。
        留兜底是因为「抄令牌」依赖面板存在（导出总在面板打开时才可能发生，但别赌）。
     ② 它会被序列化进 `SVG <foreignObject>`，在那个独立文档里**继承不到宿主页的任何样式**
        → 字体栈、底色、`box-sizing` 全部自己写。
     ③ 宿主页那份全局 `*{box-sizing;margin;padding}` 在独立文档里**不存在** → 必须用
        `:where()` 复刻一份：`:where` 的权重是 0，能压过 UA 默认样式，又压不过任何
        `.ac-*` 类规则（如 `.ac-msg{margin-bottom}`、`.ac-text p{margin}`）—— 这正是要的分寸，
        换成 `.ac-export *{margin:0}` 就会把那些间距一起抹掉。 */
.ac-export {
  box-sizing: border-box;
  padding: 20px;
  background: #0b0d11;
  color: #e8eef6;
  font-family: "Microsoft YaHei", "PingFang SC", -apple-system, sans-serif;
  font-size: 13px;
  line-height: 1.6;
  /* 兜底令牌（真实值由 JS 覆盖，见 ①） */
  --ac-bg: #0b0d11;
  --ac-surface: rgba(255, 255, 255, 0.06);
  --ac-surface-hover: rgba(255, 255, 255, 0.13);
  --ac-surface-active: rgba(255, 255, 255, 0.2);
  --ac-line: rgba(255, 255, 255, 0.12);
  --ac-line-strong: rgba(255, 255, 255, 0.28);
  --ac-fg: #e8eef6;
  --ac-fg-dim: #93a4b8;
  --ac-fg-dim2: #6f8098;
  --ac-accent: #3ea6ff;
  --ac-accent-soft: rgba(62, 166, 255, 0.18);
  --ac-accent-dim: rgba(62, 166, 255, 0.16);
  --ac-accent-fg: #cfe8ff;
  --ac-danger: #ff5c5c;
  --ac-ok: #52c41a;
  --ac-warn: #e0a33a;
  --ac-emoji-font: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji",
    "Segoe UI Symbol", sans-serif;
  --ac-radius: 8px;
}
.ac-export
  :where(p, ul, ol, li, dl, dt, dd, blockquote, figure, h1, h2, h3, h4, h5, h6, hr, pre, table, details, summary, input, button, textarea, fieldset) {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
.ac-export-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--ac-line);
}
.ac-export-brand {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}
.ac-export-ico {
  flex: 0 0 auto;
  display: flex;
  color: #4d6bfe;
}
.ac-export-name {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.3px;
}
.ac-export-model {
  flex: 0 0 auto;
  margin-left: auto;
  font-size: 11px;
  color: var(--ac-fg-dim);
}
.ac-export-sub {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 0 3px;
}
.ac-export-sess {
  min-width: 0;
  font-size: 12.5px;
  font-weight: 600;
  overflow-wrap: anywhere;
}
.ac-export-stamp {
  flex: 0 0 auto;
  margin-left: auto;
  font-size: 11px;
  color: var(--ac-fg-dim2);
}
/* 消息区：屏幕上的滚动容器在导出里必须放开，否则超过一屏的内容全被裁掉 */
.ac-export-msgs {
  flex: none;
  height: auto;
  max-height: none;
  overflow: visible;
  padding: 8px 0 0;
  scroll-behavior: auto;
}
/* 代码块 / 表格在屏幕上靠横向滚动看全 —— 导出件是静态图，滚不了
   → 只在这个「打印上下文」里放开折行（屏幕上的代码保持 `pre`，缩进是语义） */
.ac-export .ac-pre-bd {
  overflow-x: visible;
}
.ac-export .ac-pre-bd code {
  white-space: pre-wrap;
  word-break: break-word;
}
.ac-export .ac-tblwrap {
  overflow-x: visible;
}
/* 代码块的「复制」按钮在静态图里是死的（点不到）—— 而且截图里的人会以为它能点。
   导出件里直接不画它。 */
.ac-export .ac-pre-copy {
  display: none;
}
.ac-export-foot {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 12px;
  padding-top: 9px;
  border-top: 1px solid var(--ac-line);
  font-size: 11px;
  color: var(--ac-fg-dim2);
}
.ac-export-foot-tx:last-child {
  margin-left: auto;
}
