/* ============================================================
 * styles.css — 元悟空 · 金白银 收藏级主题 (V6)
 *
 * 基调:
 *  - 宣纸白底 #f8f5ec / 雪白 #ffffff (NOT 黑神话暗色)
 *  - 鎏金 #c9a35e + 暗金 #a07c3a 主点
 *  - 月银 #d8dbe0 + 墨灰 #2a2926 副点
 *  - 古典宋体 / 行楷 + 书法标题
 *  - 三幕场景: 灵山入场 / 竹简选角 / 主聊天 (qunxiang 横幅)
 *  - 书法云朵气泡, 吹气粒子, 卡通悟空跑步进度条
 *  - 横屏 grid 三栏 / 竖屏 stack 单列
 * ============================================================ */

/* ============ tokens ============ */
:root {
  /* surfaces */
  --bg: #f8f5ec;             /* 宣纸 */
  --bg-elev: #fdfbf3;        /* 米白卡片 */
  --bg-elev-2: #ffffff;      /* 雪白强调 */
  --bg-paper: #f1ebd8;       /* 老纸暖底 */
  --bg-sand: #ece5cf;        /* 竹简底 */

  /* ink */
  --ink: #2a2926;            /* 墨黑 */
  --ink-strong: #1a1916;
  --ink-dim: #5b5750;        /* 烟墨 */
  --ink-mid: #7c7669;
  --ink-faint: #a39b89;

  /* metal */
  --gold: #c9a35e;           /* 鎏金主 */
  --gold-deep: #a07c3a;      /* 暗金 */
  --gold-pale: #e8d6a8;      /* 浅金 */
  --gold-glow: rgba(201, 163, 94, 0.55);
  --silver: #d8dbe0;
  --silver-deep: #9ea3aa;
  --silver-pale: #f0f1f4;

  /* accents */
  --accent: var(--gold-deep);
  --accent-warm: var(--gold);
  --accent-deep: #7e5f24;
  --error: #b53333;
  --focus: var(--gold);

  /* lines */
  --line: #ece4cf;
  --line-strong: #d9cfaf;
  --ring-warm: #d6c9a3;
  --ring-deep: #b8a777;

  /* bubbles */
  --bubble-user-bg: rgba(255, 255, 255, 0.92);
  --bubble-user-edge: rgba(160, 124, 58, 0.45);
  --bubble-user-glow: rgba(201, 163, 94, 0.18);
  --bubble-char-bg: rgba(255, 253, 247, 0.96);
  --bubble-char-edge: rgba(160, 124, 58, 0.55);
  --bubble-char-glow: rgba(201, 163, 94, 0.25);

  /* shadows */
  --shadow-whisper: 0 4px 20px rgba(120, 90, 30, 0.10);
  --shadow-soft: 0 8px 32px rgba(120, 90, 30, 0.14);
  --shadow-gold: 0 0 24px rgba(201, 163, 94, 0.28);
  --shadow-ring: 0 0 0 1px var(--ring-warm);
  --shadow-ring-deep: 0 0 0 1px var(--ring-deep);

  /* radii */
  --r-sm: 6px;
  --r: 10px;
  --r-lg: 14px;
  --r-xl: 18px;
  --r-2xl: 28px;

  /* type */
  --font-serif: "Source Han Serif SC", "Songti SC", "Noto Serif SC", "Source Serif Pro", Georgia, serif;
  --font-cal:  "STXingkai", "Xingkai SC", "STKaiti", "Kaiti SC", "Ma Shan Zheng", "行楷", "Songti SC", serif;
  --font-sans: "PingFang SC", "Microsoft YaHei", "Inter", -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --font-mono: "JetBrains Mono", "SF Mono", "Menlo", "Consolas", monospace;
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; padding: 0; }
body {
  background:
    radial-gradient(1200px 700px at 50% -20%, rgba(232, 214, 168, 0.45), transparent 60%),
    radial-gradient(900px 500px at 100% 100%, rgba(216, 219, 224, 0.4), transparent 60%),
    var(--bg);
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.7;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
  /* V13: 全局光标换祥云 (cloud_cursor.png) */
  cursor: url("sucai/figure/cloud_cursor.png?v=v13") 4 4, auto;
}
button, .icon-btn, .compass-pin, .scroll-card, a, [data-action] {
  cursor: url("sucai/figure/cloud_cursor_hover.png?v=v13") 4 4, pointer;
}
input, textarea {
  cursor: text;   /* 文字输入框保留 I-beam */
}
button, input, select, textarea { font-family: inherit; font-size: inherit; color: var(--ink); }
a { color: var(--gold-deep); text-decoration: none; transition: color 0.2s; }
a:hover { color: var(--gold); }
code {
  background: var(--bg-paper);
  color: var(--ink-dim);
  padding: 1px 6px;
  border-radius: var(--r-sm);
  font-family: var(--font-mono);
  font-size: 0.92em;
}

/* ============ 隐藏旧入口直到选角完成 ============ */
.layout[hidden], .layout.is-hidden { display: none !important; }

/* ============================================================
 *  幕一 · 灵山入场 (welcome)
 * ============================================================ */
.welcome {
  position: fixed;
  inset: 0;
  z-index: 900;
  background: #000;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.welcome[hidden] { display: none; }
.welcome video {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: 0;
}
.welcome::after {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(900px 500px at 50% 50%, rgba(0,0,0,0) 0%, rgba(0,0,0,0.45) 70%),
    linear-gradient(180deg, rgba(0,0,0,0.15) 0%, rgba(0,0,0,0) 30%, rgba(0,0,0,0.5) 100%);
  pointer-events: none;
  z-index: 1;
}
.welcome-inner {
  position: relative;
  z-index: 2;
  text-align: center;
  color: #fff;
  padding: 24px;
  max-width: 720px;
  animation: welcome-fade 1.2s ease-out 0.4s both;
}
@keyframes welcome-fade {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}
.welcome-title {
  font-family: var(--font-cal);
  font-size: clamp(56px, 11vw, 132px);
  font-weight: 500;
  letter-spacing: 0.18em;
  background: linear-gradient(180deg, #fff8e1 0%, var(--gold) 55%, var(--gold-deep) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 4px 18px rgba(201,163,94,0.55));
  margin: 0;
  line-height: 1;
}
.welcome-sub {
  margin-top: 18px;
  font-family: var(--font-serif);
  font-size: clamp(14px, 1.6vw, 19px);
  color: #f3e7c7;
  letter-spacing: 0.4em;
  opacity: 0.92;
}
.welcome-actions { margin-top: 38px; display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; }
.welcome-btn {
  background: linear-gradient(180deg, rgba(255,255,255,0.12), rgba(255,255,255,0.04));
  border: 1px solid rgba(232,214,168,0.55);
  color: #fdf3d2;
  padding: 12px 28px;
  border-radius: 999px;
  font-family: var(--font-serif);
  font-size: 15px;
  letter-spacing: 0.15em;
  cursor: pointer;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: all 0.25s;
  box-shadow: 0 4px 18px rgba(0,0,0,0.25), inset 0 0 0 1px rgba(255,255,255,0.05);
}
.welcome-btn:hover {
  border-color: var(--gold);
  background: linear-gradient(180deg, rgba(201,163,94,0.35), rgba(160,124,58,0.2));
  color: #fff;
  box-shadow: 0 6px 26px rgba(201,163,94,0.4), inset 0 0 0 1px rgba(255,255,255,0.15);
}
.welcome-btn.primary {
  background: linear-gradient(180deg, var(--gold) 0%, var(--gold-deep) 100%);
  color: #1a1407;
  border-color: var(--gold-pale);
  font-weight: 600;
}
.welcome-btn.primary:hover { color: #1a1407; box-shadow: 0 8px 36px rgba(201,163,94,0.55); }

.welcome-skip {
  position: absolute;
  bottom: 24px;
  right: 28px;
  z-index: 3;
  background: transparent;
  border: 1px solid rgba(255,255,255,0.25);
  color: rgba(255,255,255,0.7);
  padding: 6px 14px;
  border-radius: 999px;
  font-size: 12px;
  letter-spacing: 0.15em;
  cursor: pointer;
  backdrop-filter: blur(4px);
  transition: all 0.2s;
}
.welcome-skip:hover { color: #fff; border-color: var(--gold); }

/* ============================================================
 *  幕二 · 竹简选角 (scroll-select)
 * ============================================================ */
.select-scene {
  position: fixed;
  inset: 0;
  z-index: 800;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 32px;
  overflow: hidden;
  background:
    radial-gradient(900px 600px at 50% 0%, rgba(232, 214, 168, 0.55), transparent 60%),
    radial-gradient(700px 500px at 50% 100%, rgba(216, 219, 224, 0.35), transparent 60%),
    linear-gradient(180deg, #f9f3df 0%, #f3ecd2 50%, #ece5c2 100%);
}
.select-scene[hidden] { display: none; }

/* 飘金粒子 (背景层) */
.select-scene::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(2px 2px at 12% 22%, rgba(201,163,94,0.8), transparent 60%),
    radial-gradient(1px 1px at 28% 60%, rgba(201,163,94,0.6), transparent 60%),
    radial-gradient(2px 2px at 55% 18%, rgba(232,214,168,0.7), transparent 60%),
    radial-gradient(1.5px 1.5px at 75% 70%, rgba(201,163,94,0.65), transparent 60%),
    radial-gradient(1px 1px at 88% 35%, rgba(232,214,168,0.55), transparent 60%);
  background-size: 100% 100%;
  animation: gold-float 14s linear infinite;
  pointer-events: none;
  z-index: 0;
  opacity: 0.7;
}
@keyframes gold-float {
  0%   { transform: translateY(0px); }
  50%  { transform: translateY(-22px); }
  100% { transform: translateY(0px); }
}

.select-head {
  position: relative;
  z-index: 2;
  text-align: center;
  margin-bottom: 28px;
}
.select-title {
  font-family: var(--font-cal);
  font-size: clamp(40px, 6vw, 72px);
  font-weight: 500;
  letter-spacing: 0.2em;
  margin: 0;
  background: linear-gradient(180deg, var(--gold) 0%, var(--gold-deep) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  filter: drop-shadow(0 2px 6px rgba(160,124,58,0.25));
}
.select-sub {
  font-family: var(--font-serif);
  font-size: 14px;
  color: var(--ink-mid);
  letter-spacing: 0.35em;
  margin-top: 10px;
}

/* 竹简卷轴: 一字横排, 横屏 */
.scroll-rack {
  position: relative;
  z-index: 2;
  width: min(1280px, 96vw);
  display: grid;
  grid-template-columns: repeat(8, 1fr);
  gap: 18px;
  padding: 36px 28px;
  background:
    linear-gradient(180deg, #ece1bd 0%, #e0d3a6 40%, #ece1bd 100%);
  border-radius: 20px;
  box-shadow:
    inset 0 0 0 1px rgba(160,124,58,0.35),
    inset 0 2px 0 rgba(255,255,255,0.6),
    inset 0 -2px 0 rgba(120,90,30,0.18),
    0 16px 48px rgba(120,90,30,0.22);
}
/* 卷轴两端的木轴 */
.scroll-rack::before, .scroll-rack::after {
  content: "";
  position: absolute;
  top: -18px; bottom: -18px;
  width: 28px;
  border-radius: 28px;
  background:
    linear-gradient(180deg, #b89766 0%, #8e6c3c 50%, #b89766 100%);
  box-shadow:
    inset 0 0 0 1px rgba(0,0,0,0.2),
    0 6px 18px rgba(0,0,0,0.25);
}
.scroll-rack::before { left: -16px; }
.scroll-rack::after  { right: -16px; }

/* ============================================================
 *  单根竹简 (V10) = 立绘背景 + 头像圆盘 (上 1/4) + 光泽 + 金光 + 粒子
 * ============================================================ */
.scroll-card {
  position: relative;
  height: 420px;
  border-radius: 8px;
  cursor: pointer;
  overflow: hidden;
  isolation: isolate;
  /* 竹简底: 暖色渐变 + 极细的纵向竹丝 + 左右收边阴影模拟曲率 */
  background:
    /* 左右暗边模拟竹简圆柱曲率 */
    linear-gradient(90deg,
      rgba(60, 40, 10, 0.32) 0%,
      rgba(60, 40, 10, 0.06) 8%,
      rgba(255, 250, 220, 0.0) 22%,
      rgba(255, 250, 220, 0.55) 50%,
      rgba(255, 250, 220, 0.0) 78%,
      rgba(60, 40, 10, 0.06) 92%,
      rgba(60, 40, 10, 0.32) 100%),
    /* 极细纵向竹纹 */
    repeating-linear-gradient(90deg,
      rgba(120, 90, 30, 0.08) 0,
      rgba(120, 90, 30, 0.08) 1px,
      transparent 1px,
      transparent 6px),
    /* 主底色 */
    linear-gradient(180deg, #f4e8c8 0%, #e6d4a3 50%, #c9b07a 100%);
  border: 1px solid rgba(160,124,58,0.5);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.6),
    inset 0 -3px 0 rgba(120,90,30,0.25),
    inset 0 0 0 1px rgba(255,250,220,0.18),
    0 6px 18px rgba(120,90,30,0.18);
  transition: transform 0.45s cubic-bezier(.2,.7,.3,1.25), box-shadow 0.45s, filter 0.3s;
}

/* 立绘背景 (poster 充满竹简, 半透明叠在底纹之上) */
.scroll-card-bg {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center 35%;
  background-repeat: no-repeat;
  opacity: 0.42;
  filter: saturate(0.9) contrast(1.05);
  mix-blend-mode: multiply;
  z-index: 1;
  transition: opacity 0.45s, transform 0.55s cubic-bezier(.2,.7,.3,1.2);
}
.scroll-card:hover .scroll-card-bg {
  opacity: 0.65;
  transform: scale(1.04);
}

/* 竹简光泽: 中央高光纵带 + hover 时滑过的高光 */
.scroll-card-gloss {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
  background:
    /* 中央纵向高光 (静态) */
    linear-gradient(90deg,
      transparent 0%,
      transparent 38%,
      rgba(255, 252, 220, 0.18) 50%,
      transparent 62%,
      transparent 100%),
    /* 顶部圆弧高光 */
    radial-gradient(120% 60px at 50% 0%,
      rgba(255, 250, 220, 0.5) 0%,
      transparent 70%);
}
/* hover 滑过的金色高光 */
.scroll-card-gloss::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  left: -40%;
  width: 30%;
  background: linear-gradient(
    100deg,
    transparent 0%,
    rgba(255,238,180,0.6) 50%,
    transparent 100%
  );
  filter: blur(1px);
  transform: skewX(-18deg);
  opacity: 0;
  transition: opacity 0.2s;
}
.scroll-card:hover .scroll-card-gloss::before {
  opacity: 1;
  animation: gloss-sweep 0.9s cubic-bezier(.4,.1,.2,1) forwards;
}
@keyframes gloss-sweep {
  0%   { left: -40%; }
  100% { left: 130%; }
}

/* 金光环 (脉冲闪烁, 默认低强度, hover 加倍) */
.scroll-card-halo {
  position: absolute;
  inset: -6px;
  border-radius: 12px;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(closest-side at 50% 50%,
      rgba(255, 220, 140, 0.0) 60%,
      rgba(201, 163, 94, 0.55) 90%,
      rgba(160, 124, 58, 0.0) 100%);
  opacity: 0;
  transition: opacity 0.4s;
  animation: halo-twinkle 2.6s ease-in-out infinite;
}
.scroll-card:hover .scroll-card-halo { opacity: 0.95; }
@keyframes halo-twinkle {
  0%, 100% { filter: brightness(1); }
  50%      { filter: brightness(1.4); }
}

/* 金色粒子 (上升飘) */
.scroll-card-particles {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 3;
  background-image:
    radial-gradient(2px 2px at 18% 80%, rgba(255,232,150,0.95), transparent 60%),
    radial-gradient(1.5px 1.5px at 35% 60%, rgba(255,220,140,0.85), transparent 60%),
    radial-gradient(2px 2px at 55% 70%, rgba(255,240,180,0.9), transparent 60%),
    radial-gradient(1px 1px at 72% 55%, rgba(255,232,150,0.75), transparent 60%),
    radial-gradient(2.5px 2.5px at 28% 40%, rgba(255,236,170,0.85), transparent 60%),
    radial-gradient(1.5px 1.5px at 80% 30%, rgba(255,220,140,0.7), transparent 60%),
    radial-gradient(1px 1px at 48% 22%, rgba(255,240,180,0.6), transparent 60%);
  background-repeat: no-repeat;
  opacity: 0;
  transition: opacity 0.5s;
  animation: particles-rise 4.2s linear infinite;
}
.scroll-card:hover .scroll-card-particles { opacity: 1; }
@keyframes particles-rise {
  0%   { background-position: 0 0,    0 0,    0 0,    0 0,    0 0,    0 0,    0 0; }
  100% { background-position: 0 -60px, 0 -50px, 0 -70px, 0 -40px, 0 -80px, 0 -55px, 0 -65px; }
}

/* 头像圆盘 (位于竹简上 1/4 处) */
.scroll-card-medallion {
  position: absolute;
  left: 50%;
  top: 25%;                 /* 1/4 处 */
  transform: translate(-50%, -50%);
  width: 72%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  overflow: hidden;
  background: var(--bg-paper);
  z-index: 5;
  box-shadow:
    0 0 0 2px rgba(255, 250, 220, 0.85),
    0 0 0 5px var(--gold-deep),
    0 0 0 6px rgba(232, 214, 168, 0.6),
    0 8px 22px rgba(80, 50, 10, 0.55),
    0 0 28px rgba(255, 220, 140, 0.45);
  transition: transform 0.45s cubic-bezier(.2,.7,.3,1.25), box-shadow 0.45s;
}
.scroll-card-medallion img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.scroll-card-medallion .medallion-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-cal);
  font-size: 64px;
  color: var(--gold-deep);
}
.scroll-card:hover .scroll-card-medallion {
  transform: translate(-50%, -50%) scale(1.06);
  box-shadow:
    0 0 0 2px rgba(255, 250, 220, 1),
    0 0 0 5px var(--gold),
    0 0 0 6px rgba(255, 240, 180, 0.7),
    0 12px 30px rgba(80, 50, 10, 0.6),
    0 0 44px rgba(255, 220, 140, 0.85);
}

/* 名字 (竹简下半 ~70% Y) */
.scroll-card-name {
  position: absolute;
  left: 0; right: 0;
  top: 68%;
  text-align: center;
  font-family: var(--font-cal);
  font-size: 24px;
  font-weight: 600;
  color: #3a2810;
  letter-spacing: 0.15em;
  text-shadow: 0 1px 0 rgba(255,255,255,0.55), 0 0 10px rgba(255,220,140,0.6);
  z-index: 5;
  pointer-events: none;
}
.scroll-card-tag {
  position: absolute;
  left: 8%; right: 8%;
  top: 80%;
  text-align: center;
  font-family: var(--font-serif);
  font-size: 11.5px;
  color: rgba(40, 25, 5, 0.85);
  letter-spacing: 0.05em;
  line-height: 1.55;
  text-shadow: 0 1px 0 rgba(255,255,255,0.4);
  z-index: 5;
  pointer-events: none;
}

.scroll-card:hover {
  transform: translateY(-22px) rotate(-0.5deg);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.7),
    inset 0 -3px 0 rgba(120,90,30,0.22),
    0 22px 44px rgba(160,124,58,0.45),
    0 0 0 1px var(--gold);
  filter: brightness(1.04);
}

.select-foot {
  position: relative;
  z-index: 2;
  margin-top: 26px;
  display: flex;
  gap: 14px;
}
.select-foot button {
  background: linear-gradient(180deg, #fffaef 0%, #f3e7c7 100%);
  border: 1px solid var(--ring-warm);
  color: var(--ink-dim);
  padding: 10px 22px;
  border-radius: 999px;
  font-family: var(--font-serif);
  font-size: 13px;
  letter-spacing: 0.15em;
  cursor: pointer;
  box-shadow: var(--shadow-whisper);
  transition: all 0.2s;
}
.select-foot button:hover {
  border-color: var(--gold);
  color: var(--gold-deep);
  box-shadow: 0 4px 18px rgba(201,163,94,0.32);
}

/* ============================================================
 *  幕三 · 主聊天 (layout)
 * ============================================================ */

/* 顶部 qunxiang 横幅: 主页面背景上半 */
.bg-banner {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 50vh;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
.bg-banner video {
  width: 100%; height: 100%;
  object-fit: cover;
  filter: saturate(0.95) brightness(1.04);
}
.bg-banner::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(248,245,236,0.18) 0%, rgba(248,245,236,0.65) 60%, var(--bg) 100%);
  pointer-events: none;
}

.layout {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 280px 1fr;
  grid-template-rows: 64px 1fr;
  grid-template-areas:
    "topbar topbar"
    "sidebar chat";
  height: 100vh;
}

.topbar {
  grid-area: topbar;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 28px;
  background: linear-gradient(180deg, rgba(253,251,243,0.85) 0%, rgba(253,251,243,0.5) 100%);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
  z-index: 5;
}
.brand { display: flex; align-items: center; gap: 14px; cursor: pointer; }
.brand-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  border-radius: 50%;
  background: linear-gradient(180deg, var(--gold-pale) 0%, var(--gold) 50%, var(--gold-deep) 100%);
  color: #fffbe7;
  font-family: var(--font-cal);
  font-size: 24px;
  box-shadow: 0 4px 12px rgba(160,124,58,0.35), inset 0 0 0 1px rgba(255,255,255,0.4);
}
.brand-text {
  font-family: var(--font-cal);
  font-size: 22px;
  letter-spacing: 0.15em;
  color: var(--ink-strong);
}
.topbar-right { display: flex; align-items: center; gap: 10px; }
.status-pill {
  background: rgba(255,255,255,0.7);
  padding: 6px 14px;
  border-radius: 999px;
  font-size: 12px;
  color: var(--ink-mid);
  border: 1px solid var(--line);
  font-family: var(--font-mono);
  backdrop-filter: blur(4px);
}
.icon-btn {
  background: rgba(255,255,255,0.7);
  border: 1px solid var(--line);
  color: var(--ink-dim);
  width: 38px; height: 38px;
  border-radius: 50%;
  font-size: 16px;
  cursor: pointer;
  transition: all 0.2s;
  backdrop-filter: blur(4px);
}
.icon-btn:hover {
  background: var(--gold-pale);
  border-color: var(--gold);
  color: var(--gold-deep);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(201,163,94,0.3);
}

/* ============ sidebar ============ */
.sidebar {
  grid-area: sidebar;
  background: linear-gradient(180deg, rgba(253,251,243,0.78) 0%, rgba(248,245,236,0.6) 100%);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-right: 1px solid var(--line);
  padding: 22px 0 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
.sidebar-title {
  font-family: var(--font-serif);
  font-size: 12px;
  color: var(--ink-faint);
  padding: 0 24px 14px;
  letter-spacing: 0.4em;
}
.char-list { display: flex; flex-direction: column; gap: 6px; padding: 0 12px; flex: 1; }
.char-btn {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r);
  cursor: pointer;
  text-align: left;
  width: 100%;
  transition: all 0.2s;
}
.char-btn:hover {
  background: rgba(255,255,255,0.7);
  border-color: var(--line);
}
.char-btn.active {
  background: linear-gradient(135deg, rgba(232,214,168,0.65) 0%, rgba(255,255,255,0.85) 100%);
  border-color: var(--gold);
  box-shadow: 0 4px 14px rgba(201,163,94,0.25);
}
.char-avatar {
  width: 44px; height: 44px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  overflow: hidden;
  background: var(--bg-paper);
  box-shadow: 0 0 0 2px var(--gold-pale), 0 2px 8px rgba(160,124,58,0.18);
  transition: transform 0.25s, box-shadow 0.25s;
}
.char-btn:hover .char-avatar {
  transform: translateY(-2px);
  box-shadow: 0 0 0 2px var(--gold), 0 6px 14px rgba(201,163,94,0.4);
}
.char-btn.active .char-avatar {
  box-shadow: 0 0 0 2px var(--gold-deep), 0 6px 16px rgba(160,124,58,0.45);
}
.char-avatar img { width: 100%; height: 100%; object-fit: cover; }
.char-avatar svg { width: 100%; height: 100%; }
.char-info { display: flex; flex-direction: column; min-width: 0; }
.char-name {
  font-family: var(--font-cal);
  font-size: 18px;
  color: var(--ink-strong);
  font-weight: 500;
  letter-spacing: 0.05em;
}
.char-tag {
  font-size: 11px;
  color: var(--ink-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 1px;
  font-family: var(--font-serif);
}
.sidebar-foot {
  padding: 14px 24px 18px;
  border-top: 1px solid var(--line);
  color: var(--ink-faint);
  font-size: 11px;
  line-height: 1.6;
  font-family: var(--font-serif);
}

/* ============ chat ============ */
.chat {
  grid-area: chat;
  display: grid;
  grid-template-rows: auto 1fr auto;
  height: 100%;
  min-height: 0;
  background: transparent;
}
.chat-head {
  padding: 16px 28px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 14px;
  background: rgba(253,251,243,0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.chat-head-avatar {
  width: 48px; height: 48px;
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--bg-paper);
  box-shadow: 0 0 0 2px var(--gold), 0 4px 12px rgba(160,124,58,0.3);
}
.chat-head-avatar img { width: 100%; height: 100%; object-fit: cover; }
.chat-head-avatar svg { width: 100%; height: 100%; }
.chat-head-name {
  font-family: var(--font-cal);
  font-size: 22px;
  font-weight: 500;
  color: var(--ink-strong);
  letter-spacing: 0.1em;
}
.chat-head-tag {
  font-size: 12px;
  color: var(--ink-mid);
  margin-top: 2px;
  font-family: var(--font-serif);
  letter-spacing: 0.1em;
}
.chat-head-text { color: var(--ink-faint); font-style: italic; font-family: var(--font-serif); }

.chat-stream {
  overflow-y: auto;
  padding: 28px 28px 36px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}

/* ============================================================
 * 书法云朵气泡
 * ============================================================ */
.bubble-row {
  display: flex;
  gap: 14px;
  max-width: 100%;
  align-items: flex-start;
  animation: bubble-in 0.4s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}
@keyframes bubble-in {
  from { opacity: 0; transform: translateY(14px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
.bubble-row.user { flex-direction: row-reverse; }
.bubble-avatar {
  width: 44px; height: 44px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-cal);
  font-size: 18px;
  flex-shrink: 0;
  overflow: hidden;
  background: var(--bg-paper);
  color: var(--ink-strong);
  box-shadow: 0 0 0 2px var(--gold-pale), 0 3px 10px rgba(160,124,58,0.18);
}
.bubble-avatar img { width: 100%; height: 100%; object-fit: cover; }
.bubble-avatar svg { width: 100%; height: 100%; }

/* 云朵气泡: 多次 box-shadow + 大圆角 + 伪元素小尾尖 */
.bubble {
  position: relative;
  padding: 16px 22px 14px;
  max-width: 72%;
  white-space: pre-wrap;
  line-height: 1.85;
  font-size: 16px;
  color: var(--ink);
  background: var(--bubble-char-bg);
  border-radius: 28px 28px 28px 8px;
  font-family: var(--font-serif);
  box-shadow:
    inset 0 0 0 1px var(--bubble-char-edge),
    inset 0 1px 0 rgba(255,255,255,0.7),
    0 6px 24px rgba(160,124,58,0.12),
    var(--shadow-gold);
}
/* 云朵小耳: 用伪元素叠两个白色圆模拟书法云脚 */
.bubble::after {
  content: "";
  position: absolute;
  width: 14px; height: 14px;
  background: var(--bubble-char-bg);
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px var(--bubble-char-edge);
  bottom: -6px;
  left: -8px;
}
.bubble::before {
  content: "";
  position: absolute;
  width: 8px; height: 8px;
  background: var(--bubble-char-bg);
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px var(--bubble-char-edge);
  bottom: -14px;
  left: -2px;
}

/* user 气泡 */
.bubble-row.user .bubble {
  background: var(--bubble-user-bg);
  border-radius: 28px 28px 8px 28px;
  font-family: var(--font-serif);
  box-shadow:
    inset 0 0 0 1px var(--bubble-user-edge),
    inset 0 1px 0 rgba(255,255,255,0.8),
    0 6px 22px rgba(201,163,94,0.16);
}
.bubble-row.user .bubble::before { right: -2px; left: auto; bottom: -14px; background: var(--bubble-user-bg); box-shadow: inset 0 0 0 1px var(--bubble-user-edge); }
.bubble-row.user .bubble::after  { right: -8px; left: auto; bottom: -6px; background: var(--bubble-user-bg); box-shadow: inset 0 0 0 1px var(--bubble-user-edge); }

/* char 气泡: 字体放大一档, 行楷感 */
.bubble-row.char .bubble {
  font-size: 16.5px;
  line-height: 1.9;
}

/* hover 加强发光 */
.bubble-row:hover .bubble { transition: box-shadow 0.25s; }
.bubble-row.char:hover .bubble {
  box-shadow:
    inset 0 0 0 1px var(--bubble-char-edge),
    inset 0 1px 0 rgba(255,255,255,0.8),
    0 8px 32px rgba(201,163,94,0.32);
}

/* 老 callsign 干掉 (云朵气泡不再显示) — V6 隐藏所有 data-callsign 旧痕迹 */
.bubble[data-callsign] { /* keep attribute, do not render */ }

/* system 气泡 */
.bubble-row.system { justify-content: center; }
.bubble-row.system .bubble {
  background: transparent;
  color: var(--ink-faint);
  font-size: 11.5px;
  font-family: var(--font-serif);
  letter-spacing: 0.3em;
  text-align: center;
  margin: 0 auto;
  border: 1px dashed var(--ring-warm);
  border-radius: 999px;
  padding: 4px 18px;
  max-width: none;
  box-shadow: none;
}
.bubble-row.system .bubble::before,
.bubble-row.system .bubble::after { display: none; }

/* pending 气泡: 不显示文字 (思考过程隐藏), 只显示悟空跑步进度条 */
.bubble.pending {
  font-size: 0;
  padding: 12px 18px;
  background: rgba(255,253,247,0.85);
  min-height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.bubble.pending > *:not(.wukong-runner):not(.jindouyun-loader):not(.gpt-loader):not(.video-loader-wrap):not(.rag-hits) { display: none; }
.bubble.pending .rag-hits { display: none; }

/* ============================================================
 * 悟空跑步进度条
 * ============================================================ */
.wukong-runner {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-width: 220px;
  font-size: 12px;
  font-family: var(--font-serif);
  color: var(--gold-deep);
  letter-spacing: 0.1em;
}
.wukong-track {
  flex: 1;
  height: 14px;
  background: linear-gradient(180deg, #f0e7c8 0%, #e6d8a8 100%);
  border-radius: 999px;
  position: relative;
  overflow: hidden;
  box-shadow: inset 0 1px 2px rgba(120,90,30,0.2);
}
.wukong-track::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(90deg,
      transparent 0%,
      rgba(201,163,94,0.45) 50%,
      transparent 100%);
  background-size: 60% 100%;
  background-repeat: no-repeat;
  animation: track-shine 1.6s linear infinite;
}
@keyframes track-shine {
  0%   { background-position: -60% 0; }
  100% { background-position: 160% 0; }
}
.wukong-sprite {
  position: absolute;
  top: -10px;
  left: 0;
  font-size: 28px;
  line-height: 1;
  filter: drop-shadow(0 2px 3px rgba(120,90,30,0.45));
  animation: wukong-run 3.6s cubic-bezier(.45,.1,.55,.9) infinite, wukong-bob 0.4s ease-in-out infinite;
  transform-origin: center;
}
@keyframes wukong-run {
  0%   { left: -4px; }
  90%  { left: calc(100% - 28px); }
  100% { left: -4px; }
}
@keyframes wukong-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-3px) rotate(-3deg); }
}
.wukong-label {
  font-family: var(--font-cal);
  font-size: 13px;
  letter-spacing: 0.15em;
  color: var(--gold-deep);
  white-space: nowrap;
}

/* ============================================================
 * 反馈/RAG 区
 * ============================================================ */
.feedback {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed var(--line-strong);
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  color: var(--ink-faint);
  font-family: var(--font-sans);
}
.feedback .stars { display: inline-flex; gap: 2px; }
.feedback .star {
  cursor: pointer;
  font-size: 18px;
  color: var(--silver-deep);
  background: none;
  border: none;
  padding: 0 2px;
  line-height: 1;
  transition: all 0.15s;
  box-shadow: none;
}
.feedback .star:hover, .feedback .star.hover-on { color: var(--gold); }
.feedback .star.filled { color: var(--gold-deep); }
.feedback .star.filled:hover { transform: scale(1.15); }
.feedback .fb-comment {
  flex: 1;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 5px 10px;
  font-size: 12px;
  color: var(--ink);
  outline: none;
}
.feedback .fb-comment:focus { border-color: var(--gold); }
.feedback .fb-status { color: var(--gold-deep); font-family: var(--font-mono); }

.rag-hits {
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px dashed var(--line-strong);
  font-family: var(--font-sans);
  font-size: 11.5px;
  color: var(--ink-faint);
}
.rag-hits summary {
  cursor: pointer;
  user-select: none;
  color: var(--ink-mid);
  font-family: var(--font-serif);
  letter-spacing: 0.1em;
}
.rag-hits ul, .rag-hits ol { margin: 6px 0 0; padding-left: 18px; }
.rag-hits li { margin-bottom: 6px; }
.agent-trace summary { color: var(--gold-deep); }
.agent-trace ol li code {
  display: inline-block;
  background: var(--bg-paper);
  padding: 2px 7px;
  border-radius: var(--r-sm);
  font-size: 11px;
  color: var(--ink-dim);
  word-break: break-all;
}
.agent-trace .trace-preview {
  margin-top: 4px;
  padding: 8px 10px;
  border-left: 2px solid var(--gold);
  background: var(--bg-elev-2);
  color: var(--ink-mid);
  white-space: pre-wrap;
  font-size: 11.5px;
  line-height: 1.6;
  max-height: 90px;
  overflow-y: auto;
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
}

/* ============================================================
 * composer + 吹气发送动画
 * ============================================================ */
.composer {
  display: flex;
  gap: 12px;
  padding: 16px 22px 18px;
  border-top: 1px solid var(--line);
  background: rgba(253,251,243,0.7);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.composer textarea {
  flex: 1;
  /* V12: 金色金属镶边 — 用 border-image 模拟拉丝金边 + 内层米白底 */
  border: 3px solid transparent;
  border-radius: var(--r-lg);
  background:
    linear-gradient(var(--bg-elev-2), var(--bg-elev-2)) padding-box,
    linear-gradient(135deg,
      #7e5f24 0%,
      #c9a35e 18%,
      #fff8d8 38%,
      #c9a35e 55%,
      #7e5f24 75%,
      #c9a35e 92%,
      #7e5f24 100%) border-box;
  padding: 12px 16px;
  resize: none;
  outline: none;
  font-size: 15.5px;
  line-height: 1.7;
  color: var(--ink);
  font-family: var(--font-serif);
  box-shadow:
    0 0 0 1px rgba(255, 250, 230, 0.45) inset,
    0 4px 14px rgba(120, 90, 30, 0.18),
    0 0 0 1px rgba(126, 95, 36, 0.45);
  transition: box-shadow 0.2s;
}
.composer textarea:focus {
  box-shadow:
    0 0 0 1px rgba(255, 250, 230, 0.7) inset,
    0 6px 22px rgba(201, 163, 94, 0.35),
    0 0 0 2px rgba(255, 220, 140, 0.4);
}
.composer .send-wrap { position: relative; }

/* V12: 发送按钮 = 桃子 + 金箍棒猴 (peach_nobg.png 已抠图) */
button.primary.big.send-btn {
  position: relative;
  width: 70px;
  height: 70px;
  padding: 0;
  border: 2px solid var(--gold-deep);
  border-radius: 50%;
  background:
    radial-gradient(circle at 35% 30%, #fff8e0 0%, #f8d8a0 50%, #c9a35e 100%);
  color: transparent;     /* 隐藏 "发 送" 文字, 留 alt 给屏幕阅读器 */
  font-size: 0;
  letter-spacing: 0;
  box-shadow:
    0 4px 16px rgba(160, 124, 58, 0.45),
    inset 0 0 0 1px rgba(255, 255, 255, 0.5),
    0 0 24px rgba(255, 220, 140, 0.5);
  transition: all 0.3s cubic-bezier(.2, .8, .3, 1.2);
  overflow: visible;
  flex-shrink: 0;
}
button.primary.big.send-btn::before {
  content: "";
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background:
    url("sucai/figure/peach_nobg.png?v=v12") center 45% / 130% no-repeat;
  filter: drop-shadow(0 2px 4px rgba(120, 90, 30, 0.4));
}
button.primary.big.send-btn:hover:not(:disabled) {
  transform: translateY(-2px) rotate(-4deg);
  box-shadow:
    0 8px 26px rgba(160, 124, 58, 0.6),
    inset 0 0 0 1px rgba(255, 255, 255, 0.65),
    0 0 36px rgba(255, 220, 140, 0.85);
}
button.primary.big.send-btn:active:not(:disabled) {
  transform: translateY(0) rotate(2deg) scale(0.96);
}
button.primary.big.send-btn:disabled {
  opacity: 0.55;
  filter: grayscale(0.7);
  box-shadow: 0 2px 6px rgba(120, 90, 30, 0.2);
}

/* 吹气粒子云 (按下发送时短暂喷出) */
.blow-burst {
  position: absolute;
  pointer-events: none;
  font-family: var(--font-cal);
  font-size: 14px;
  color: var(--gold-deep);
  opacity: 0;
  white-space: nowrap;
  animation: blow-out 0.8s cubic-bezier(.2,.7,.3,1) forwards;
  text-shadow: 0 0 6px rgba(255,238,180,0.7);
}
@keyframes blow-out {
  0%   { opacity: 0; transform: translate(0, 0) scale(0.6); }
  20%  { opacity: 1; }
  100% { opacity: 0; transform: var(--blow-end, translate(-80px, -40px)) scale(1.1); }
}

/* ============================================================
 * 通用按钮
 * ============================================================ */
button {
  background: var(--bg-paper);
  color: var(--ink-dim);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 8px 16px;
  cursor: pointer;
  font-weight: 500;
  font-family: var(--font-serif);
  transition: all 0.2s;
  box-shadow: var(--shadow-whisper);
}
button:hover:not(:disabled) {
  background: var(--bg-elev-2);
  border-color: var(--gold);
  color: var(--gold-deep);
  box-shadow: 0 4px 12px rgba(201,163,94,0.2);
}
button:disabled { opacity: 0.45; cursor: not-allowed; }
button.primary {
  background: linear-gradient(180deg, var(--gold) 0%, var(--gold-deep) 100%);
  border-color: var(--gold-deep);
  color: #fffaef;
  box-shadow: 0 4px 12px rgba(160,124,58,0.25);
}
button.primary:hover:not(:disabled) {
  filter: brightness(1.06);
  border-color: var(--gold-deep);
  color: #fffaef;
  box-shadow: 0 6px 18px rgba(160,124,58,0.45);
}
button.big { padding: 11px 22px; font-size: 15px; border-radius: var(--r-lg); letter-spacing: 0.15em; }

/* ============================================================
 * 弹窗
 * ============================================================ */
.modal {
  position: fixed; inset: 0;
  background: rgba(40, 30, 12, 0.42);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 24px;
  overflow-y: auto;
}
.modal[hidden] { display: none; }
.modal-card {
  background: linear-gradient(180deg, #fffdf5 0%, #f8f0d8 100%);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-xl);
  padding: 32px 36px;
  max-width: 640px;
  width: 100%;
  position: relative;
  box-shadow:
    0 24px 60px rgba(60, 40, 10, 0.25),
    inset 0 0 0 1px rgba(255,255,255,0.6),
    inset 0 -2px 0 rgba(160,124,58,0.18);
  font-family: var(--font-serif);
}
.modal-card.large { max-width: 880px; }
.modal-close {
  position: absolute;
  top: 14px; right: 14px;
  background: transparent;
  border: none;
  color: var(--ink-faint);
  font-size: 22px;
  width: 32px; height: 32px;
  cursor: pointer;
  box-shadow: none;
  padding: 0;
}
.modal-close:hover { color: var(--gold-deep); background: var(--bg-paper); }
.modal-card h2 {
  margin: 0 0 8px;
  font-family: var(--font-cal);
  font-size: 32px;
  font-weight: 500;
  letter-spacing: 0.15em;
  color: var(--ink-strong);
  line-height: 1.2;
}
.modal-card .lead {
  color: var(--ink-mid);
  margin: 0 0 22px;
  font-size: 15px;
  line-height: 1.8;
  font-family: var(--font-serif);
}
.modal-card h3 {
  margin: 22px 0 8px;
  font-family: var(--font-cal);
  font-size: 21px;
  font-weight: 500;
  letter-spacing: 0.1em;
  color: var(--ink-strong);
}
.modal-card .hint {
  color: var(--ink-faint);
  font-size: 13px;
  margin-top: 0;
  font-family: var(--font-serif);
}

/* ============ mode cards ============ */
.mode-cards { display: flex; flex-direction: column; gap: 10px; margin: 12px 0 22px; }
.mode-card {
  display: flex;
  gap: 12px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  cursor: pointer;
  transition: all 0.2s;
  background: var(--bg-elev-2);
}
.mode-card:hover {
  border-color: var(--gold);
  background: rgba(255,250,233,0.95);
}
.mode-card:has(input:checked) {
  border-color: var(--gold-deep);
  background: linear-gradient(135deg, rgba(232,214,168,0.4) 0%, rgba(255,255,255,0.95) 100%);
  box-shadow: 0 4px 14px rgba(201,163,94,0.2);
}
.mode-card input[type="radio"] { margin-top: 4px; accent-color: var(--gold-deep); }
.mode-card-body { flex: 1; }
.mode-title {
  font-weight: 600;
  font-size: 15px;
  margin-bottom: 4px;
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--ink-strong);
  font-family: var(--font-serif);
}
.mode-desc { color: var(--ink-mid); font-size: 13px; line-height: 1.7; }
.mode-config {
  margin-top: 10px;
  font-size: 12px;
  color: var(--ink-faint);
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
}
.mode-config input, .mode-config select {
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 4px 8px;
  width: auto;
  min-width: 140px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink);
}
.badge {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 10px;
  letter-spacing: 0.2em;
  font-family: var(--font-serif);
}
.badge-rec { background: var(--gold-deep); color: #fffaef; }
.badge-safe { background: var(--ink-dim); color: #fffaef; }
.badge-exp { background: var(--bg-paper); color: var(--ink-mid); border: 1px solid var(--line-strong); }

/* ============ prompt box ============ */
.prompt-box {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  margin: 12px 0;
  background: var(--bg);
}
.prompt-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.prompt-toolbar .spacer { flex: 1; }
.copy-status { font-size: 12px; color: var(--gold-deep); font-family: var(--font-mono); }
.llm-jump {
  font-size: 12px;
  padding: 4px 10px;
  border-radius: var(--r-sm);
  background: var(--bg-elev-2);
  text-decoration: none;
  border: 1px solid var(--line);
  color: var(--ink-dim);
}
.llm-jump:hover { background: var(--gold-pale); border-color: var(--gold); color: var(--gold-deep); }

#prompt-out, #response-in {
  width: 100%;
  background: var(--bg);
  color: var(--ink);
  border: none;
  padding: 14px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.7;
  resize: vertical;
  outline: none;
}
#response-in {
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  font-family: var(--font-serif);
  font-size: 14.5px;
}
.actions-row { display: flex; gap: 8px; margin-top: 14px; }

/* ============ V17 · 推理预设卡片 ============ */
.preset-cards {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 8px 0 18px;
}
.preset-card {
  display: flex;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  cursor: pointer;
  transition: all 0.2s;
  background: var(--bg-elev-2);
}
.preset-card:hover { border-color: var(--gold); }
.preset-card:has(input:checked) {
  border-color: var(--gold-deep);
  background: linear-gradient(135deg, rgba(232,214,168,0.4) 0%, rgba(255,255,255,0.95) 100%);
  box-shadow: 0 4px 12px rgba(201, 163, 94, 0.18);
}
.preset-card input[type="radio"] { margin-top: 4px; flex-shrink: 0; accent-color: var(--gold-deep); }
.preset-title {
  font-weight: 600;
  font-size: 15px;
  margin-bottom: 3px;
  color: var(--ink-strong);
  font-family: var(--font-serif);
}
.preset-desc {
  color: var(--ink-mid);
  font-size: 13px;
  line-height: 1.55;
}
.preset-cfg {
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--ink-faint);
  letter-spacing: 0.02em;
}

/* preset 选中 quick / deep 时, 下方详细参数行变只读外观 */
.settings-detail-locked .setting-row input,
.settings-detail-locked .setting-row select {
  opacity: 0.55;
  pointer-events: none;
}
.settings-detail-locked .setting-row label {
  opacity: 0.55;
}

/* ============ settings ============ */
.setting-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
  gap: 12px;
}
.setting-row:last-child { border-bottom: none; }
.setting-row label { color: var(--ink-mid); font-size: 14px; font-family: var(--font-serif); }
.setting-row select, .setting-row input[type="number"] {
  background: var(--bg-elev-2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 6px 10px;
  width: 160px;
  color: var(--ink);
}
.setting-row.danger { border-bottom: none; gap: 8px; }

/* ============ toast ============ */
.toast {
  position: fixed;
  bottom: 28px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--ink-strong);
  color: var(--bg);
  padding: 10px 22px;
  border-radius: 999px;
  z-index: 2000;
  box-shadow: 0 8px 24px rgba(40,30,10,0.35), inset 0 1px 0 rgba(255,255,255,0.1);
  font-size: 13px;
  letter-spacing: 0.15em;
  font-family: var(--font-serif);
}
.toast[hidden] { display: none; }

/* ============ setup wizard ============ */
.setup-llm-checks { display: flex; flex-direction: column; gap: 8px; margin: 12px 0 16px; }
.setup-llm-card {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  cursor: pointer;
  background: var(--bg-elev-2);
  transition: all 0.2s;
}
.setup-llm-card:hover { border-color: var(--gold); }
.setup-llm-card:has(input:checked) {
  border-color: var(--gold-deep);
  background: rgba(232,214,168,0.4);
}
.setup-llm-card input[type="checkbox"] { margin-top: 4px; flex-shrink: 0; accent-color: var(--gold-deep); }
.setup-llm-card .title { font-weight: 600; font-size: 14px; margin-bottom: 3px; color: var(--ink-strong); }
.setup-llm-card .desc { color: var(--ink-mid); font-size: 12px; line-height: 1.6; }

.setup-console {
  margin-top: 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  background: #2a2926;
  overflow: hidden;
  box-shadow: var(--shadow-whisper);
}
.setup-console-head {
  background: var(--bg-paper);
  padding: 8px 14px;
  font-size: 10px;
  color: var(--ink-faint);
  letter-spacing: 0.3em;
  font-family: var(--font-mono);
  border-bottom: 1px solid var(--line-strong);
}
.setup-console pre {
  margin: 0;
  padding: 14px 16px;
  max-height: 320px;
  overflow-y: auto;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.7;
  color: #d8cfa8;
  white-space: pre-wrap;
  word-break: break-word;
  background: #2a2926;
}
.setup-console .ok    { color: #b0d99a; }
.setup-console .warn  { color: var(--gold); }
.setup-console .err   { color: #e29c8c; }
.setup-console .head  { color: var(--gold-pale); font-weight: 600; }
.setup-console .dim   { color: #a39b89; }

/* ============ bootstrap & share ============ */
.bootstrap-step {
  margin: 16px 0;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--bg-elev-2);
}
.bootstrap-step.ok { border-color: rgba(120, 160, 90, 0.4); background: rgba(120, 160, 90, 0.06); }
.bootstrap-step.warn { border-color: var(--gold); background: rgba(232,214,168,0.3); }
.bootstrap-step .step-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
  font-weight: 600;
  font-size: 14px;
  color: var(--ink-strong);
}
.bootstrap-step .step-status { font-family: var(--font-mono); font-size: 11px; }
.bootstrap-step .step-status.ok { color: #6b9352; }
.bootstrap-step .step-status.warn { color: var(--gold-deep); }
.bootstrap-step .step-status.err { color: var(--error); }
.bootstrap-step .step-body { font-size: 13px; color: var(--ink-mid); line-height: 1.6; font-family: var(--font-serif); }
.bootstrap-step pre.cmd {
  margin: 8px 0 0;
  padding: 10px 12px;
  background: #2a2926;
  color: #d8cfa8;
  font-family: var(--font-mono);
  font-size: 11.5px;
  line-height: 1.6;
  border-radius: var(--r-sm);
  overflow-x: auto;
  white-space: pre-wrap;
}
.bootstrap-step .copy-cmd-btn { margin-top: 8px; font-size: 11px; padding: 6px 12px; }

/* ============ dropzone ============ */
.dropzone {
  border: 1.5px dashed var(--line-strong);
  border-radius: var(--r-lg);
  padding: 20px;
  text-align: center;
  background: var(--bg);
  color: var(--ink-faint);
  cursor: pointer;
  transition: all 0.2s;
  font-family: var(--font-serif);
}
.dropzone:hover, .dropzone.dragover {
  border-color: var(--gold);
  background: rgba(232,214,168,0.25);
  color: var(--ink-mid);
}
.dropzone strong { color: var(--ink-strong); }
.uploaded-list { margin-top: 10px; display: flex; flex-direction: column; gap: 4px; }
.uploaded-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-mid);
  padding: 6px 10px;
  background: var(--bg-elev-2);
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
}
.uploaded-item .remove-btn {
  margin-left: auto;
  background: transparent;
  border: none;
  color: var(--ink-faint);
  cursor: pointer;
  font-size: 14px;
  padding: 2px 6px;
  box-shadow: none;
}
.uploaded-item .remove-btn:hover { color: var(--gold-deep); }
.upload-progress { font-size: 12px; color: var(--gold-deep); margin-top: 6px; font-family: var(--font-mono); }

/* ============================================================
 * 响应式 — 手机竖屏
 * ============================================================ */
@media (max-width: 880px), (orientation: portrait) and (max-width: 1100px) {
  /* 主布局: 隐藏 sidebar, 单列, 顶栏更紧 */
  .layout {
    grid-template-columns: 1fr;
    grid-template-rows: 56px auto 1fr;
    grid-template-areas:
      "topbar"
      "sidebar"
      "chat";
  }
  .sidebar {
    border-right: none;
    border-bottom: 1px solid var(--line);
    padding: 10px 0 12px;
    max-height: 96px;
  }
  .sidebar-title { display: none; }
  .char-list {
    flex-direction: row;
    overflow-x: auto;
    overflow-y: hidden;
    padding: 0 12px;
    gap: 8px;
  }
  .char-btn { min-width: auto; padding: 6px 10px; }
  .char-btn .char-info { display: none; }
  .char-btn .char-avatar { width: 48px; height: 48px; }
  .sidebar-foot { display: none; }

  .bg-banner { height: 30vh; }
  .topbar { padding: 0 14px; }
  .brand-text { font-size: 18px; letter-spacing: 0.1em; }
  .brand-mark { width: 34px; height: 34px; font-size: 20px; }
  .status-pill { display: none; }

  .chat-stream { padding: 16px 14px 28px; gap: 18px; }
  .chat-head { padding: 12px 16px; }
  .chat-head-name { font-size: 18px; }
  .composer { padding: 12px 12px 14px; }
  .bubble { max-width: 86%; padding: 14px 16px 12px; font-size: 15.5px; line-height: 1.8; }
  .bubble-row { gap: 10px; }
  .bubble-avatar { width: 36px; height: 36px; }

  .modal-card { padding: 22px 18px; max-width: 100%; border-radius: var(--r-lg); }
  .modal-card h2 { font-size: 26px; }

  /* 选角竖屏: 改成 2 列网格垂直竹简 */
  .scroll-rack {
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
    padding: 22px 18px;
    width: 96vw;
    max-height: 70vh;
    overflow-y: auto;
  }
  .scroll-rack::before { left: -10px; width: 18px; }
  .scroll-rack::after  { right: -10px; width: 18px; }
  .scroll-card { height: 260px; border-radius: 6px; }
  .scroll-card-medallion { width: 60%; top: 24%; }
  .scroll-card-name { font-size: 18px; top: 62%; letter-spacing: 0.1em; }
  .scroll-card-tag  { font-size: 10px; top: 76%; line-height: 1.45; }
  .scroll-card:hover { transform: translateY(-10px); }

  .select-title { font-size: 38px; }
  .select-sub   { font-size: 11px; letter-spacing: 0.25em; }

  .welcome-title { font-size: clamp(48px, 14vw, 88px); letter-spacing: 0.12em; }
  .welcome-sub   { letter-spacing: 0.25em; font-size: 13px; }

  /* 发送按钮在手机: 紧凑成图标 */
  button.primary.big.send-btn { padding: 10px 16px; letter-spacing: 0.1em; font-size: 14px; }

  /* 移动端: 把输入框做圆润化 */
  .composer textarea { padding: 10px 14px; font-size: 15px; }
}

/* 大屏 (横屏 16:9): 卷轴稍微大一点 */
@media (min-width: 1400px) and (orientation: landscape) {
  .scroll-rack { padding: 44px 36px; gap: 22px; }
  .scroll-card { height: 420px; }
}

/* 老 sci-fi callsign 兼容: 不再渲染 (保留兼容旧 attribute 但不显示) */
.bubble[data-callsign]::first-letter { /* noop */ }

/* ============================================================
 * V8 · 寻宝罗盘 (luopan.png 贴图)
 *   · 整圆罗盘悬浮在左侧, 8 颗宝石环已绘在底图上
 *   · 拖拽 rotor 整体旋转 (含底图 + pins), pin 内部反向旋转保头像正
 *   · 抬手 → snap 中轴最近的 pin → 自动进对话
 *   · 单击 pin → 顺时针转到中轴 → 自动进对话
 * ============================================================ */
.compass {
  /* V11: 罗盘中心落在视窗左侧边框上 — 只显示右半圆 */
  position: fixed;
  left: -260px;             /* = -width/2, 中心 → x=0 */
  top: 50%;
  transform: translateY(-50%);
  width: 520px;
  height: 520px;
  z-index: 4;
  pointer-events: none;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
}
.compass[hidden] { display: none; }
.compass-rotor {
  position: absolute;
  inset: 0;
  pointer-events: auto;
  cursor: grab;
  transform: rotate(0deg);
  transform-origin: 50% 50%;
  transition: transform 0.55s cubic-bezier(.2,.8,.3,1);
  /* 白光 + 金光: 让罗盘从背景里浮起来 */
  filter:
    drop-shadow(0 0 24px rgba(255, 252, 230, 0.85))
    drop-shadow(0 0 48px rgba(255, 252, 230, 0.55))
    drop-shadow(0 0 80px rgba(255, 220, 140, 0.4))
    drop-shadow(0 16px 32px rgba(40, 25, 5, 0.55));
}
.compass-rotor.dragging { cursor: grabbing; transition: none; }
.compass-bg {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: contain;
  pointer-events: none;
  -webkit-user-drag: none;
  user-drag: none;
}

.compass-pin {
  position: absolute;
  width: 56px; height: 56px;
  margin-left: -28px; margin-top: -28px;
  pointer-events: auto;
  cursor: pointer;
}
/* 头像反向旋转层 — 用 inline transform 由 JS 设置, 保头像永远正立 */
.compass-pin .head-rot {
  position: absolute; inset: 0;
  transform-origin: 50% 50%;
  transition: transform 0.45s cubic-bezier(.2,.8,.3,1.25);
}
.compass-rotor.dragging .compass-pin .head-rot { transition: none; }
.compass-pin .head {
  width: 100%; height: 100%;
  border-radius: 50%;
  overflow: hidden;
  background: #2a2926;
  box-shadow:
    inset 0 0 0 1.5px rgba(255,247,210,0.55),
    0 4px 12px rgba(80,50,10,0.5);
  transition: box-shadow 0.4s, filter 0.4s;
}
.compass-pin .head img { width: 100%; height: 100%; object-fit: cover; display: block; }
.compass-pin .head svg { width: 100%; height: 100%; }
.compass-pin .name {
  position: absolute;
  left: 50%; top: calc(100% + 10px);
  transform: translateX(-50%);
  font-family: var(--font-cal);
  font-size: 20px;
  letter-spacing: 0.18em;
  color: var(--gold-pale);
  text-shadow:
    0 1px 0 rgba(0,0,0,0.6),
    0 0 16px rgba(255,220,140,0.75),
    0 0 4px rgba(0,0,0,0.6);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.4s;
}
.compass-pin.selected { z-index: 6; }
.compass-pin.selected .head {
  box-shadow:
    inset 0 0 0 2px rgba(255,247,210,0.95),
    0 0 0 3px rgba(255,220,140,0.7),
    0 0 24px rgba(255,220,140,0.85),
    0 8px 22px rgba(120,90,30,0.55);
  filter: brightness(1.06);
}
.compass-pin.selected .head-rot { transform: scale(1.18); }
.compass-pin.selected .name { opacity: 1; }
.compass-pin.confirm-pulse .head { animation: pin-confirm 0.7s ease-out; }
@keyframes pin-confirm {
  0%   { box-shadow:
           inset 0 0 0 2px rgba(255,247,210,0.95),
           0 0 0 0 rgba(255,220,140,0.85),
           0 0 24px rgba(255,220,140,0.85); }
  100% { box-shadow:
           inset 0 0 0 2px rgba(255,247,210,0.95),
           0 0 0 80px rgba(255,220,140,0),
           0 0 24px rgba(255,220,140,0.85); }
}

/* 3 点钟方向中轴指示线 (从罗盘右边缘向 chat 延伸) */
.compass-marker {
  position: fixed;
  left: calc(-260px + 520px - 30px);  /* 罗盘右缘往内 30px */
  top: 50%;
  width: 220px;
  height: 2px;
  pointer-events: none;
  z-index: 3;
  background: linear-gradient(90deg,
    rgba(255,220,140,0) 0%,
    rgba(255,220,140,0.55) 35%,
    rgba(255,220,140,0.95) 100%);
  transform: translateY(-1px);
  filter: drop-shadow(0 0 8px rgba(255,220,140,0.55));
}
.compass-marker::after {
  content: "";
  position: absolute;
  right: -1px;
  top: 50%;
  width: 12px; height: 12px;
  border: 2px solid var(--gold);
  border-radius: 50%;
  transform: translateY(-50%);
  box-shadow: 0 0 14px rgba(255,220,140,0.9);
  background: rgba(255,250,233,0.55);
}

/* 桌面横屏: 罗盘出场, 旧 sidebar 隐藏, 聊天区让出左侧空间 */
@media (min-width: 881px) and (orientation: landscape) {
  .layout {
    grid-template-columns: 1fr;
    grid-template-areas:
      "topbar"
      "chat";
  }
  .sidebar { display: none; }
  /* 罗盘只露右半 ~260px — 给所有行留出 280px 让位避免文字被覆盖, 内容用 flex 居中 */
  .chat-head    { padding-left: 280px; padding-right: 28px; }
  .chat-stream  { padding-left: 280px; padding-right: 28px; }
  .chat-stream > * { max-width: 820px; align-self: center; width: 100%; }
  .composer {
    padding-left: 280px;
    padding-right: 28px;
    justify-content: center;
    align-items: center;
  }
  .composer textarea { max-width: 720px; flex: 1 1 auto; }
  .topbar       { padding-left: 280px; }
}

/* 移动竖屏: 罗盘隐藏, 顶部 sidebar 横排 (兼容现有 mobile) */
@media (max-width: 880px), (orientation: portrait) and (max-width: 1100px) {
  .compass { display: none; }
}

/* ============================================================
 * V7 · qunxiang 横幅加深 — 不再透明遮蒙, 只在底部淡入背景
 * ============================================================ */
.bg-banner {
  height: 64vh;   /* 之前 50vh, 现在 64vh — 上半显著 */
  z-index: 0;
}
.bg-banner video {
  filter: saturate(1.05) brightness(1.02) contrast(1.04);
}
.bg-banner::after {
  background:
    linear-gradient(180deg,
      rgba(0,0,0,0) 0%,
      rgba(248,245,236,0) 55%,
      rgba(248,245,236,0.55) 78%,
      rgba(248,245,236,0.92) 92%,
      var(--bg) 100%);
}

/* 顶栏在横幅之上, 加重底色保对比度 */
.topbar {
  background: linear-gradient(180deg,
    rgba(40, 30, 12, 0.45) 0%,
    rgba(40, 30, 12, 0.18) 100%);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-bottom: 1px solid rgba(232,214,168,0.3);
}
.topbar .brand-text { color: #fffaef; text-shadow: 0 2px 8px rgba(0,0,0,0.5); }
.topbar .brand-mark { box-shadow: 0 4px 14px rgba(0,0,0,0.4), inset 0 0 0 1px rgba(255,255,255,0.5); }
.topbar .status-pill {
  background: rgba(0,0,0,0.3);
  color: rgba(255,250,233,0.85);
  border-color: rgba(232,214,168,0.4);
  backdrop-filter: blur(4px);
}
.topbar .icon-btn {
  background: rgba(0,0,0,0.3);
  border-color: rgba(232,214,168,0.4);
  color: rgba(255,250,233,0.85);
}
.topbar .icon-btn:hover {
  background: var(--gold);
  border-color: var(--gold-pale);
  color: #1a1407;
}

/* 聊天头部也半透明叠在视频上 */
.chat-head {
  background: rgba(253,251,243,0.4);
  border-bottom: 1px solid rgba(232,214,168,0.5);
}
@media (max-width: 880px), (orientation: portrait) and (max-width: 1100px) {
  .bg-banner { height: 38vh; }
}

/* ============================================================
 * V7 · 筋斗云 loader (替换 wukong-runner)
 * ============================================================ */
.jindouyun-loader {
  position: relative;
  width: 100%;
  min-width: 260px;
  height: 56px;
  overflow: visible;
}
.jdy-cloud {
  position: absolute;
  top: 14px;
  width: 92px; height: 36px;
  pointer-events: none;
  animation: jdy-fly 3.4s cubic-bezier(.55,.05,.45,.95) infinite, jdy-bob 0.6s ease-in-out infinite;
}
.jdy-puff {
  position: absolute;
  background: linear-gradient(180deg, #fff 0%, #fff8d8 60%, #f0e2ad 100%);
  border-radius: 50%;
  box-shadow:
    0 6px 14px rgba(160,124,58,0.3),
    inset 0 -3px 6px rgba(232,214,168,0.7),
    inset 0 2px 3px rgba(255,255,255,0.9);
}
.jdy-puff:nth-child(1) { width: 32px; height: 30px; top: 6px;  left: 0;  }
.jdy-puff:nth-child(2) { width: 44px; height: 42px; top: -4px; left: 18px; }
.jdy-puff:nth-child(3) { width: 36px; height: 34px; top: 4px;  left: 50px; }
.jdy-puff:nth-child(4) { width: 24px; height: 22px; top: 12px; left: 76px; }
.jdy-wukong {
  position: absolute;
  top: -22px;
  left: 26px;
  font-size: 30px;
  pointer-events: none;
  filter: drop-shadow(0 3px 5px rgba(120,90,30,0.5));
  animation: jdy-monkey 0.5s ease-in-out infinite;
  z-index: 2;
}
.jdy-trail {
  position: absolute;
  top: 30px;
  left: 0;
  right: 0;
  height: 4px;
  pointer-events: none;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(255,220,140,0.7) 40%,
    rgba(201,163,94,0.85) 60%,
    transparent 100%);
  filter: blur(2.5px);
  border-radius: 999px;
  animation: jdy-trail 3.4s cubic-bezier(.55,.05,.45,.95) infinite;
  opacity: 0.5;
  z-index: 0;
}
.jdy-label {
  position: absolute;
  bottom: -18px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-cal);
  font-size: 13px;
  letter-spacing: 0.35em;
  color: var(--gold-deep);
  white-space: nowrap;
  opacity: 0.85;
}
@keyframes jdy-fly {
  0%   { left: -100px; }
  48%  { left: calc(100% - 92px); }
  52%  { left: calc(100% - 92px); }   /* 短暂停留 */
  100% { left: -100px; }
}
@keyframes jdy-monkey {
  0%, 100% { transform: translateY(0) rotate(-3deg); }
  50%      { transform: translateY(-2px) rotate(3deg); }
}
@keyframes jdy-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-3px); }
}
@keyframes jdy-trail {
  0%   { transform: scaleX(0); opacity: 0; transform-origin: left center; }
  30%  { opacity: 0.5; }
  50%  { transform: scaleX(1); opacity: 0.7; transform-origin: left center; }
  70%  { opacity: 0.5; }
  100% { transform: scaleX(0); opacity: 0; transform-origin: right center; }
}

/* pending 气泡: 提高高度容纳筋斗云 + 标签 */
.bubble.pending {
  min-height: 84px;
  padding: 16px 22px 24px;
}

/* ============================================================
 * V15 · 大气泡 + 右下角小视频 loader (脑筋动一动)
 * ============================================================ */
.bubble.pending {
  /* 大气泡: 撑开留白, 让小视频靠右下角点缀 */
  min-height: 220px;
  min-width: 340px;
  padding: 18px 24px 20px;
  position: relative;
}
.video-loader-wrap {
  position: absolute;
  right: 16px;
  bottom: 14px;
  width: 96px;
  height: 56px;
  border-radius: 8px;
  overflow: hidden;
  background: linear-gradient(135deg,
    rgba(255, 248, 216, 0.35) 0%,
    rgba(232, 214, 168, 0.5) 50%,
    rgba(255, 248, 216, 0.35) 100%);
  box-shadow:
    inset 0 0 0 1px rgba(160, 124, 58, 0.3),
    0 2px 8px rgba(160, 124, 58, 0.15);
  pointer-events: none;
}
.video-loader-wrap video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scaleX(-1);   /* 水平翻转, 让 cartoon 主角从左向右走 */
  display: block;
  filter: drop-shadow(0 2px 6px rgba(120, 90, 30, 0.3));
}
.video-loader-label {
  position: absolute;
  bottom: -16px;            /* 标签放到视频框外正下方 */
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-serif);
  font-size: 10px;
  letter-spacing: 0.18em;
  color: rgba(20, 18, 14, 0.78);   /* 小黑字 */
  white-space: nowrap;
  z-index: 2;
}
.bubble.pending .video-loader-wrap { bottom: 30px; }   /* 给标签留出位置 */

/* ============================================================
 * V16 · 鼠标金沙拖尾 — 细碎多颗, 1s 飘散
 * ============================================================ */
.cursor-sand {
  position: fixed;
  margin-left: -1.5px; margin-top: -1.5px;
  border-radius: 50%;
  pointer-events: none;
  z-index: 9999;
  background: radial-gradient(circle at 30% 30%,
    #fffbe5 0%,
    #ffe89a 30%,
    #f0c860 60%,
    #a07c3a 100%);
  box-shadow: 0 0 2px rgba(255, 220, 140, 0.7);
  animation: sand-fall 1s cubic-bezier(.3,.05,.45,1) forwards;
  will-change: transform, opacity;
}
@keyframes sand-fall {
  0%   { opacity: 1;   transform: translate(0,0) rotate(0deg) scale(1); }
  20%  { opacity: 1; }
  85%  { opacity: 0.55; }
  100% { opacity: 0;   transform: translate(var(--ex, 6px), var(--ey, 22px)) rotate(var(--rot, 80deg)) scale(0.35); }
}

/* 关闭转场: 答案到达瞬间, loader 缩小+模糊+消散 */
.bubble.closing .video-loader-wrap,
.bubble.closing .gpt-loader,
.bubble.closing .jindouyun-loader {
  animation: loader-close 0.45s cubic-bezier(.55,.05,.55,.95) forwards;
}
@keyframes loader-close {
  0%   { opacity: 1; transform: scale(1)    rotate(0deg);  filter: blur(0); }
  60%  { opacity: 0.6; transform: scale(0.6) rotate(-6deg); filter: blur(2px); }
  100% { opacity: 0;  transform: scale(0.2) rotate(-18deg); filter: blur(8px); }
}

/* 答案出现: 字带 fade + scale + 微上浮 */
.bubble.bubble-reveal {
  animation: bubble-reveal-in 0.55s cubic-bezier(.2,.8,.3,1.2);
}
@keyframes bubble-reveal-in {
  0%   { opacity: 0; transform: scale(0.94) translateY(8px); filter: blur(3px); }
  60%  { opacity: 1; filter: blur(0); }
  100% { opacity: 1; transform: scale(1) translateY(0); filter: blur(0); }
}

/* ============================================================
 * V14 · 章节上标引用
 * ============================================================ */
.bubble sup.cite {
  display: inline-block;
  margin-left: 1px;
  padding: 0 5px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  color: var(--gold-deep);
  background: linear-gradient(180deg, #fff8d8 0%, #e8d6a8 100%);
  border: 1px solid var(--gold);
  border-radius: 999px;
  vertical-align: super;
  line-height: 1.4;
  cursor: pointer;
  transition: all 0.2s;
  letter-spacing: 0;
}
.bubble sup.cite:hover {
  background: linear-gradient(180deg, var(--gold) 0%, var(--gold-deep) 100%);
  color: #fffaef;
  transform: translateY(-1px);
  box-shadow: 0 2px 6px rgba(160, 124, 58, 0.4);
}
.bubble-citations {
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px dashed var(--ring-warm);
  font-family: var(--font-serif);
  font-size: 12px;
  color: var(--ink-mid);
}
.bubble-citations-title {
  font-family: var(--font-cal);
  font-size: 13px;
  letter-spacing: 0.3em;
  color: var(--gold-deep);
  margin-bottom: 6px;
}
.bubble-citations ol {
  margin: 4px 0 0;
  padding-left: 22px;
  line-height: 1.65;
}
.bubble-citations ol li { margin-bottom: 4px; }
.bubble-citations .cite-num {
  display: inline-block;
  min-width: 22px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  color: var(--gold-deep);
}
.bubble-citations .cite-extra {
  margin-top: 8px;
  padding-top: 6px;
  border-top: 1px dotted var(--line);
  font-size: 11.5px;
  color: var(--ink-faint);
}
.bubble-citations .cite-extra-title {
  font-family: var(--font-serif);
  letter-spacing: 0.2em;
  color: var(--ink-mid);
  margin-bottom: 4px;
}

/* ============================================================
 * V13 · GPT-Image-2 风格生成动画 (保留作 fallback)
 *   · 鎏金渐变底脉冲 + 斜向 shimmer 扫光 + 横向 scan 线 + 下方标签
 * ============================================================ */
.gpt-loader {
  position: relative;
  width: 100%;
  min-width: 280px;
  height: 72px;
  border-radius: 14px;
  overflow: hidden;
  isolation: isolate;
  background:
    linear-gradient(135deg,
      rgba(255, 248, 216, 0.6) 0%,
      rgba(232, 214, 168, 0.85) 25%,
      rgba(255, 240, 180, 0.95) 50%,
      rgba(232, 214, 168, 0.85) 75%,
      rgba(255, 248, 216, 0.6) 100%);
  background-size: 280% 280%;
  animation: gpt-pulse 3.4s ease-in-out infinite;
  box-shadow:
    inset 0 0 0 1px rgba(160, 124, 58, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.6),
    0 4px 18px rgba(160, 124, 58, 0.2);
}
@keyframes gpt-pulse {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}
/* 斜向 shimmer 扫光 */
.gpt-loader::before {
  content: "";
  position: absolute;
  top: -120%; bottom: -120%;
  left: -40%;
  width: 32%;
  background: linear-gradient(
    110deg,
    transparent 0%,
    rgba(255, 255, 255, 0.7) 45%,
    rgba(255, 252, 220, 0.95) 50%,
    rgba(255, 255, 255, 0.7) 55%,
    transparent 100%
  );
  filter: blur(3px);
  transform: skewX(-18deg);
  animation: gpt-shimmer 2.2s linear infinite;
  z-index: 1;
}
@keyframes gpt-shimmer {
  0%   { left: -40%; }
  100% { left: 140%; }
}
/* 横向 scan 线 (上下扫) */
.gpt-loader::after {
  content: "";
  position: absolute;
  left: 6%;
  right: 6%;
  top: 0;
  height: 3px;
  background: linear-gradient(90deg,
    transparent 0%,
    rgba(255, 220, 140, 0.85) 25%,
    rgba(255, 255, 255, 0.95) 50%,
    rgba(255, 220, 140, 0.85) 75%,
    transparent 100%);
  filter: blur(0.5px) drop-shadow(0 0 8px rgba(255, 220, 140, 0.85));
  border-radius: 999px;
  animation: gpt-scan 2.6s ease-in-out infinite;
  z-index: 2;
}
@keyframes gpt-scan {
  0%   { top: 0;            opacity: 0; }
  8%   { opacity: 1; }
  50%  { top: calc(100% - 3px); opacity: 1; }
  92%  { opacity: 1; }
  100% { top: 0;            opacity: 0; }
}
/* 中央 token 流动 (模仿 token 流) */
.gpt-loader-tokens {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  z-index: 3;
  pointer-events: none;
}
.gpt-loader-tokens span {
  display: inline-block;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: radial-gradient(circle at 30% 30%, #fffbe5 0%, var(--gold) 60%, var(--gold-deep) 100%);
  box-shadow: 0 0 8px rgba(255, 220, 140, 0.7);
  animation: gpt-token 1.4s ease-in-out infinite;
}
.gpt-loader-tokens span:nth-child(2) { animation-delay: 0.18s; }
.gpt-loader-tokens span:nth-child(3) { animation-delay: 0.36s; }
.gpt-loader-tokens span:nth-child(4) { animation-delay: 0.54s; }
.gpt-loader-tokens span:nth-child(5) { animation-delay: 0.72s; }
@keyframes gpt-token {
  0%, 80%, 100% { transform: scale(0.65); opacity: 0.5; }
  40%           { transform: scale(1.15); opacity: 1; }
}
.gpt-loader-label {
  position: absolute;
  bottom: 6px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-cal);
  font-size: 11.5px;
  letter-spacing: 0.4em;
  color: var(--gold-deep);
  opacity: 0.85;
  z-index: 4;
  white-space: nowrap;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.55);
}

