/* =============================================================
 *  assistant.css
 *  教学站智能问答助教 · 聊天 widget 样式（SPEC-teaching-site-assistant-20260916 §2.5）
 *
 *  用法：由 scripts/build_site.py 在构建期注入到全部产物页面（源文件零改动）：
 *    <link rel="stylesheet" href="_shared/assistant.css">   （</head> 前）
 *    <script src="_shared/assistant.js" defer></script>     （<body> 后）
 *
 *  设计纪律：
 *    - 全部颜色走 design-tokens.css 变量（--ink / --accent / --rule …），
 *      暗色主题经 theme.css 令牌覆盖自动适配，本文件不写死任何颜色
 *    - 样式类一律 asst- 前缀，与 components.css 零冲突
 *    - DOM 由 assistant.js 动态注入，本文件不假设页面结构
 * ============================================================= */

/* ---------- 暗色主题精修（教学站 + 门户统一信号 <html data-theme="dark">） ----------
   设计目标：不是"能用"的反色，而是独立设计的夜间质感——
   ① FAB：深石板内底 + 更浓郁的紫罗兰渐变环 + 暗色专属呼吸辉光
      （⚠️ 亮色呼吸动画的 keyframes 会覆盖静态暗色投影，必须换暗色专属动画名）
   ② 面板：双色深空渐变 + 顶部微高光描边，悬浮于暗色页面之上
   ③ 头部：accent 微光渐变条；气泡/卡片/输入框逐层拉开明度差 */
[data-theme="dark"] .asst-fab {
  --asst-fab-inner: #171c2b;   /* 深石板内底：白 logo 圆盘如「月章」浮于暗环之上 */
  background:
    linear-gradient(var(--asst-fab-inner, #171c2b), var(--asst-fab-inner, #171c2b)) padding-box,
    conic-gradient(from 215deg,
      #c4b5fd 0%, #8b5cf6 28%, #4c1d95 52%,
      #8b5cf6 76%, #c4b5fd 100%) border-box;
  animation-name: asst-fab-breathe-dark;
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.55),
    0 8px 24px rgba(124, 92, 255, 0.28),
    0 20px 56px rgba(76, 29, 149, 0.30);
}
@keyframes asst-fab-breathe-dark {
  0%, 100% { box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.55),
    0 8px 24px rgba(124, 92, 255, 0.28),
    0 20px 56px rgba(76, 29, 149, 0.30); }
  50%      { box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.55),
    0 10px 30px rgba(139, 92, 246, 0.42),
    0 24px 64px rgba(76, 29, 149, 0.40); }
}
[data-theme="dark"] .asst-fab:hover {
  box-shadow:
    0 2px 8px rgba(0, 0, 0, 0.60),
    0 12px 34px rgba(139, 92, 246, 0.48),
    0 28px 72px rgba(76, 29, 149, 0.44);
}
[data-theme="dark"] .asst-fab.asst-fab-active {
  animation: none;
  box-shadow:
    0 2px 6px rgba(0, 0, 0, 0.60),
    0 10px 30px rgba(139, 92, 246, 0.46),
    0 22px 56px rgba(76, 29, 149, 0.36);
}
[data-theme="dark"] .asst-fab-logo {
  box-shadow: 0 0 0 1px rgba(196, 181, 253, 0.35),  /* 月章描边：logo 圆盘与暗环间的一线光 */
              inset 0 1px 3px rgba(0, 0, 0, 0.20);
}
[data-theme="dark"] .asst-head-logo {
  box-shadow: 0 0 0 1px rgba(196, 181, 253, 0.30), 0 1px 4px rgba(0, 0, 0, 0.40);
}

[data-theme="dark"] .asst-panel {
  border-color: rgba(138, 150, 196, 0.24);
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--bg2) 88%, transparent) 0%,
    color-mix(in srgb, var(--bg) 94%, transparent) 100%);
  box-shadow:
    0 12px 40px rgba(0, 0, 0, 0.50),
    0 4px 14px rgba(0, 0, 0, 0.35),
    inset 0 1px 0 rgba(232, 236, 245, 0.06);   /* 顶部微高光：面板的"天际线" */
}
[data-theme="dark"] .asst-head {
  background: linear-gradient(90deg, var(--accent-12), transparent 65%);
  border-bottom-color: var(--rule);
}
[data-theme="dark"] .asst-msg-bot {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.30);   /* 气泡与面板拉开明度差 */
}
[data-theme="dark"] .asst-msg-user {
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}
[data-theme="dark"] .asst-ref {
  background: color-mix(in srgb, var(--bg2) 60%, transparent);
  border-color: rgba(138, 150, 196, 0.16);
}
[data-theme="dark"] .asst-ref:hover {
  border-color: var(--accent);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.35), 0 0 0 1px var(--accent-30);
}
[data-theme="dark"] .asst-input {
  background: color-mix(in srgb, var(--bg) 80%, transparent);
}
[data-theme="dark"] .asst-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-12);      /* 聚焦辉光 */
}
[data-theme="dark"] .asst-send:hover {
  box-shadow: 0 2px 10px var(--accent-30);
}
[data-theme="dark"] .asst-msgs {
  scrollbar-color: var(--rule) transparent;
}

/* ---------- 悬浮入口 FAB（右下角 · 吉祥物 logo 光环按钮） ----------
   艺术加工设计（2026-09-16 张老师审美指令）：
   ① logo 不铺满——padding 留白内聚，logo 圆盘与按钮边缘之间有一圈「光晕环」
   ② 渐变描边光环——双层 background 技巧（padding-box 内底 + border-box 锥形渐变环）
   ③ 三层柔和投影——近景接触影 + 中景紫色环境影 + 远景弥散影
   ④ 呼吸微光——5s 周期的投影脉动（prefers-reduced-motion 时关闭）
   ⑤ 悬停抬升发光 + 高光扫过（::after 斜向 sheen）
   bottom 默认值；assistant.js 检测 .portal-back / .site-home-fab /
   .toc-expand-btn 等固定元素的重叠情况，动态抬高 style.bottom 避让 */
/* FAB 外层包裹：承载定位与自定义提示（FAB 本体 overflow:hidden 会裁剪提示，
   故提示作为包裹层内 FAB 的兄弟节点） */
.asst-fab-wrap {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 10000;   /* 全站最前：门户/讲义页最高 z-index 为 999（theme-toggle 等），抬到 10000 保底 */
  transition: bottom 0.2s ease;
}
/* 即时提示（悬停即现，替代有系统级 1-2s 延迟的原生 title） */
.asst-fab-tip {
  position: absolute;
  bottom: calc(100% + 10px);
  right: 0;
  white-space: nowrap;
  pointer-events: none;
  background: rgba(23, 28, 43, 0.94);
  color: #f2f4fa;
  border: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 0.75rem;
  line-height: 1;
  padding: 0.42rem 0.7rem;
  border-radius: 8px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.28);
  opacity: 0;
  transform: translateY(4px);
  visibility: hidden;
  transition: opacity 0.12s ease, transform 0.12s ease, visibility 0s linear 0.12s;
}
.asst-fab-tip::after {
  content: '';
  position: absolute;
  top: 100%;
  right: 24px;
  border: 5px solid transparent;
  border-top-color: rgba(23, 28, 43, 0.94);
}
.asst-fab-wrap:hover .asst-fab-tip,
.asst-fab:focus-visible ~ .asst-fab-tip {
  opacity: 1;
  transform: translateY(0);
  visibility: visible;
  transition: opacity 0.12s ease, transform 0.12s ease;   /* 进入零延迟，悬停即现 */
}
/* 面板打开时不再提示 */
.asst-fab-wrap:has(.asst-fab.asst-fab-active) .asst-fab-tip { display: none; }

.asst-fab {
  position: relative;
  width: 56px;
  height: 56px;
  padding: 6px;                 /* ① logo 内聚留白环 */
  border: 2px solid transparent; /* ② 渐变环由此显现（border-box 层） */
  border-radius: 50%;
  background:
    linear-gradient(var(--asst-fab-inner, #ffffff), var(--asst-fab-inner, #ffffff)) padding-box,
    conic-gradient(from 215deg,
      #c9a7ff 0%, #8b5cf6 28%, #5b21b6 52%,
      #8b5cf6 76%, #c9a7ff 100%) border-box;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  /* ③ 三层柔和投影（品牌紫色调） */
  box-shadow:
    0 1px 3px rgba(91, 33, 182, 0.18),
    0 6px 18px rgba(91, 33, 182, 0.22),
    0 18px 48px rgba(91, 33, 182, 0.16);
  transition: transform 0.22s cubic-bezier(0.34, 1.56, 0.64, 1),
              box-shadow 0.22s ease, bottom 0.2s ease;
  animation: asst-fab-breathe 5s ease-in-out infinite;  /* ④ 呼吸微光 */
  overflow: hidden;
}
@keyframes asst-fab-breathe {
  0%, 100% { box-shadow:
    0 1px 3px rgba(91, 33, 182, 0.18),
    0 6px 18px rgba(91, 33, 182, 0.22),
    0 18px 48px rgba(91, 33, 182, 0.16); }
  50%      { box-shadow:
    0 1px 3px rgba(91, 33, 182, 0.20),
    0 8px 24px rgba(91, 33, 182, 0.30),
    0 22px 56px rgba(91, 33, 182, 0.22); }
}
@media (prefers-reduced-motion: reduce) {
  .asst-fab { animation: none; }
  .asst-fab::after { display: none; }
}
/* ⑤ 悬停高光扫过层 */
.asst-fab::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: linear-gradient(115deg, transparent 30%, rgba(255, 255, 255, 0.45) 50%, transparent 68%);
  transform: translateX(-120%);
  transition: transform 0.55s ease;
  pointer-events: none;
}
.asst-fab:hover::after { transform: translateX(120%); }
.asst-fab:hover {
  transform: translateY(-2px) scale(1.05);
  box-shadow:
    0 2px 4px rgba(91, 33, 182, 0.20),
    0 10px 28px rgba(91, 33, 182, 0.32),
    0 26px 64px rgba(91, 33, 182, 0.26);
}
.asst-fab:focus-visible {
  outline: 2px solid #8b5cf6;
  outline-offset: 3px;
}
/* FAB 吉祥物 logo（留白环内居中，不铺满） */
.asst-fab-logo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
  display: block;
  box-shadow: inset 0 1px 3px rgba(91, 33, 182, 0.10);  /* 圆盘轻内陷质感 */
}
/* 面板头部同款小 logo */
.asst-head-logo {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  object-fit: cover;
  margin-right: 6px;
  vertical-align: -4px;
  box-shadow: 0 1px 4px rgba(91, 33, 182, 0.30);
}
/* 面板打开时 FAB 保持可见（再次点击可收起）：环增亮 + 微微下压 */
.asst-fab.asst-fab-active {
  transform: translateY(1px) scale(0.97);
  animation: none;
  box-shadow:
    0 1px 3px rgba(91, 33, 182, 0.22),
    0 8px 24px rgba(91, 33, 182, 0.34),
    0 20px 52px rgba(91, 33, 182, 0.24);
}
/* （暗色 FAB 规则已前移至文件顶部「暗色主题精修」区块，此处不再重复） */

/* ---------- 聊天面板（380×560，移动端全宽抽屉） ---------- */
.asst-panel {
  position: fixed;
  right: 18px;
  bottom: 82px;
  z-index: 10000;   /* 与 .asst-fab 同档，压过全站最高 999 */
  width: 380px;
  max-width: calc(100vw - 24px);
  height: 560px;
  max-height: calc(100vh - 110px);
  display: flex;
  flex-direction: column;
  border: 1px solid var(--accent-12);
  border-radius: var(--radius);
  background: var(--card-bg);
  -webkit-backdrop-filter: blur(14px);
          backdrop-filter: blur(14px);
  box-shadow: 0 12px 40px var(--accent-07), 0 4px 14px var(--accent-07);
  overflow: hidden;
  font-family: var(--font);
  color: var(--ink);
}
.asst-panel[hidden] { display: none; }

/* 头部 */
.asst-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--rule);
  font-size: var(--fs-sm);
  font-weight: 600;
  flex: 0 0 auto;
}
.asst-head .asst-head-title { flex: 1; }
.asst-head .asst-head-badge {
  font-size: var(--fs-tag);
  font-weight: 500;
  color: var(--muted);
  border: 1px solid var(--rule);
  border-radius: var(--radius-pill);
  padding: 0.1rem 0.5rem;
}
.asst-close {
  border: none;
  background: transparent;
  color: var(--muted);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.2rem 0.35rem;
  border-radius: 6px;
  transition: color 0.15s ease, background 0.15s ease;
}
.asst-close:hover { color: var(--ink); background: var(--bg2); }
.asst-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* 消息区 */
.asst-msgs {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent;
}
.asst-msg {
  max-width: 88%;
  padding: 0.55rem 0.8rem;
  border-radius: var(--radius);
  font-size: var(--fs-sm);
  line-height: 1.7;
  overflow-wrap: break-word;
  word-break: break-word;
  white-space: pre-wrap;
}
.asst-msg-user {
  align-self: flex-end;
  background: var(--accent-12);
  border: 1px solid var(--accent-30);
  border-bottom-right-radius: 4px;
}
.asst-msg-bot {
  align-self: flex-start;
  background: var(--bg2);
  border: 1px solid var(--rule);
  border-bottom-left-radius: 4px;
}
.asst-msg code {
  font-family: var(--font-mono);
  font-size: 0.86em;
  background: var(--accent-06);
  border-radius: 4px;
  padding: 0.05em 0.3em;
}
/* 降级模式徽标（检索模式 / 离线检索模式） */
.asst-mode-tag {
  display: inline-block;
  font-size: var(--fs-tag);
  color: var(--accent2);
  border: 1px solid var(--accent2-30);
  background: var(--accent2-06);
  border-radius: var(--radius-pill);
  padding: 0.05rem 0.5rem;
  margin-bottom: 0.35rem;
}
/* FAQ 秒答徽标（KB 链路 mode:"faq"：标准答案 0 LLM token，与 LLM 生成区分） */
.asst-faq-badge {
  display: inline-block;
  font-size: var(--fs-tag);
  color: var(--accent);
  border: 1px solid var(--accent-30);
  background: var(--accent-06);
  border-radius: var(--radius-pill);
  padding: 0.05rem 0.5rem;
  margin-bottom: 0.35rem;
  margin-right: 0.35rem;
}
/* 所属模块提示（refs 含 module 字段时追加在答案下方；缺省不渲染） */
.asst-module-hint {
  margin-top: 0.45rem;
  font-size: var(--fs-tag);
  color: var(--muted);
}
/* 回答内嵌引用标记 【n】：可点，与 refs chips 同效 */
.asst-cite {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.78em;
  color: var(--accent);
  border: 1px solid var(--accent-30);
  border-radius: 6px;
  padding: 0 0.3em;
  margin: 0 0.1em;
  cursor: pointer;
  text-decoration: none;
  vertical-align: baseline;
  transition: background 0.15s ease;
}
.asst-cite:hover { background: var(--accent-12); }

/* 流式打字光标 */
.asst-cursor {
  display: inline-block;
  width: 0.55em;
  height: 1.05em;
  margin-left: 2px;
  vertical-align: text-bottom;
  background: var(--accent);
  border-radius: 2px;
  animation: asst-blink 0.85s steps(2, start) infinite;
}
@keyframes asst-blink {
  to { visibility: hidden; }
}

/* 流式占位行：meta 到达（LLM 调用前 ~50ms）→ 首 token 合帧渲染之间显示，
   三点跳动动画；首帧正文渲染时被 renderAnswer 的 body 重建一并替换 */
.asst-placeholder {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--muted);
  font-size: var(--fs-xs);
}
.asst-placeholder-dots {
  display: inline-flex;
  gap: 3px;
}
.asst-placeholder-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--muted);
  animation: asst-dot-bounce 1.2s ease-in-out infinite;
}
.asst-placeholder-dot:nth-child(2) { animation-delay: 0.15s; }
.asst-placeholder-dot:nth-child(3) { animation-delay: 0.3s; }
@keyframes asst-dot-bounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.45; }
  30% { transform: translateY(-3px); opacity: 1; }
}

/* 引用 chips（卡片式：页标题 + 节标题 + 跳转箭头） */
.asst-refs {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.5rem;
}
.asst-refs-label {
  font-size: var(--fs-tag);
  color: var(--muted);
}
.asst-ref {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.45rem 0.65rem;
  border: 1px solid var(--accent-12);
  border-radius: 10px;
  background: var(--card-bg);
  text-decoration: none;
  color: var(--ink);
  font-size: var(--fs-xs);
  line-height: 1.45;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.asst-ref:hover {
  border-color: var(--accent);
  transform: translateY(-1px);
}
.asst-ref:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.asst-ref .asst-ref-dot {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent2);
}
.asst-ref .asst-ref-text { flex: 1; min-width: 0; }
.asst-ref .asst-ref-page {
  display: block;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.asst-ref .asst-ref-sec {
  display: block;
  color: var(--muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.asst-ref .asst-ref-arrow { flex: 0 0 auto; color: var(--accent); }

/* 引导问题 chips */
.asst-guides {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.45rem;
}
.asst-guide {
  border: 1px solid var(--accent-30);
  background: transparent;
  color: var(--accent);
  border-radius: var(--radius-pill);
  padding: 0.28rem 0.7rem;
  font-size: var(--fs-xs);
  font-family: var(--font);
  cursor: pointer;
  text-align: left;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.asst-guide:hover { background: var(--accent-12); border-color: var(--accent); }
.asst-guide:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* 输入区 */
.asst-inputbar {
  flex: 0 0 auto;
  display: flex;
  gap: 0.5rem;
  padding: 0.7rem 0.9rem;
  border-top: 1px solid var(--rule);
}
.asst-input {
  flex: 1;
  min-width: 0;
  border: 1px solid var(--rule);
  border-radius: 10px;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font);
  font-size: var(--fs-sm);
  padding: 0.5rem 0.7rem;
  outline: none;
  transition: border-color 0.15s ease;
}
.asst-input:focus { border-color: var(--accent); }
.asst-input::placeholder { color: var(--muted); }
.asst-send {
  flex: 0 0 auto;
  border: 1px solid var(--accent-30);
  border-radius: 10px;
  background: var(--accent-12);
  color: var(--accent);
  font-family: var(--font);
  font-size: var(--fs-sm);
  font-weight: 600;
  padding: 0.5rem 0.9rem;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.asst-send:hover { border-color: var(--accent); }
.asst-send:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.asst-send:disabled { opacity: 0.5; cursor: default; }
/* 流式中 = 「停止」态 */
.asst-send.asst-stop {
  color: var(--ink);
  background: var(--bg2);
  border-color: var(--rule);
}

/* 目标 section 高亮闪烁（同页引用跳转后 1.6s） */
.asst-flash {
  animation: asst-flash-kf 1.6s ease-out 1;
  border-radius: var(--radius);
}
@keyframes asst-flash-kf {
  0%   { box-shadow: 0 0 0 0 var(--accent-30); background: var(--accent-12); }
  60%  { box-shadow: 0 0 0 6px var(--accent-12); background: var(--accent-06); }
  100% { box-shadow: 0 0 0 0 transparent; background: transparent; }
}

/* ---------- 移动端：全宽底部抽屉 ---------- */
@media (max-width: 480px) {
  .asst-fab-wrap {
    right: 12px;
    bottom: 12px;
  }
  .asst-fab {
    width: 50px;
    height: 50px;
    padding: 5px;
  }
  .asst-panel {
    right: 0;
    left: 0;
    bottom: 0;
    width: 100%;
    max-width: 100%;
    height: 72vh;
    max-height: 72vh;
    border-radius: var(--radius) var(--radius) 0 0;
    border-left: none;
    border-right: none;
    border-bottom: none;
  }
}

/* 打印：不带走聊天控件 */
@media print {
  .asst-fab-wrap, .asst-panel { display: none; }
}

/* ---------- 门户页令牌兜底 ----------
 * 门户页（/、/stats.html、/readings/…）不加载 design-tokens.css，助教缺失的令牌
 * 在此映射到门户自有令牌（--card / --bg2 / --accent / --accent2 门户均已有定义）；
 * 仅当 portal-toggle.js 助教 loader 给 <html> 加 .asst-portal-tokens 时生效，
 * 讲义页（design-tokens.css 全量定义）永不受影响 */
:root.asst-portal-tokens {
  --card-bg:     var(--card);
  --accent-30:   color-mix(in srgb, var(--accent) 30%, transparent);
  --accent-12:   color-mix(in srgb, var(--accent) 12%, transparent);
  --accent-07:   color-mix(in srgb, var(--accent) 7%, transparent);
  --accent-06:   color-mix(in srgb, var(--accent) 6%, transparent);
  --accent2-30:  color-mix(in srgb, var(--accent2) 30%, transparent);
  --accent2-06:  color-mix(in srgb, var(--accent2) 6%, transparent);
  --radius:      12px;
  --radius-pill: 999px;
  --font:        -apple-system, BlinkMacSystemFont, "PingFang SC", "Segoe UI", "Microsoft YaHei", sans-serif;
  --font-mono:   ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --fs-sm:       0.88rem;
  --fs-tag:      0.72rem;
  --fs-xs:       0.82rem;
}
