/* ============================================================
   山河纪 · 全局 AI 智能助手（悬浮球 + 面板）样式
   ------------------------------------------------------------
   ★ 全文件**不出现任何写死的颜色**：所有颜色、圆角外的视觉都走
     主题 CSS 变量（themes.css 的 :root 与 html[data-theme="…"] 两套）。
     换皮肤时不需要 JS 重绘，也不会出现「深色主题里一块白斑」。
     用到的变量（每一个都在 11 套主题里都存在）：
       --panel / --panel2 / --bg2 / --tx / --tx2 / --tx3
       --line / --line2 / --accent / --accent2 / --accentRGB
       --hlRGB / --shRGB / --red / --redTx / --onAccent / --btnGrad
       --cardF（主题的卡片渐变；缺失时回落 --panel）/ --serif / --sans

   ★ 尺寸单位一律用 rem：themes.css 里 html{font-size:calc(15px*--fsBase*--fsScale)}，
     所以「明亮课堂 +10%」「长者关怀 20px 起」以及无障碍里的无级字号调节，
     本控件会自动跟着缩放，不必单独适配。

   ★ 层级：420 —— 这个数是实测逼出来的，不是随手写的：
     全站浮层从低到高是 弹窗遮罩 200 · 命令面板 300 · 主题面板 320 ·
     用户下拉 340 · **临时提示（toast）400**；而 toast 的定位是
     `right:22px; bottom:22px`（见 v3.js / console.js / literature-view.js），
     **正好压住悬浮球**。实测过：刚登录时弹出一条成就 toast，那一刻点球
     完全没有反应（第一下被 toast 吃掉），第二次才生效 —— 助手球必须排在
     toast 之上，否则「新用户第一次点助手」这条最关键的路径会偶发失灵。
     常驻型助手控件排在通知层之上是通行做法（聊天类挂件都在最上层）。
     代价（助手也会压住更低的遮罩层）由下面一条 `body:has(...)` 规则补掉：
     任何页面级弹窗一打开，助手整体让位。
     ⚠️ 若团队更希望助手永远低于弹窗（放弃上面那条 toast 修复），把下面
     #shj-ai 的 420 改回 190 即可，代价是「toast 吃掉第一次点击」会回来。

   ★ 本文件与其它栏目样式同源：不用 .btn/.inp 这些全站类名（它们的
     内边距是给内容区排版的），一律用 shjai- 前缀自己的类，避免任何越界。
   ============================================================ */

/* ---------- 挂载点：零尺寸锚点，不占据文档流、不拦截点击 ---------- */
#shj-ai {
  position: fixed;
  right: 0;
  bottom: 0;
  width: 0;
  height: 0;
  z-index: 420;
  font-family: var(--sans);
}

/* ---------- 有弹窗 / 主题面板 / 命令面板打开时：整个让位 ----------
   420 这一层让悬浮球能压住 toast（见文件头说明），代价是它同时也会压住
   那些 z-index 更低的遮罩层。实测过代价有多大：1280 宽下打开主题面板，
   助手面板覆盖主题面板 15% 的面积，最右一列的主题卡点不动
   （elementFromPoint 命中的是助手的建议提问按钮）—— 那就是在破坏别人做完的功能。
   :has() 一行解决：页面级遮罩一出现，助手整体收起；遮罩关掉，助手按原状态回来
   （不写 JS、不动 localStorage，所以「用户自己的展开/收起偏好」不会被污染）。
   · #mask       弹窗（影视播放页 / 详情）z200
   · #cmd-mask   全局检索命令面板 z300
   · #th-mask    主题面板 z320
   · #lf-detail  物种详情 z400
   ★ 这里原先写的「栏目内的 .m-modal 是 z4000，本身就盖得住助手，无需在此再列」
     是**错的**：盖得住 = 助手被压在它下面，而 55% 黑遮罩下的球**看得见、点不动**
     （实测 elementFromPoint 命中 .m-sg-ov）。所以四条显式判断只作为**快路径**保留，
     真正兜底的是下面那条通用规则 —— 它不认类名，只认「球心那点上最顶层是不是球自己」。 */
body:has(#mask.on) #shj-ai,
body:has(#cmd-mask.on) #shj-ai,
body:has(#th-mask.on) #shj-ai,
body:has(#lf-detail.on) #shj-ai { display: none; }

/* ---------- 让位（通用判据）----------
   由 ai-assistant.js 的 evaluateYield() 维护这个属性：
   只要「球心那个点上最顶层的元素」不是球自己（被任何元素盖住 —— 栏目模态、
   全屏引导、将来任何新加的遮罩），就加上 data-yield=1 整体收起；
   盖住它的东西一消失，下一拍复查就恢复。
   为什么不在这里继续枚举类名：这条链已经长了四回（上面那四个），每加一个栏目模态
   就要再补一条，而且**没有任何东西会提醒我们漏了** —— 漏掉的表现就是
   「球还在、点不动」，最容易被当成偶发。判据改成现测事实后，新模态自动被覆盖。 */
#shj-ai[data-yield="1"] { display: none; }

/* ================= 悬浮球（收起态 / 再唤起入口） ================= */
.shjai-ball {
  position: fixed;
  right: 1.0667rem;
  bottom: 1.0667rem;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  max-width: calc(100vw - 2.1333rem);
  background: var(--btnGrad);
  color: var(--onAccent);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .5rem .9333rem;
  font-family: var(--sans);
  font-size: .8667rem;
  font-weight: 600;
  letter-spacing: 1.5px;
  cursor: pointer;
  box-shadow: 0 .4rem 1.1rem rgba(var(--shRGB), .38);
  transition: transform .18s ease, box-shadow .18s ease, filter .18s ease;
}
.shjai-ball:hover { filter: brightness(1.08); transform: translateY(-1px); }
.shjai-ball:focus-visible { outline: 2px solid rgba(var(--accentRGB), .75); outline-offset: 2px; }
.shjai-ball svg { width: 1.0667rem; height: 1.0667rem; flex: 0 0 auto; display: block; }
.shjai-ball .shjai-ball-t { white-space: nowrap; }

/* 展开时球变成「收起」语义：图标旋转 180°，文字换成「收起」 */
#shj-ai[data-open="1"] .shjai-ball svg { transform: rotate(180deg); }

/* ================= 面板 ================= */
.shjai-panel {
  position: fixed;
  right: 1.0667rem;
  bottom: 4.9333rem;
  z-index: 2;
  display: none;
  flex-direction: column;
  width: min(23.4667rem, calc(100vw - 2.1333rem));
  max-height: min(72vh, 38rem);
  min-height: 0;
  background: var(--cardF, var(--panel));
  color: var(--tx);
  border: 1px solid var(--line);
  border-radius: .9333rem;
  box-shadow: 0 .9333rem 2.4rem rgba(var(--shRGB), .42);
  overflow: hidden;
  font-size: .9333rem;
  line-height: 1.6;
}
#shj-ai[data-open="1"] .shjai-panel { display: flex; }

/* ---------- 头部 ---------- */
.shjai-hd {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: .4rem;
  padding: .6rem .6rem .6rem .9333rem;
  border-bottom: 1px solid var(--line2);
  background: rgba(var(--hlRGB), .03);
}
.shjai-hd-t {
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--serif);
  font-size: 1rem;
  letter-spacing: 2px;
  color: var(--accent2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.shjai-x {
  flex: 0 0 auto;
  width: 1.8rem;
  height: 1.8rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 1px solid var(--line2);
  border-radius: .5rem;
  color: var(--tx2);
  font-family: var(--sans);
  font-size: .9rem;
  line-height: 1;
  cursor: pointer;
}
.shjai-x:hover { color: var(--accent); border-color: var(--accent); }
.shjai-x:focus-visible { outline: 2px solid rgba(var(--accentRGB), .7); outline-offset: 1px; }

/* ---------- 滚动区（辅助块 + 对话） ---------- */
.shjai-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: .8rem .9333rem;
  display: flex;
  flex-direction: column;
  gap: .6667rem;
}

/* ---------- 「这一页怎么用」辅助块 ---------- */
.shjai-help {
  border: 1px solid var(--line2);
  border-radius: .75rem;
  background: var(--panel2, var(--bg2));
  padding: .6667rem .8rem;
}
.shjai-help-h {
  font-family: var(--serif);
  font-size: .9333rem;
  letter-spacing: 1.5px;
  color: var(--accent);
  margin: 0 0 .2667rem;
}
.shjai-help-h .shjai-help-n { color: var(--accent2); }
.shjai-help-p { margin: .1333rem 0 0; color: var(--tx2); font-size: .8667rem; }
.shjai-help-sec { margin-top: .5333rem; }
.shjai-help-sec-t {
  font-size: .8rem;
  letter-spacing: 1.5px;
  color: var(--accent2);
  margin-bottom: .1333rem;
}
.shjai-help ol, .shjai-help ul {
  margin: 0;
  padding-left: 1.1333rem;
  color: var(--tx2);
  font-size: .8667rem;
}
.shjai-help li { margin: .1333rem 0; overflow-wrap: anywhere; }
.shjai-help .shjai-tips li { color: var(--tx3); }
.shjai-help details {
  margin-top: .4rem;
  border-top: 1px dashed var(--line2);
  padding-top: .4rem;
}
.shjai-help details summary {
  cursor: pointer;
  color: var(--tx2);
  font-size: .8rem;
  letter-spacing: 1px;
  list-style: none;
}
.shjai-help details summary::-webkit-details-marker { display: none; }
.shjai-help details summary::before { content: "▸ "; color: var(--accent); }
.shjai-help details[open] summary::before { content: "▾ "; }
.shjai-faq-q { color: var(--tx2); font-size: .8333rem; margin-top: .4rem; }
.shjai-faq-a { color: var(--tx3); font-size: .8333rem; margin-top: .1333rem; overflow-wrap: anywhere; }

/* ---------- 建议提问（点一下直接发出） ---------- */
.shjai-asks { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .5333rem; }
.shjai-ask {
  max-width: 100%;
  background: transparent;
  border: 1px dashed var(--line);
  border-radius: 999px;
  color: var(--tx3);
  padding: .2333rem .6rem;
  font-family: var(--sans);
  font-size: .8rem;
  text-align: left;
  cursor: pointer;
}
.shjai-ask:hover { color: var(--accent); border-color: var(--accent); }
.shjai-ask:focus-visible { outline: 2px solid rgba(var(--accentRGB), .6); outline-offset: 1px; }

/* ---------- 对话 ---------- */
.shjai-log { display: flex; flex-direction: column; gap: .5333rem; }
.shjai-msg {
  border-radius: .75rem;
  padding: .4667rem .6667rem;
  font-size: .9rem;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}
.shjai-msg.me {
  align-self: flex-end;
  max-width: 88%;
  background: rgba(var(--accentRGB), .16);
  border: 1px solid var(--line);
  color: var(--tx);
}
.shjai-msg.ai {
  align-self: stretch;
  background: var(--panel2, var(--bg2));
  border: 1px solid var(--line2);
  color: var(--tx);
}
.shjai-msg.note {
  align-self: stretch;
  padding: 0;
  background: transparent;
  border: 0;
  color: var(--tx3);
  font-size: .8rem;
  letter-spacing: 1px;
  text-align: center;
}
.shjai-msg.err {
  align-self: stretch;
  background: transparent;
  border: 1px dashed var(--line);
  color: var(--redTx, var(--red));
  font-size: .8667rem;
}
.shjai-src { display: block; margin-top: .2667rem; color: var(--tx3); font-size: .75rem; letter-spacing: .5px; }

/* 等待态：三点呼吸 */
.shjai-load { display: inline-flex; align-items: center; gap: .2667rem; }
.shjai-load i {
  width: .3333rem;
  height: .3333rem;
  border-radius: 50%;
  background: var(--tx3);
  animation: shjai-dot 1.1s ease-in-out infinite;
}
.shjai-load i:nth-child(2) { animation-delay: .16s; }
.shjai-load i:nth-child(3) { animation-delay: .32s; }
@keyframes shjai-dot {
  0%, 80%, 100% { opacity: .28; transform: translateY(0); }
  40% { opacity: 1; transform: translateY(-.1333rem); }
}

/* ---------- 输入区 ---------- */
.shjai-form {
  flex: 0 0 auto;
  display: flex;
  gap: .4rem;
  padding: .6rem .9333rem;
  border-top: 1px solid var(--line2);
  background: rgba(var(--hlRGB), .03);
}
.shjai-in {
  flex: 1 1 auto;
  min-width: 0;
  background: rgba(var(--hlRGB), .03);
  border: 1px solid var(--line2);
  border-radius: .6rem;
  color: var(--tx);
  padding: .4667rem .6667rem;
  font-family: var(--sans);
  font-size: .9rem;
  outline: none;
}
.shjai-in::placeholder { color: var(--tx3); }
.shjai-in:focus { border-color: var(--accent); }
.shjai-in:focus-visible { outline: 2px solid rgba(var(--accentRGB), .45); outline-offset: 0; }
.shjai-send {
  flex: 0 0 auto;
  background: var(--btnGrad);
  color: var(--onAccent);
  border: 1px solid var(--line);
  border-radius: .6rem;
  padding: .4667rem .8rem;
  font-family: var(--sans);
  font-size: .9rem;
  font-weight: 600;
  letter-spacing: 1px;
  cursor: pointer;
}
.shjai-send:hover { filter: brightness(1.08); }
.shjai-send:focus-visible { outline: 2px solid rgba(var(--accentRGB), .7); outline-offset: 1px; }
.shjai-send:disabled { opacity: .5; cursor: not-allowed; filter: none; }

/* ---------- 底部一行说明（配额 / 页面上下文） ---------- */
.shjai-foot {
  flex: 0 0 auto;
  padding: 0 .9333rem .5333rem;
  color: var(--tx3);
  font-size: .7333rem;
  letter-spacing: .5px;
  background: rgba(var(--hlRGB), .03);
}

/* ---------- 无障碍：仅供读屏的文本 ---------- */
.shjai-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ================= 窄屏（折叠屏合起 / 手机） ================= */
/* 关键约束：面板必须近全宽但不溢出 —— 左右各留 0.6667rem，
   width:auto 由左右边距定宽（不用 100vw，避免滚动条宽度把页面顶出横向溢出）。 */
@media (max-width: 560px) {
  .shjai-ball { right: .6rem; bottom: .6rem; padding: .4667rem .8rem; }
  .shjai-panel {
    left: .6667rem;
    right: .6667rem;
    bottom: 4.2667rem;
    width: auto;
    max-width: none;
    max-height: 70vh;
    border-radius: .8rem;
  }
  .shjai-body { padding: .6667rem .8rem; }
  .shjai-msg.me { max-width: 94%; }
  .shjai-form { padding: .5333rem .8rem; }
  .shjai-foot { padding: 0 .8rem .4667rem; }
}

/* 超大字号（长者关怀 --fsBase:1.34 与无障碍放大）下：
   面板宽度按 rem 也变大，这里给一个屏幕占比上限，防止在窄屏顶出视口。 */
@media (max-width: 900px) {
  .shjai-panel { max-width: calc(100vw - 2.1333rem); }
}

/* ---------- 动效偏好 ---------- */
@media (prefers-reduced-motion: reduce) {
  .shjai-ball, .shjai-ball:hover { transition: none; transform: none; }
  .shjai-load i { animation: none; opacity: .7; }
}

/* 主题里的「减少动效 / 长者关怀」会把 --dur 设成 0（见 themes.css），
   本控件的过渡用固定时长，这里跟随站点口径再兜一层。 */
@media (prefers-reduced-motion: reduce) {
  .shjai-ball { transform: none !important; }
}
