:root {
  color-scheme: dark;
  --app-width: 430px;
  --viewport-height: 100dvh;
  --viewport-offset-top: 0px;
  /* CO0174：软键盘实际吃掉聊天页底部的高度（由 app.js 用 visualViewport 实测写入，键盘收起时为 0px）。 */
  --chat-keyboard-inset: 0px;
  /* CO0166/CO0168：主页常驻底栏的高度（含 iOS 主页条安全区）。首页网格、衣橱/商城页的可用高度都靠它对齐。 */
  --home-nav-h: calc(62px + env(safe-area-inset-bottom));
  /* CO0168：tab 横向切换的时长与缓动（甲方要「平稳的滑动」，非匀速）。 */
  --home-tab-slide: 300ms cubic-bezier(0.22, 1, 0.36, 1);
  --bg: #0b0d12;
  --panel: rgba(26, 29, 38, 0.82);
  --panel-strong: rgba(33, 37, 48, 0.96);
  --line: rgba(255, 255, 255, 0.1);
  --text: #f5f5f7;
  --muted: #9a9aa3;
  --assistant: #232838;
  --user: #0a84ff;
  --field: rgba(118, 118, 128, 0.18);
  --danger: #ff6b6b;
}

/* CO0141：触摸/鼠标点击不显示浏览器默认蓝色闪光；键盘焦点由各控件的
   :focus-visible 明确绘制，不能以此替代无障碍焦点。 */
* {
  -webkit-tap-highlight-color: transparent;
}

/* CO0131 素材防拖拽：所有内容图不可原生拖拽（拖出幽灵图/拖到桌面即另存），
   iOS 上再禁长按弹出「存储图像」菜单。029 画布节点拖动走 pointer 事件、
   调色盘拖色是 <button draggable="true">，均不受影响（JS 兜底层同样放行）。 */
img,
picture,
svg,
canvas {
  -webkit-user-drag: none;
  user-drag: none;
}

img {
  -webkit-touch-callout: none;
}

.conversation-panel {
  width: min(520px, calc(100vw - 32px));
}

.conversation-note {
  margin: 0 0 16px;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.65;
}

.conversation-list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 20px 0 8px;
}

.conversation-list-head small {
  color: var(--muted);
}

.conversation-list {
  display: grid;
  gap: 8px;
  max-height: min(48vh, 420px);
  overflow: auto;
}

.conversation-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
  min-height: 68px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  color: var(--text);
  text-align: left;
}

.conversation-option.current {
  border-color: var(--accent);
  box-shadow: inset 3px 0 0 var(--accent);
}

.conversation-option span {
  display: grid;
  min-width: 0;
  gap: 4px;
}

.conversation-option strong,
.conversation-option small {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.conversation-option small,
.conversation-option em {
  color: var(--muted);
  font-size: 12px;
  font-style: normal;
}

:root[data-theme="campus"] {
  color-scheme: light;
  --bg: #e8eff5;
  --panel: rgba(248, 251, 253, 0.86);
  --panel-strong: rgba(252, 253, 255, 0.98);
  --line: rgba(55, 79, 99, 0.16);
  --text: #24313d;
  --muted: #71808d;
  --assistant: #ffffff;
  --user: #3b8edb;
  --field: rgba(86, 119, 145, 0.09);
  --danger: #cb4e5b;
}

/* CO0135：新增紫色主题 Violet（第一槽 / 新默认），配色取自主页紫色系（STORY_SLIDE_TINT.swtlove、
   顶部 INTERACTIVE STORY 紫字、Continue 按钮紫、轮播 dots 紫，品牌紫 #8b6cff）。蓝色 Midnight 仍为 :root 基座。 */
:root[data-theme="violet"] {
  color-scheme: dark;
  --bg: #0f0b1a;
  --panel: rgba(32, 24, 51, 0.82);
  --panel-strong: rgba(40, 30, 62, 0.96);
  --line: rgba(255, 255, 255, 0.1);
  --text: #f5f2fb;
  --muted: #a79cbd;
  --assistant: #271d3d;
  --user: #8b6cff;
  --field: rgba(139, 108, 255, 0.16);
  --danger: #ff6b6b;
}

/* CO0135 暂时隐藏：Cinematic（金棕）已从主题选择器 UI 拿掉，但 CSS 与相关代码全部保留，以后可恢复。 */
:root[data-theme="cinema"] {
  color-scheme: dark;
  --bg: #050505;
  --panel: rgba(12, 12, 12, 0.82);
  --panel-strong: rgba(16, 16, 15, 0.98);
  --line: rgba(219, 190, 130, 0.17);
  --text: #f0ece3;
  --muted: #9d978d;
  --assistant: rgba(12, 12, 12, 0.82);
  --user: #8a6a35;
  --field: rgba(226, 211, 181, 0.08);
  --danger: #d9655f;
}

:root[data-theme="wechat"] {
  color-scheme: light;
  --bg: #ededed;
  --panel: rgba(247, 247, 247, 0.98);
  --panel-strong: #ffffff;
  --line: rgba(0, 0, 0, 0.1);
  --text: #171717;
  --muted: #999999;
  --assistant: #ffffff;
  --user: #95ec69;
  --field: #ffffff;
  --danger: #d94c4c;
}

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html,
body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  position: fixed;
  inset: 0;
  margin: 0;
  min-height: 100%;
  background:
    radial-gradient(circle at top left, rgba(10, 132, 255, 0.18), transparent 34%),
    linear-gradient(180deg, #11141c 0%, var(--bg) 50%, #07080b 100%);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", "PingFang SC", "Microsoft YaHei", sans-serif;
}

:root[data-theme="campus"] body {
  background: #dbe6ef;
}

:root[data-theme="cinema"] body {
  background: #020202;
}

:root[data-theme="wechat"] body {
  background: #ededed;
}

button,
input,
textarea,
select {
  font: inherit;
}

button {
  cursor: pointer;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  border: 0;
  margin: -1px;
  white-space: nowrap;
}

.game-shell {
  width: min(var(--app-width), 100%);
  height: var(--viewport-height, 100dvh);
  min-height: 0;
  margin: 0 auto;
}

/* ===== CO0144：桌面端全局收敛成手机宽居中列 =====
   主壳（.game-shell / .app / .modal）本就已 min(--app-width,100%) 居中；这里补上「商城弹层」——
   它由 economy-store.js 运行时注入 <style>，排在本表之后，故用 !important 覆盖，把桌面全屏平铺改成
   和其它屏一致的手机宽居中列（单/双列卡，不再六卡横铺）。手机端 min(...,100%)=100% 不受影响。 */
.econ-store-modal {
  justify-content: center !important;
}
.econ-store-panel {
  width: min(var(--app-width), 100%) !important;
  margin: 0 auto !important;
  border-left: 1px solid rgba(255, 255, 255, 0.06) !important;
  border-right: 1px solid rgba(255, 255, 255, 0.06) !important;
}
/* 卡片网格固定成舒适双列（桌面不再撑成三列六卡横铺）。 */
.econ-grid,
.econ-pack-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
}
/* 抵消 econ 在宽屏 media query 里塞的 (100vw-1080px)/2 巨型侧边距，回到手机版的 16px。 */
.econ-store-head,
.econ-balance-bar,
.econ-tab-body {
  padding-left: 16px !important;
  padding-right: 16px !important;
}
.econ-tab-body > * {
  width: 100% !important;
}

.game-home[hidden],
.play-screen[hidden],
.game-entry-transition[hidden] {
  display: none !important;
}

.game-entry-transition {
  position: fixed;
  z-index: 90;
  top: var(--viewport-offset-top, 0px);
  bottom: auto;
  left: 50%;
  width: min(var(--app-width), 100%);
  height: var(--viewport-height, 100dvh);
  display: grid;
  place-items: center;
  overflow: hidden;
  transform: translateX(-50%);
  background: #050507;
  color: #f7f7fb;
  opacity: 1;
  transition: opacity 950ms cubic-bezier(.22, .61, .36, 1);
}

.game-entry-transition.is-revealing {
  opacity: 0;
  pointer-events: none;
}

.game-entry-transition-content {
  width: min(280px, calc(100% - 64px));
  display: grid;
  gap: 12px;
  text-align: center;
}

.game-entry-transition-content > span {
  color: rgba(255, 255, 255, 0.4);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0;
}

.game-entry-transition-content > strong {
  overflow: hidden;
  color: #fff;
  font-size: 18px;
  line-height: 1.35;
  letter-spacing: 0;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.game-entry-transition-content > small {
  color: rgba(255, 255, 255, 0.42);
  font-size: 10px;
  letter-spacing: 0;
}

.game-entry-progress {
  height: 2px;
  overflow: hidden;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.12);
}

.game-entry-progress i {
  width: 100%;
  height: 100%;
  display: block;
  border-radius: inherit;
  background: #8b6cff;
  box-shadow: 0 0 12px rgba(139, 108, 255, 0.75);
  transform: scaleX(0);
  transform-origin: left center;
}

.game-entry-transition.is-loading .game-entry-progress i {
  transform: scaleX(1);
  transition: transform 1450ms cubic-bezier(.2, .72, .24, 1);
}

@media (prefers-reduced-motion: reduce) {
  .game-entry-transition {
    transition-duration: 100ms;
  }

  .game-entry-transition.is-loading .game-entry-progress i {
    transition-duration: 100ms;
  }
}

.game-home {
  position: relative;
  width: 100%;
  height: 100%;
  display: grid;
  /* CO0166：两行网格——主区吃满剩余高度，底栏常驻自占一行（含 safe-area），不再是浮层、不再开合。
     底栏既然占行，控制区就不再重复预留 62px 槽位（见 .home-deck-controls），避免双倍留白。 */
  grid-template-rows: minmax(0, 1fr) var(--home-nav-h);
  overflow: hidden;
  border-inline: 1px solid rgba(255, 255, 255, 0.08);
  /* CO0165：原来写死在这里的两团紫/粉径向光挪进 .home-ambient——那两团永远是紫的，换剧本纹丝不动，
     正是「背景和内容不相关」的根源。这里只留基色，颜色交给氛围层按当前剧本走。 */
  background: var(--amb-base);
  color: #f7f7fb;
  box-shadow: 0 0 70px rgba(0, 0, 0, 0.38);
}

/* ===== CO0165：主页氛围背景 ===== */
/* 一组可调变量，四套主题各给一份：深色主题是「夜里的星屑」，浅色主题是「白昼的薄雾」。
   --amb-tint 是兜底氛围色，运行时由 app.js 用当前剧本的 --slide-tint 覆盖到 .home-ambient-glow 上。 */
.game-home {
  --amb-base: #0b0c12;
  --amb-tint: 268 52% 46%;
  --amb-a: 0.3;   /* 右上主辉光 */
  --amb-b: 0.17;  /* 左中副辉光 */
  --amb-c: 0.2;   /* 底部托光 */
  --amb-lift: rgba(255, 255, 255, 0.035);
  --amb-star: 44 92% 84%;
  --amb-star-alpha: 0.5;
  --amb-vignette: 0.5;
  --amb-grain: 0.05;
}

/* 蓝色 Midnight（:root 基座）：冷一点、星屑偏银。 */
:root:not([data-theme="violet"]):not([data-theme="campus"]):not([data-theme="wechat"]):not([data-theme="cinema"]) .game-home {
  --amb-base: #080a10;
  --amb-tint: 214 54% 44%;
  --amb-star: 205 60% 90%;
}

/* Cinematic（金棕，UI 里暂时隐藏但样式保留）。 */
:root[data-theme="cinema"] .game-home {
  --amb-base: #040404;
  --amb-tint: 34 46% 40%;
  --amb-a: 0.24;
  --amb-b: 0.13;
  --amb-star: 38 70% 82%;
  --amb-vignette: 0.58;
}

/* 浅色主题（校园 / 经典聊天）的浅色变体：底不再是墨黑而是抬起来的雾灰蓝，
   辉光更亮更散像白昼漫射，暗角只轻收边不压黑，颗粒减半（浅底上噪点更容易显脏），星屑转冷白。 */
/* ⚠️ 辉光强度在浅色变体里必须比深色主题低：底被抬亮之后，压在背景上的白色系文案
   （「管理剧本」等）对比度会跟着掉。这组数值是按最亮的剧本色（西游记 32 58% 50%）
   反算过的最坏情况，白字 0.62 alpha 下仍有 4.5:1 以上。 */
:root[data-theme="campus"] .game-home {
  --amb-base: #1c232d;
  --amb-tint: 205 46% 50%;
  --amb-a: 0.26;
  --amb-b: 0.17;
  --amb-c: 0.2;
  --amb-lift: rgba(255, 255, 255, 0.045);
  --amb-star: 200 40% 96%;
  --amb-star-alpha: 0.42;
  --amb-vignette: 0.26;
  --amb-grain: 0.028;
}

:root[data-theme="wechat"] .game-home {
  --amb-base: #202426;
  --amb-tint: 128 26% 50%;
  --amb-a: 0.22;
  --amb-b: 0.15;
  --amb-c: 0.18;
  --amb-lift: rgba(255, 255, 255, 0.05);
  --amb-star: 120 18% 96%;
  --amb-star-alpha: 0.4;
  --amb-vignette: 0.24;
  --amb-grain: 0.026;
}

.home-ambient {
  position: absolute;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  pointer-events: none;
  /* 颗粒层的 soft-light 只跟氛围层自己混，混不到上面的卡片和文字；
     同时把混合限制在一个渲染面里，星屑 canvas 重绘不必反复重混。 */
  isolation: isolate;
}

/* ① 基底：顶部一层极浅的抬升，让画面不是一块死黑纸。 */
.home-ambient-wash {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, var(--amb-lift) 0%, transparent 42%);
}

/* ② 动态氛围色：三团大面积柔光。两层同构，靠 is-on 交叉淡入换色（600~800ms），
   淡入完成后由 app.js 把新色抄给底层、顶层瞬时归零，所以中途不会出现两层叠加的亮度脉冲。 */
.home-ambient-glow {
  position: absolute;
  inset: -20%;
  opacity: 0;
  background:
    /* 主辉光的核心刻意压到 26%（约在剧本卡上沿背后），不要顶到页眉那一条：
       「选择一个故事 / 管理剧本」压在那里，核心一亮，暖色剧本下白字对比度会掉。页眉只吃衰减尾部。 */
    radial-gradient(48% 34% at 80% 26%, hsl(var(--glow-tint, var(--amb-tint)) / var(--amb-a)), transparent 68%),
    radial-gradient(52% 34% at 4% 52%, hsl(var(--glow-tint, var(--amb-tint)) / var(--amb-b)), transparent 70%),
    radial-gradient(96% 42% at 50% 98%, hsl(var(--glow-tint, var(--amb-tint)) / var(--amb-c)), transparent 72%);
  transition: opacity 720ms cubic-bezier(0.4, 0, 0.2, 1);
}

.home-ambient-glow.is-on {
  opacity: 1;
}

/* ③ 极细颗粒：内联 SVG feTurbulence，零外部请求。这层是「廉价感 vs 高级感」的分水岭——
   大面积渐变没有它就是一片数码塑料。刻意不做动画：动态颗粒每帧重绘，手机上不划算。 */
.home-ambient-grain {
  position: absolute;
  inset: 0;
  opacity: var(--amb-grain);
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23g)'/%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 140px 140px;
}

/* ④ 星屑微光：canvas 由 app.js 驱动（rAF 限流 30fps、页面不可见或主页不在视口即停）。
   不是星空壁纸，是「空气里有微光」，所以整层再压一次透明度。 */
.home-ambient-stars {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: var(--amb-star-alpha);
}

/* ⑤ 暗角：四周轻压，把视线收拢到剧本卡上。 */
.home-ambient-vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(120% 86% at 50% 36%, transparent 40%, rgba(0, 0, 0, var(--amb-vignette)) 100%);
}

/* 内容层压在氛围层之上（底栏本身 z-index 1100，见 CO0168）。 */
.game-home-main {
  position: relative;
  z-index: 1;
  min-height: 0;
  overflow-y: auto;
  padding: max(22px, calc(env(safe-area-inset-top) + 12px)) 16px 26px;
  overscroll-behavior: contain;
  scrollbar-width: none;
}

.game-home-main::-webkit-scrollbar {
  display: none;
}

.game-home-hero {
  position: relative;
  min-height: 252px;
  display: flex;
  align-items: end;
  overflow: hidden;
  padding: 26px 20px 24px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 24px;
  background:
    linear-gradient(110deg, rgba(23, 18, 43, 0.96) 0%, rgba(42, 30, 77, 0.88) 52%, rgba(13, 15, 23, 0.16) 100%),
    #1d1931;
  isolation: isolate;
  box-shadow: 0 20px 48px rgba(0, 0, 0, 0.24);
}

.game-home-hero::after {
  position: absolute;
  z-index: -1;
  inset: 0;
  content: "";
  background: linear-gradient(0deg, rgba(9, 10, 16, 0.7), transparent 64%);
}

.game-home-hero img {
  position: absolute;
  z-index: -2;
  top: 0;
  right: -8px;
  width: 63%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 18%;
  opacity: 0.76;
  mask-image: linear-gradient(90deg, transparent 0%, #000 35%);
}

.game-home-hero-copy {
  max-width: 82%;
}

.game-home-kicker,
.home-section-head span,
.home-continue-card > div > span {
  color: #bdabff;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.14em;
}

.game-home-hero h1 {
  margin: 9px 0 11px;
  color: #fff;
  font-size: 29px;
  line-height: 1.18;
  letter-spacing: -0.04em;
}

.game-home-hero p {
  max-width: 290px;
  margin: 0;
  color: rgba(255, 255, 255, 0.62);
  font-size: 11px;
  line-height: 1.65;
}

.home-continue-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  margin-top: 14px;
  padding: 15px 15px 15px 17px;
  border: 1px solid rgba(146, 111, 255, 0.3);
  border-radius: 18px;
  background: linear-gradient(120deg, rgba(129, 91, 255, 0.15), rgba(255, 255, 255, 0.045));
}

.home-continue-card h2 {
  margin: 4px 0 3px;
  overflow: hidden;
  color: #fff;
  font-size: 16px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.home-continue-card p {
  margin: 0;
  color: rgba(255, 255, 255, 0.43);
  font-size: 10px;
}

.home-continue-card > button {
  min-height: 42px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px 0 15px;
  border: 1.5px solid transparent;
  border-radius: 13px;
  background: #8b6cff;
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  box-shadow: 0 8px 24px rgba(122, 83, 255, 0.3);
}

.home-continue-card > button b {
  font-size: 22px;
  font-weight: 400;
}

/* CO0137：主页主区改成 flex 列，让空白触发区吃满卡牌区与底栏之间的剩余空间。 */
.game-home-main {
  display: flex;
  flex-direction: column;
}

/* CO0137：空白触发区——低调线性把手 + 上滑提示，占满剩余高度，轻点展开 LAST PLAYED。 */
.home-continue-trigger {
  flex: 1 1 auto;
  min-height: 72px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding: 16px 12px 14px;
  border: 0;
  background: transparent;
  color: rgba(255, 255, 255, 0.5);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.home-continue-trigger[hidden] {
  display: none;
}

.home-continue-handle {
  width: 40px;
  height: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.24);
  transition: background 160ms ease;
}

.home-continue-trigger:hover .home-continue-handle,
.home-continue-trigger:focus-visible .home-continue-handle {
  background: rgba(139, 108, 255, 0.75);
}

.home-continue-trigger-hint {
  font-size: 11px;
  letter-spacing: 0.04em;
}

/* CO0137：点面板外收回用的背板（覆盖主区，点它即收起）。默认不可见、不拦截。 */
.home-continue-backdrop {
  position: absolute;
  inset: 0;
  z-index: 5;
  background: rgba(0, 0, 0, 0.4);
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms ease;
}

.game-home.home-continue-open .home-continue-backdrop {
  opacity: 1;
  pointer-events: auto;
}

/* CO0137：LAST PLAYED 底部浮层。默认平移到底栏下方藏起，展开时滑到底栏上沿；150~200ms 过渡。 */
.home-continue-sheet {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(62px + env(safe-area-inset-bottom));
  z-index: 6;
  padding: 6px 16px 12px;
  transform: translateY(140%);
  opacity: 0;
  pointer-events: none;
  transition:
    transform 190ms cubic-bezier(0.22, 1, 0.36, 1),
    opacity 160ms ease;
}

.game-home.home-continue-open .home-continue-sheet {
  transform: translateY(0);
  opacity: 1;
  pointer-events: auto;
}

.home-continue-collapse {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: 6px 0 8px;
  border: 0;
  background: transparent;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.home-continue-grip {
  width: 44px;
  height: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.32);
}

/* 浮层内部沿用原 LAST PLAYED 卡片视觉，仅去掉原来在流内的上边距。 */
.home-continue-sheet .home-continue-card {
  margin-top: 0;
  box-shadow: 0 -6px 30px rgba(0, 0, 0, 0.38);
  background: linear-gradient(120deg, rgba(129, 91, 255, 0.28), rgba(24, 20, 38, 0.96));
  backdrop-filter: blur(18px);
}

@media (prefers-reduced-motion: reduce) {
  .home-continue-sheet,
  .home-continue-backdrop {
    transition-duration: 1ms;
  }
}

.home-library {
  margin-top: 24px;
}

/* 首页横滑剧本卡轮播（取代固定 Hero + 小条列表） */
/* CO0155：showcase 永远撑满主区高度，让剧本卡固定为大图（不再随底栏来去放大/缩小）。 */
.home-story-showcase {
  margin-top: 6px;
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

.home-script-carousel {
  display: flex;
  gap: 14px;
  margin: 2px -20px 0;
  padding: 6px 20px 8px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  /* CO0134：横向到边界收敛回弹，桌面用抓手光标提示卡片可拖拽。 */
  /* CO0136：touch-action: pan-x 锁定卡牌区只吃水平手势——手机斜滑的垂直分量不再冒泡带动
     .game-home-main 或页面滚动；overscroll-behavior: contain 同时切断横向与纵向的滚动链。 */
  touch-action: pan-x;
  overscroll-behavior: contain;
  cursor: grab;
}

/* CO0155：大卡永远撑满 showcase 剩余高度（不再由 is-immersive 门控）；卡片随之为大图。 */
.home-script-carousel.is-expanded {
  flex: 1 1 auto;
  min-height: 0;
}

/* CO0134：鼠标拖拽滚动进行中——抓取光标、禁止选中、关闭平滑滚动让拖动跟手。 */
.home-script-carousel.is-dragging {
  cursor: grabbing;
  scroll-behavior: auto;
  user-select: none;
}

.home-script-carousel::-webkit-scrollbar {
  display: none;
}

/* CO0133 自定义剧本（内测）卡：与其它剧本卡同尺寸同基座，用虚线描边+内测标记区分。 */
.story-slide-custom {
  border-style: dashed;
  border-color: rgba(255, 255, 255, 0.28);
}

.story-slide-custom .story-slide-body {
  justify-content: flex-end;
}

/* CO0280：自定义内容封面已按 3:4 卡片比例出图，完整铺满即可，不再套普通角色卡的右侧渐隐裁切。 */
.story-slide.story-slide-custom.story-slide-full-art .story-slide-art {
  object-position: 50% 50%;
}

.custom-script-kicker {
  display: flex;
  align-items: center;
  gap: 8px;
}

.custom-script-beta-tag {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #fff;
  background: rgba(139, 108, 255, 0.9);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.25) inset;
}

.custom-script-card-desc {
  font-size: 12.5px;
  line-height: 1.55;
  opacity: 0.92;
}

/* CO0133 自定义剧本（内测）弹窗 */
.custom-script-panel {
  max-width: min(var(--app-width), 100%);
  gap: 14px;
}

.custom-script-step {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.custom-script-disclaimer {
  margin: 0;
  padding: 12px 14px;
  border-radius: 14px;
  font-size: 13.5px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.9);
  background: rgba(139, 108, 255, 0.12);
  border: 1px solid rgba(139, 108, 255, 0.32);
}

.custom-script-disclaimer-compact {
  font-size: 12px;
  padding: 10px 12px;
}

/* CO0195：这一行从 <label> 改成 <div>（内含 <label for> + 独立的条款链接）。
   ⚠️ cursor:pointer 必须从容器移到 label 上 —— 容器上留着的话，鼠标扫过整行都是手型，
   包括那个不可点的空白区，会诱导玩家去点空处然后以为没反应。 */
.custom-script-agree {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 8px;
  font-size: 14px;
}

/* ══ CO0279 ══ 勾选框从独立页并进表单后，原样式让它换行跑到文字上方去了。
   复选框是行内首元素，必须固定尺寸、不参与 flex 伸缩，才会稳稳待在文字左边。 */
.custom-script-agree input[type='checkbox'] {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: #8b6cff;
  cursor: pointer;
}

/* 没勾之前「开始使用」必须**看起来**也是不能点的，
   只把 disabled 属性挂上而外观不变，用户会反复点然后以为坏了。 */
.custom-script-step .primary-wide[disabled] {
  opacity: 0.42;
  cursor: not-allowed;
  filter: grayscale(0.5);
}

.custom-script-agree label {
  cursor: pointer;
}

/* 条款链接是本行唯一的外链，给足对比度和触控命中区（移动端 44px 是底线，
   这里靠上下 padding 撑到位而不是改字号，避免把「同意」那句挤到第二行）。 */
.custom-script-terms-link {
  color: #b9a8ff;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  padding: 2px 0;
}

.custom-script-terms-link:hover {
  color: #d3c8ff;
}

.custom-script-agree input {
  margin-top: 2px;
  width: 18px;
  height: 18px;
  accent-color: #8b6cff;
  flex: 0 0 auto;
}

.custom-script-channel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px;
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
}

.custom-script-channel-title {
  margin: 0;
  font-size: 15px;
}

.custom-script-hint {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.68);
}

.custom-script-textarea,
.custom-script-input {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px;
  border-radius: 12px;
  color: #fff;
  background: rgba(0, 0, 0, 0.28);
  border: 1px solid rgba(255, 255, 255, 0.16);
  font: inherit;
  resize: vertical;
}

/* ══ CO0278 ══ 甲方：「粘贴剧本这个画面占比是最大的」。
   剧本正文是这个界面的主角，让它吃掉全部剩余高度；key 与按钮固定在下方不被挤走。
   ⛔ 别再退回 rows="6" 的小框：那是原界面显得复杂的主要原因之一。 */
.custom-script-step .custom-script-textarea {
  flex: 1 1 auto;
  /* ⚠️ 面板高度不受约束，所以 flex:1 没有"剩余空间"可长 —— 真正决定大小的是这个 min-height。
     用 vh 让它在手机和桌面都占据主导，同时封顶避免超长屏上失控。 */
  min-height: clamp(240px, 46vh, 520px);
}

/* 文件选择降级成一行浅色文字链接 —— 它是少数人的备选路径，不该和主输入区抢注意力 */
.custom-script-filelink {
  align-self: flex-start;
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.55);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.custom-script-filelink input { display: none; }

.custom-script-provider {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: -6px 0 0;
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.62);
}

.custom-script-advanced-toggle {
  border: 0;
  background: none;
  padding: 0;
  color: rgba(159, 212, 255, 0.9);
  font: inherit;
  font-size: 12.5px;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.custom-script-textarea:focus,
.custom-script-input:focus {
  outline: none;
  border-color: rgba(139, 108, 255, 0.7);
}

.custom-script-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

.custom-script-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.8);
}

.custom-script-key-row {
  display: flex;
  gap: 8px;
  align-items: stretch;
}

.custom-script-key-row .custom-script-input {
  flex: 1 1 auto;
}

.custom-script-key-toggle,
.custom-script-save,
.custom-script-file {
  padding: 9px 14px;
  border-radius: 12px;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
}

.custom-script-save {
  align-self: flex-start;
  background: rgba(139, 108, 255, 0.9);
  border-color: transparent;
  font-weight: 600;
}

.custom-script-file {
  display: inline-flex;
  align-items: center;
}

.custom-script-file input[type="file"] {
  display: none;
}

.custom-script-warn {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  color: #ffd27a;
}

.custom-script-status {
  margin: 0;
  min-height: 16px;
  font-size: 12.5px;
  color: #8fe3a0;
}

/* CO0268：官方 / 个人 API 连接窗口。个人配置只在浏览器本地使用。 */
.settings-ai-card {
  padding: 16px;
  border: 1px solid rgba(139, 108, 255, 0.24);
  border-radius: 14px;
  background: rgba(139, 108, 255, 0.055);
}

.ai-connection-badge {
  padding: 4px 8px;
  border: 1px solid rgba(100, 210, 255, 0.42);
  border-radius: 999px;
  color: #64d2ff;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.08em;
}

.ai-connection-badge.is-personal {
  border-color: rgba(139, 108, 255, 0.52);
  color: #b9a8ff;
}

.modal.ai-connection-modal {
  z-index: 70;
}

.ai-connection-panel {
  width: min(560px, 100%);
  max-height: calc(100dvh - 28px);
  gap: 15px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.ai-connection-intro,
.ai-connection-privacy,
.ai-connection-limit {
  margin: 0;
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.6;
}

.ai-connection-options {
  display: grid;
  gap: 10px;
}

.ai-connection-option {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) 20px;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 76px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 15px;
  background: var(--field);
  color: var(--text);
  text-align: left;
}

.ai-connection-option > span:nth-child(2) {
  min-width: 0;
  display: grid;
  gap: 4px;
}

.ai-connection-option strong {
  font-size: 14px;
}

.ai-connection-option small {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.45;
}

.ai-connection-option-mark {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: rgba(100, 210, 255, 0.12);
  color: #64d2ff;
  font-size: 11px;
  font-weight: 800;
}

.ai-connection-option > i {
  width: 18px;
  height: 18px;
  border: 2px solid var(--line);
  border-radius: 50%;
}

.ai-connection-option[aria-checked="true"] {
  border-color: rgba(139, 108, 255, 0.7);
  background: rgba(139, 108, 255, 0.09);
  box-shadow: 0 0 0 2px rgba(139, 108, 255, 0.08);
}

.ai-connection-option[aria-checked="true"] > i {
  border: 5px solid #8b6cff;
}

.ai-personal-config {
  display: grid;
  gap: 12px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: rgba(0, 0, 0, 0.1);
}

.ai-personal-config[hidden] {
  display: none;
}

.ai-connection-privacy {
  padding: 11px 12px;
  border: 1px solid rgba(100, 210, 255, 0.26);
  border-radius: 12px;
  background: rgba(100, 210, 255, 0.065);
  color: var(--text);
}

.ai-connection-limit {
  color: #d7a84f;
}

.ai-connection-actions {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  gap: 10px;
}

.ai-connection-delete {
  min-height: 44px;
  padding: 10px 13px;
  border: 1px solid rgba(255, 99, 99, 0.35);
  border-radius: 12px;
  background: transparent;
  color: #ff8989;
  font: inherit;
  font-size: 12px;
}

@media (max-width: 460px) {
  .ai-connection-actions {
    grid-template-columns: 1fr;
  }

  .ai-connection-actions .primary-wide {
    grid-row: 1;
  }
}

.story-slide {
  position: relative;
  flex: 0 0 84%;
  min-height: 430px;
  padding: 0;
  overflow: hidden;
  scroll-snap-align: center;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 26px;
  isolation: isolate;
  color: #fff;
  text-align: left;
  background:
    linear-gradient(158deg, hsl(var(--slide-tint) / 0.97) 0%, hsl(var(--slide-tint) / 0.52) 54%, #0d0f17 100%),
    #14131f;
  box-shadow: 0 22px 50px rgba(0, 0, 0, 0.34);
}

/* CO0125：封面从 CSS background-image 改成真正的 <img>（能被预扫描器提前发现），
   视觉用 object-fit/object-position 一比一复现原来的 background-size/position。
   LQIP 占位层与真图共用同一套几何，保证模糊图与清晰图严丝合缝地重合。 */
.story-slide-art,
.story-slide-lqip {
  position: absolute;
  top: 0;
  right: -6px;
  bottom: 0;
  width: 74%;
  height: 100%;
  display: block;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 44%);
  mask-image: linear-gradient(90deg, transparent 0%, #000 44%);
}

.story-slide.story-slide-full-art .story-slide-art,
.story-slide.story-slide-full-art .story-slide-lqip {
  inset: 0;
  width: 100%;
  -webkit-mask-image: none;
  mask-image: none;
}

/* ⚠️ 这几层刻意一律不写 z-index，纯靠 DOM 顺序决定绘制次序：
   lqip → art → shade → lock → body。
   Chrome 对 <button> 内的替换元素有个坑：带 z-index 的 <img>（负值、甚至小的正值）
   都不会被绘制，同位置的 <span> 背景却画得出来——封面从 background-image 改成真 <img>
   之后若沿用旧的 z-index:-2，整张封面会直接不显示。踩过，别再加回来。 */
.story-slide-art {
  object-fit: cover;
  object-position: 50% 14%;
  opacity: 0;
  transition: opacity 180ms ease;
}

.story-slide.story-slide-full-art .story-slide-art {
  object-position: 50% 35%;
}

.story-slide-art.is-loaded {
  opacity: 0.94;
}

.story-slide.story-slide-full-art .story-slide-art.is-loaded {
  opacity: 1;
}

.story-slide-art.is-failed {
  opacity: 0;
}

/* CO0125 冷启动首帧：内联 base64 LQIP（低质量模糊占位图，单张 ≤ 300B）。
   它随首屏 CSS 一起到达，画出来不需要任何网络请求，所以新用户/新设备第一次打开时
   卡片从第一帧起就有画面，不再是「纯色空卡 → 封面突然跳出来」。
   真图 .is-loaded 后淡入盖在上层，LQIP 保留在下层不移除（移除反而会闪）；
   真图 .is-failed 时 LQIP 正好当兜底。 */
.story-slide-lqip {
  background-repeat: no-repeat;
  background-size: cover;
  background-position: 50% 14%;
  filter: blur(12px);
  transform: scale(1.06);
}

.story-slide.story-slide-full-art .story-slide-lqip {
  background-position: 50% 35%;
}

.story-slide[data-art="isekaiAdventure"] .story-slide-lqip {
  background-image: url("data:image/webp;base64,UklGRt4AAABXRUJQVlA4INIAAADwBQCdASoVACAAPrVInkmnJCKhMAgA4BaJQBOmUGYP1gnwAdxe3T/TB1cm8vPoFoKTPqWH9FhRlAD+qvqBO3J0AuvRbfV5gvKtJrtDN2L/PcigID8J2S8MI7JU9yOz3k3s0vPqJzeZ+YiXFzWfgy1Jw49GG01CxmhFRdlyPc23/BfcfbYv5Annsom5+emFKgsWOFIUkWiVV8UFGIq4kRgFLZCbQAKkpvHynv+nDRcUWSkJidmg35z2WrC5xC/1t6fArd2s8Q4rTWVYyXfuf42AAAA=");
}

.story-slide[data-art="yuan05"] .story-slide-lqip,
.story-slide[data-art="swtlove"] .story-slide-lqip {
  background-image: url("data:image/webp;base64,UklGRg4BAABXRUJQVlA4IAIBAACQBgCdASogACAAPrVOoEqnJKMhsBgIAOAWiWQAnTKCWZqkACvpaLJJ4NWVvhbArjxXHPt1ND+MQnN19DiAAP7xhiAKh/XLOY7n5JmUx5AYezSWS4mj2FWa+IWdGx+zEWw4RBwoZggBYm1RFEgy+QGmjR6wiEL3mT5I4BTqAolF3ZE7bWAjP4ZK6Ld5Yg6wFi3QfV3qN7dLR4UJYNC2fdz5cSunLNUAOFovJE7vU4dDXjqsHjfBU+sTnJ332v3sZmvsOxaWnxVT9iws+T/VW2YL+9pktIhC/vuJjjUXJfKAEV6/eJ82U5jub1e5nHvVMIUfc5RAXg4vjBjzQkqXBTk7MAA=");
}

.story-slide[data-art="zhaozhiyi"] .story-slide-lqip {
  background-image: url("data:image/webp;base64,UklGRpYAAABXRUJQVlA4IIoAAAAQBACdASoPACAAPrVKn0onJCKhsAgA4BaJZwC7ACB/MIeNq7sA6zXQwAD+84Ghg9Vi6F2Ew89AX89FDcdZAgMn4jOEsyOB0aMEB1EaNy/87u+VIqhUfdCsd8yAG5sbR+dfqGERjAJP/BlwiU08rWGRjM0x7yfZpgWPrioSV0Ptficvy8tYXK/EDAA=");
}

@media (prefers-reduced-motion: reduce) {
  .story-slide-art {
    transition: none;
  }
}

.story-slide.story-slide-full-art .story-slide-shade {
  background:
    linear-gradient(0deg, rgba(8, 9, 15, 0.94) 3%, rgba(8, 9, 15, 0.64) 33%, rgba(8, 9, 15, 0.08) 67%),
    linear-gradient(90deg, rgba(8, 9, 15, 0.16), transparent 62%);
}

.story-slide-shade {
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, rgba(8, 9, 15, 0.86) 4%, rgba(8, 9, 15, 0.24) 46%, transparent 72%);
}

.story-slide-body {
  position: absolute;
  inset: auto 20px 22px 20px;
  display: flex;
  flex-direction: column;
}

.story-slide-kicker {
  color: #cdb9ff;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.14em;
}

.story-slide-title {
  margin: 9px 0 9px;
  font-size: 27px;
  line-height: 1.16;
  letter-spacing: -0.02em;
}

.story-limit-egg {
  display: inline-block;
  position: relative;
  user-select: none;
  -webkit-user-select: none;
}

.story-limit-egg.is-tapped {
  animation: story-egg-tap 160ms ease-out;
}

.story-limit-egg.is-unlocking,
.story-limit-egg.is-unlocked {
  color: #fff;
  text-shadow:
    0 0 8px rgba(142, 239, 255, 0.95),
    0 0 20px rgba(137, 96, 255, 0.86);
}

.story-limit-egg.is-unlocked {
  animation: story-egg-unlocked 1.1s ease-out both;
}

@keyframes story-egg-tap {
  50% { transform: scale(0.9); }
}

@keyframes story-egg-unlocked {
  0% { transform: scale(0.9); filter: brightness(1); }
  40% { transform: scale(1.18); filter: brightness(1.65); }
  100% { transform: scale(1); filter: brightness(1); }
}

.story-slide-desc {
  max-width: 90%;
  color: rgba(255, 255, 255, 0.66);
  font-size: 11px;
  line-height: 1.6;
  display: -webkit-box;
  overflow: hidden;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.story-slide-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 16px;
}

.story-slide-foot small {
  color: #b8a8ee;
  font-size: 10px;
  font-weight: 600;
}

/* CO0151：Enter Story 更醒目 + 视觉引导（更大点击区、更强对比、箭头右移暗示「进入」）。 */
.story-slide-cta {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 11px 18px;
  border: 1.5px solid transparent;
  border-radius: 14px;
  background: #8b6cff;
  color: #fff;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.02em;
  box-shadow: 0 8px 22px rgba(122, 83, 255, 0.34);
}

/* 箭头轻微右移循环，暗示「进入」；hover/focus 时再多推一点。 */
.story-slide-cta-arrow {
  display: inline-block;
  font-size: 15px;
  font-weight: 400;
  line-height: 1;
  transition: transform 0.2s ease;
  animation: ctaArrowNudge 1.9s ease-in-out infinite;
}

.story-slide:hover .story-slide-cta-arrow {
  transform: translateX(4px);
}

@keyframes ctaArrowNudge {
  0%, 100% { transform: translateX(0); }
  55% { transform: translateX(3px); }
}

/* CO0116 首页主次按钮差异化：有存档时 Continue 实心为主、Enter Story 描边为次；无存档反过来。
   CO0151：主态加缓慢呼吸紫光晕做视觉引导；次态（有 Continue 时）保留清晰描边+箭头引导但不抢主按钮。 */
.home-continue-card > button.is-home-cta-primary,
.story-slide-cta.is-home-cta-primary {
  background: #8b6cff;
  color: #fff;
  border-color: transparent;
  box-shadow: 0 8px 24px rgba(122, 83, 255, 0.34);
}

.story-slide-cta.is-home-cta-primary {
  animation: ctaGlowPulse 2.6s ease-in-out infinite;
}

@keyframes ctaGlowPulse {
  0%, 100% {
    box-shadow: 0 8px 22px rgba(122, 83, 255, 0.34), 0 0 0 0 rgba(139, 108, 255, 0);
  }
  50% {
    box-shadow: 0 10px 26px rgba(122, 83, 255, 0.5), 0 0 18px 3px rgba(139, 108, 255, 0.5);
  }
}

.home-continue-card > button.is-home-cta-ghost {
  background: transparent;
  color: #cbbcff;
  border-color: rgba(168, 140, 255, 0.62);
  box-shadow: none;
}

/* 次态（Enter Story 退为次按钮）：仍给足引导感——更亮描边 + 一点内发光，箭头照常轻移。 */
.story-slide-cta.is-home-cta-ghost {
  background: rgba(139, 108, 255, 0.16);
  color: #e6ddff;
  border-color: rgba(197, 179, 255, 0.85);
  box-shadow: inset 0 0 0 1px rgba(139, 108, 255, 0.18), 0 4px 16px rgba(122, 83, 255, 0.2);
  backdrop-filter: blur(8px);
}

/* CO0151/CO0155：大卡永远展开，Enter Story 固定放大一档更醒目。 */
.home-script-carousel.is-expanded .story-slide-cta {
  padding: 13px 22px;
  font-size: 13px;
  border-radius: 15px;
}

@media (prefers-reduced-motion: reduce) {
  /* 减少动效：呼吸光晕与箭头脉冲全部停掉。 */
  .story-slide-cta.is-home-cta-primary {
    animation: none;
  }
  .story-slide-cta-arrow {
    animation: none;
  }
}

.home-continue-card > button.is-home-cta-ghost b {
  color: rgba(203, 188, 255, 0.72);
}

.story-slide.selected {
  border-color: rgba(168, 140, 255, 0.85);
}

.story-slide.locked {
  filter: saturate(0.55);
  cursor: not-allowed;
}

.story-slide.locked .story-slide-cta {
  background: rgba(255, 255, 255, 0.14);
  box-shadow: none;
}

.story-slide-lock {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(10, 10, 16, 0.6);
  color: rgba(255, 255, 255, 0.82);
  font-family: ui-serif, "Songti SC", serif;
  font-size: 15px;
}

.home-carousel-dots {
  display: flex;
  gap: 6px;
  justify-content: center;
  margin: 13px 0 2px;
}

.home-carousel-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.24);
  transition: width 0.2s, background 0.2s;
  cursor: pointer;
}

.home-carousel-dot.active {
  width: 18px;
  border-radius: 3px;
  background: #9c86ff;
}

/* ===== CO0166 剧本卡：永远大图展开 + 底栏常驻（砍掉 CO0155 浮层开关） ===== */
/* 卡片下方的控制区：LAST PLAYED「继续」条 + dots。
   底栏已在 .game-home 网格里自占一行，这里不再预留 62px 槽位（否则底栏上方多出一块空白）。 */
.home-deck-controls {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex: 0 0 auto;
  padding-bottom: 4px;
}

.home-carousel-dots[hidden] {
  display: none;
}

/* CO0149 附带修复（沿用）：首页/底栏 UI chrome 文本不可选中，避免长按弹出 iOS 文本选择菜单。 */
.game-home-nav,
.home-section-head,
.home-carousel-dots,
.game-home-kicker {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}

.home-section-head {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 12px;
  margin: 0 2px 11px;
}

.home-section-head h2 {
  margin: 3px 0 0;
  font-size: 21px;
}

.home-section-head button {
  padding: 7px 9px;
  border: 0;
  background: transparent;
  /* CO0165：0.52 → 0.62。「管理剧本」正好压在右上主辉光上，氛围色换成暖色剧本（西游记）时
     背景会比原来的固定紫底亮一截；抬 alpha 把最坏情况的对比度从 4.4:1 拉回 5.2:1（原基线 5.19:1）。 */
  color: rgba(255, 255, 255, 0.62);
  font-size: 10px;
}

/* CO0156：主页右上角改为程序设置；背景音乐与音效都移入程序设置。 */
.home-section-tools {
  position: relative;
  width: 28px;
  height: 28px;
  flex: none;
  display: block;
}

.home-section-head .home-section-tools button {
  white-space: nowrap;
}

.home-runtime-mode-switch {
  position: absolute;
  top: 0;
  right: 36px;
  width: 138px;
  height: 28px;
  display: grid;
  grid-template-columns: 45px minmax(0, 1fr);
  padding: 2px;
  overflow: hidden;
  border: 1px solid rgba(89, 204, 255, 0.38);
  border-radius: 9px;
  background: linear-gradient(135deg, rgba(28, 134, 206, 0.22), rgba(123, 92, 255, 0.16));
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
  color: #d8f4ff;
  white-space: nowrap;
}

.home-runtime-mode-switch[hidden] {
  display: none;
}

/* ══ CO0256 本地 / Online 模式横幅 ═══════════════════════════════════════════
   甲方：「只是一个按钮的切换，并没有进行实质内容的切换」。这条横幅让切换当场可见，
   两个模式用不同颜色区分：本地=青蓝（功能全集），Online 预览=琥珀（受限视角）。
   ⚠️ 选择器故意挂在横幅自己的 [data-mode] 上，不挂 html 的 runtime-channel 属性：
      CO0246 有一条回归禁令，不许在那个属性选择器附近出现隐藏规则，防的是
      "预览模式把本地内容藏起来"。注意那条测试是纯文本正则、不区分注释与真规则，
      所以这段注释里也不能原样写出被禁的那个属性选择器。 */
.home-runtime-banner {
  margin: 0 0 10px;
  padding: 7px 12px;
  border-radius: 9px;
  border: 1px solid transparent;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.01em;
  line-height: 1.45;
}

.home-runtime-banner[hidden] {
  display: none;
}

.home-runtime-banner[data-mode='local'] {
  border-color: rgba(89, 204, 255, 0.32);
  background: linear-gradient(135deg, rgba(28, 134, 206, 0.16), rgba(123, 92, 255, 0.1));
  color: #cdeeff;
}

.home-runtime-banner[data-mode='online-preview'] {
  border-color: rgba(255, 186, 84, 0.42);
  background: linear-gradient(135deg, rgba(214, 138, 26, 0.2), rgba(206, 92, 42, 0.12));
  color: #ffdfae;
}

/* Owner 专属控件在 Online 预览里进入锁定态。
   ⛔ 是「锁定」不是「隐藏」：《本地与Online分支规则.md》明确要求预览不得隐藏或替换
      本地内容。变灰 + 禁点既做出了区别，又让人看得见东西还在。 */
:root[data-owner-locked='true'] .owner-only-badge {
  opacity: 0.4;
  filter: grayscale(1);
}

:root[data-owner-locked='true'] .contact-detail-creator {
  opacity: 0.42;
  filter: grayscale(0.85);
  pointer-events: none;
}

.home-section-head .home-runtime-mode-switch button {
  min-width: 0;
  height: 22px;
  display: grid;
  place-items: center;
  padding: 0 4px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: rgba(216, 244, 255, 0.58);
  font-size: 7.5px;
  font-weight: 780;
  letter-spacing: 0.015em;
  line-height: 1;
}

.home-section-head .home-runtime-mode-switch button[aria-pressed="true"] {
  background: rgba(80, 178, 255, 0.22);
  color: #8edcff;
  box-shadow: inset 0 0 0 1px rgba(142, 220, 255, 0.22);
}

.home-section-head .home-runtime-mode-switch button:focus-visible {
  outline: 2px solid #a7e5ff;
  outline-offset: -1px;
}

.home-section-head .home-settings-toggle {
  width: 28px;
  height: 28px;
  flex: none;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.05);
  color: #bdabff;
}

.home-settings-toggle svg {
  width: 15px;
  height: 15px;
  display: block;
}

.home-settings-toggle:focus-visible {
  outline: 2px solid #a88fff;
  outline-offset: 2px;
}

.home-script-list {
  display: grid;
  gap: 10px;
}

.home-script-card {
  position: relative;
  width: 100%;
  min-height: 96px;
  display: grid;
  grid-template-columns: 60px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 11px 12px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.045);
  color: #fff;
  text-align: left;
}

.home-script-card:hover,
.home-script-card:focus-visible,
.home-script-card.selected {
  border-color: rgba(149, 116, 255, 0.72);
  background: rgba(130, 93, 245, 0.13);
}

.home-script-card:disabled {
  cursor: not-allowed;
  filter: saturate(0.3);
  opacity: 0.52;
}

.home-script-cover {
  width: 58px;
  height: 72px;
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: 11px;
  background:
    radial-gradient(circle at 30% 20%, rgba(255, 255, 255, 0.3), transparent 24%),
    linear-gradient(145deg, #5d45a7, #151525);
  color: rgba(255, 255, 255, 0.86);
  font-family: ui-serif, "Songti SC", serif;
  font-size: 23px;
  font-weight: 700;
}

.home-script-copy {
  min-width: 0;
}

.home-script-copy strong {
  display: block;
  overflow: hidden;
  font-size: 14px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.home-script-copy p {
  display: -webkit-box;
  margin: 5px 0 7px;
  overflow: hidden;
  color: rgba(255, 255, 255, 0.46);
  font-size: 10px;
  line-height: 1.4;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.home-script-copy small {
  color: #a998eb;
  font-size: 9px;
}

.home-script-enter {
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.76);
  font-size: 22px;
}

/* CO0166：底栏常驻——占 .game-home 网格的第二行，正常参与布局流，不再绝对定位/平移隐藏。
   safe-area-inset-bottom 仍由 min-height + padding 吃掉，iOS 主页条不会压住 tab。
   CO0168：z-index 抬到 1100，压过衣橱页(80)与商城弹层(1000)，让底栏在三个 tab 页上都露出来、且自身不参与滑动。 */
.game-home-nav {
  position: relative;
  z-index: 1100;
  min-height: var(--home-nav-h);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  padding: 7px 12px max(7px, env(safe-area-inset-bottom));
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(13, 15, 23, 0.94);
  backdrop-filter: blur(20px);
}

/* CO0155：LAST PLAYED「继续」条（横排：文案 + 继续按钮），有存档时常驻显示。 */
.home-continue-bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  margin-top: 12px;
  padding: 12px 14px;
  border: 1px solid rgba(146, 111, 255, 0.3);
  border-radius: 16px;
  background: linear-gradient(120deg, rgba(129, 91, 255, 0.24), rgba(24, 20, 38, 0.9));
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.3);
}

.home-continue-bar[hidden] {
  display: none;
}

.home-continue-bar > div > span {
  color: rgba(255, 255, 255, 0.5);
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.home-continue-bar h2 {
  margin: 3px 0 2px;
  overflow: hidden;
  color: #fff;
  font-size: 15px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.home-continue-bar p {
  margin: 0;
  color: rgba(255, 255, 255, 0.45);
  font-size: 10px;
}

.home-continue-bar > button {
  min-height: 40px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 14px;
  border: 0;
  border-radius: 12px;
  background: #8b6cff;
  color: #fff;
  font-size: 12px;
  font-weight: 800;
  box-shadow: 0 8px 22px rgba(122, 83, 255, 0.34);
  cursor: pointer;
}

.home-continue-bar > button b {
  font-size: 20px;
  font-weight: 400;
}

@media (prefers-reduced-motion: reduce) {
  /* 减少动效：主页容器不做大位移过渡，直接切换（CO0166 后底栏常驻、本就无过渡）。 */
  .game-home {
    transition-duration: 1ms;
  }
}

.game-home-nav button {
  display: grid;
  place-items: center;
  align-content: center;
  gap: 2px;
  border: 0;
  background: transparent;
  color: rgba(255, 255, 255, 0.42);
  -webkit-appearance: none;
  appearance: none;
  -webkit-tap-highlight-color: transparent;
  transition:
    color 150ms ease,
    background 150ms ease,
    box-shadow 150ms ease;
}

.game-home-nav button:focus:not(:focus-visible) {
  outline: none;
}

.game-home-nav button:focus-visible {
  border-radius: 12px;
  outline: 2px solid #8b6cff;
  outline-offset: -3px;
  background: rgba(139, 108, 255, 0.1);
  box-shadow: inset 0 0 0 1px rgba(139, 108, 255, 0.22);
}

.game-home-nav button:active {
  background: rgba(139, 108, 255, 0.08);
  color: #b7a3ff;
}

.game-home-nav button.active {
  color: #a88fff;
}

/* CO0168 高亮平滑迁移：色值做过渡，图标轻微抬起，让「当前 tab」跟着页面滑动一起软着陆。 */
.game-home-nav button {
  transition:
    color 220ms ease,
    background 220ms ease;
}

.game-home-nav button .home-nav-icon {
  transition: transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
}

.game-home-nav button.active .home-nav-icon {
  transform: translateY(-1px) scale(1.06);
}

/* ============================================================
   CO0168：Stories / 衣橱 / 商城 三个 tab 共用同一条常驻底栏，内容区横向滑动切换。
   布局方案：不把弹层搬进网格，而是「底栏抬到弹层之上 + 弹层底部让出 --home-nav-h」——
   衣橱页(.wardrobe-screen) 与商城弹层(.econ-store-modal，由 economy-store.js 运行时注入样式)
   都保持原样式与关闭按钮，改动面最小，且完全不碰 economy-store.js（CO0167 正在改它）。
   :root.home-tabbar 只在主页语境（#gameHome 可见）挂上，故事内打开衣橱/商城仍是原来的全屏行为。
   ============================================================ */

/* 首页内容区（不含底栏）——离开 Stories tab 时整块向左滑走，底栏纹丝不动。 */
:root.home-tabbar .game-home-main {
  transition: transform var(--home-tab-slide);
}

:root.home-tabbar.wardrobe-open .game-home-main,
:root.home-tabbar.econ-store-open .game-home-main {
  transform: translateX(-100%);
}

/* 衣橱页：高度减去底栏，底栏从下方露出来。 */
:root.home-tabbar .wardrobe-screen {
  height: calc(var(--viewport-height, 100dvh) - var(--home-nav-h));
  transition:
    transform var(--home-tab-slide),
    opacity 220ms ease;
}

/* 进/出方向：--tab-dir = 1 从右侧、-1 从左侧（由 app.js 按 tab 先后顺序写入）。 */
:root.home-tabbar .wardrobe-screen:not(.show) {
  transform: translateX(calc(-50% + var(--tab-dir, 1) * min(var(--app-width), 100vw)));
}

/* 商城弹层：底部让出底栏；面板由上滑改成横滑，与衣橱同一套方位语言。 */
:root.home-tabbar .econ-store-modal {
  bottom: var(--home-nav-h) !important;
    /* 出场把 visibility 的延迟拉到与横滑同长，否则滑到一半就被 visibility:hidden 砍掉。 */
  transition:
    opacity 220ms ease,
    visibility 0s linear 300ms !important;
}

:root.home-tabbar .econ-store-modal.show {
  transition:
    opacity 220ms ease,
    visibility 0s !important;
}

:root.home-tabbar .econ-store-panel {
  height: 100% !important;
  transform: translateX(calc(var(--tab-dir, 1) * 100%)) !important;
  transition: transform var(--home-tab-slide) !important;
}

:root.home-tabbar .econ-store-modal.show .econ-store-panel {
  transform: translateX(0) !important;
}

@media (prefers-reduced-motion: reduce) {
  /* 减少动效：三个 tab 之间只做淡入淡出，不做横向位移。 */
  :root.home-tabbar .game-home-main {
    transition: opacity 160ms ease;
  }

  :root.home-tabbar.wardrobe-open .game-home-main,
  :root.home-tabbar.econ-store-open .game-home-main {
    transform: none;
    opacity: 0;
  }

  :root.home-tabbar .wardrobe-screen,
  :root.home-tabbar .wardrobe-screen:not(.show) {
    transform: translateX(-50%);
    transition: opacity 160ms ease;
  }

  :root.home-tabbar .econ-store-panel,
  :root.home-tabbar .econ-store-modal.show .econ-store-panel {
    transform: none !important;
    transition: none !important;
  }

  .game-home-nav button,
  .game-home-nav button .home-nav-icon {
    transition: none;
  }
}

.game-home-nav .home-nav-icon {
  width: 20px;
  height: 20px;
  display: block;
  line-height: 1;
}

.game-home-nav .home-nav-icon svg {
  width: 100%;
  height: 100%;
  display: block;
}

.game-home-nav strong {
  font-size: 9px;
}

.game-topbar {
  position: relative;
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) 44px;
  align-items: center;
  gap: 8px;
  min-height: 62px;
  padding: 8px 12px;
}

.game-topbar .chat-contact-btn {
  position: static;
  display: block;
  max-width: none;
  overflow: hidden;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text);
  font-size: 17px;
  font-weight: 750;
  text-align: center;
  text-overflow: ellipsis;
  transform: none;
  white-space: nowrap;
}

.game-topbar.stamina-enabled {
  grid-template-columns: 44px minmax(0, 1fr) auto 44px;
}

.stamina-hud {
  min-width: 70px;
  height: 36px;
  display: grid;
  grid-template-columns: 24px minmax(18px, auto) 18px;
  align-items: center;
  gap: 3px;
  padding: 4px 7px 4px 5px;
  border: 1px solid rgba(155, 115, 255, 0.34);
  border-radius: 18px;
  background: linear-gradient(145deg, rgba(61, 39, 91, 0.94), rgba(24, 20, 39, 0.96));
  color: #fff;
  box-shadow: 0 8px 24px rgba(30, 15, 57, 0.22);
}

.stamina-hud img {
  width: 24px;
  height: 24px;
  object-fit: contain;
}

.stamina-hud strong {
  font-size: 13px;
  line-height: 1;
  text-align: center;
}

.stamina-hud span {
  width: 18px;
  height: 18px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: #9f7cff;
  color: #fff;
  font-size: 14px;
  font-weight: 800;
  line-height: 1;
}

.game-home-back,
.game-settings-trigger {
  width: 42px;
  height: 42px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text);
}

.game-home-back {
  font-family: Arial, sans-serif;
  font-size: 42px;
  font-weight: 300;
  line-height: 34px;
}

.game-settings-trigger {
  border: 1px solid var(--line);
  border-radius: 13px;
  background: var(--field);
  font-size: 17px;
}

/* CO0130：聊天顶栏 ⚙ 的二选一浮层（剧本设置/游戏设置）。
   锚在 .game-topbar（已是 position:relative）右缘、按钮正下方，避开拇指区遮挡；点外面/Escape 关闭。 */
.game-settings-menu {
  position: absolute;
  top: calc(100% - 2px);
  right: 10px;
  z-index: 60;
  display: grid;
  gap: 2px;
  min-width: 186px;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 14px;
  /* 背景走主题变量：深夜主题为深底、经典聊天等浅色主题为白底，字色 var(--text) 两边都可读。 */
  background: var(--panel-strong);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.28);
}

.game-settings-menu[hidden] {
  display: none;
}

.game-settings-menu button {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 8px 12px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--text);
  font-size: 14px;
  text-align: left;
  cursor: pointer;
}

.game-settings-menu button:hover,
.game-settings-menu button:focus-visible {
  background: var(--field);
}

.game-settings-menu button img {
  width: 22px;
  height: 22px;
  flex: none;
}

.game-tools-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px;
}

.game-tools-grid button {
  min-height: 66px;
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  align-items: center;
  gap: 9px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--field);
  color: var(--text);
  text-align: left;
}

.game-tools-grid b {
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border-radius: 10px;
  background: rgba(100, 210, 255, 0.12);
  color: #64d2ff;
  font-size: 13px;
}

.game-tools-grid span {
  font-size: 12px;
  font-weight: 750;
}

.app {
  width: min(var(--app-width), 100%);
  height: var(--viewport-height, 100dvh);
  min-height: 0;
  margin: 0 auto;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
  background: rgba(9, 11, 16, 0.72);
  backdrop-filter: blur(24px);
  box-shadow: 0 0 70px rgba(0, 0, 0, 0.38);
  transition: transform 420ms cubic-bezier(0.22, 1, 0.36, 1), opacity 300ms ease;
}

/* ===== CO0174：键盘弹起时聊天内容被「推上去」，不再被打字栏盖住 =====
   --chat-keyboard-inset 由 public/app.js 用 visualViewport 实测得出（键盘收起时为 0px），
   绝不猜固定像素——中文输入法带候选栏时键盘更高，实测值会自动跟上。
   .play-screen 是 border-box 的 grid(auto / minmax(0,1fr) / auto)：加 padding-bottom 会让中间那行
   （.chat-stage / .messages）变矮、打字栏整体上移，于是最后一条消息始终留在可视区里。
   刻意不加 transition：padding 与键盘 1:1 同步，无额外动画，天然满足 prefers-reduced-motion。 */
.play-screen {
  padding-bottom: var(--chat-keyboard-inset, 0px);
}

.wardrobe-screen {
  position: fixed;
  z-index: 80;
  top: var(--viewport-offset-top, 0px);
  left: 50%;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  width: min(var(--app-width), 100vw);
  height: var(--viewport-height, 100dvh);
  overflow: hidden;
  background: #0b0e13;
  color: #f6f7f9;
  opacity: 0;
  pointer-events: none;
  transform: translateX(calc(-50% + min(var(--app-width), 100vw)));
  transition: transform 420ms cubic-bezier(0.22, 1, 0.36, 1), opacity 260ms ease;
  isolation: isolate;
}

:root.scene-open .app {
  opacity: 0;
  pointer-events: none;
  transform: translateX(-100%);
}

.scene-screen {
  position: fixed;
  z-index: 79;
  top: var(--viewport-offset-top, 0px);
  left: 50%;
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  width: min(var(--app-width), 100vw);
  height: var(--viewport-height, 100dvh);
  overflow: hidden;
  border-inline: 1px solid var(--line);
  background:
    radial-gradient(circle at 88% 5%, rgba(100, 210, 255, 0.13), transparent 28%),
    var(--bg);
  color: var(--text);
  opacity: 0;
  pointer-events: none;
  transform: translateX(calc(-50% + min(var(--app-width), 100vw)));
  transition: transform 420ms cubic-bezier(0.22, 1, 0.36, 1), opacity 260ms ease;
}

.scene-screen.show {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%);
}

.scene-screen-header {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr) 42px;
  align-items: center;
  gap: 11px;
  min-height: calc(72px + env(safe-area-inset-top));
  padding: max(12px, env(safe-area-inset-top)) 16px 12px;
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--panel-strong) 92%, transparent);
  backdrop-filter: blur(20px);
}

.scene-screen-header small {
  display: block;
  margin-bottom: 2px;
  color: var(--muted);
  font-size: 11px;
}

.scene-screen-header h2 {
  margin: 0;
  font-size: 21px;
  line-height: 1.2;
}

.scene-screen-back {
  width: 40px;
  height: 40px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--field);
  color: var(--text);
  font-size: 34px;
  font-weight: 400;
  line-height: 32px;
}

.scene-screen-symbol {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 12px;
  background: linear-gradient(145deg, #2aaeff, #1673df);
  color: #fff;
  font-size: 17px;
  font-weight: 800;
  box-shadow: 0 8px 20px rgba(10, 132, 255, 0.24);
}

.scene-screen-body {
  min-height: 0;
  overflow-y: auto;
  padding: 18px 16px calc(28px + env(safe-area-inset-bottom));
  overscroll-behavior: contain;
}

.scene-current-summary {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  align-items: center;
  gap: 14px;
  min-height: 104px;
  padding: 14px;
  border: 1px solid rgba(100, 210, 255, 0.48);
  border-radius: 18px;
  background: rgba(100, 210, 255, 0.08);
}

.scene-current-summary > i {
  width: 68px;
  height: 68px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(100, 210, 255, 0.56);
  border-radius: 19px;
  background-position: center;
  background-size: cover;
  overflow: hidden;
  font-style: normal;
}

.scene-current-summary > i b {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  background: rgba(3, 8, 14, 0.38);
  color: #bcecff;
  font-size: 24px;
  text-shadow: 0 2px 10px #000;
}

.scene-current-summary span {
  min-width: 0;
}

.scene-current-summary span small {
  display: block;
  margin-bottom: 3px;
  color: #64d2ff;
  font-size: 10px;
  font-weight: 750;
}

.scene-current-summary span strong {
  display: block;
  font-size: 18px;
}

.scene-current-summary span p {
  margin: 5px 0 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
}

.scene-screen-section-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: 12px;
  margin: 24px 2px 11px;
}

.scene-screen-section-head small {
  color: var(--muted);
  font-size: 10px;
}

.scene-screen-section-head h3 {
  margin: 3px 0 0;
  font-size: 16px;
}

.scene-screen-section-head > span {
  max-width: 132px;
  color: var(--muted);
  font-size: 9px;
  line-height: 1.4;
  text-align: right;
}

.scene-screen .scene-list {
  gap: 10px;
}

.scene-screen .scene-option {
  min-height: 82px;
  grid-template-columns: 58px minmax(0, 1fr) auto;
  gap: 13px;
  padding: 11px 12px;
  border-radius: 16px;
  background: var(--panel-strong);
  box-shadow: 0 7px 24px rgba(0, 0, 0, 0.08);
}

.scene-screen .scene-option > i {
  width: 56px;
  height: 56px;
}

.scene-screen .scene-option strong {
  font-size: 15px;
}

.scene-screen .scene-option small {
  margin-top: 4px;
  font-size: 11px;
}

.scene-screen .scene-option em {
  font-size: 11px;
  font-weight: 750;
}

:root[data-theme="wechat"] .scene-screen {
  background: #f5f5f5;
}

:root[data-theme="wechat"] .scene-screen-header {
  background: rgba(255, 255, 255, 0.94);
}

:root[data-theme="wechat"] .scene-screen .scene-option {
  background: #fff;
}

.wardrobe-screen.show {
  opacity: 1;
  pointer-events: auto;
  transform: translateX(-50%);
}

:root.wardrobe-open .app {
  pointer-events: none;
  transform: translateX(-100%);
}

.wardrobe-screen-backdrop {
  position: absolute;
  z-index: -2;
  inset: -44px;
  background-position: 50% 22%;
  background-size: cover;
  filter: blur(34px) saturate(0.72) brightness(0.48);
  transform: scale(1.18);
}

.wardrobe-screen::after {
  position: absolute;
  z-index: -1;
  inset: 0;
  content: "";
  background: linear-gradient(180deg, rgba(7, 9, 13, 0.68) 0%, rgba(7, 9, 13, 0.08) 34%, rgba(7, 9, 13, 0.2) 62%, rgba(7, 9, 13, 0.94) 100%);
  pointer-events: none;
}

.wardrobe-screen-header {
  z-index: 3;
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  min-height: calc(62px + env(safe-area-inset-top));
  padding: max(10px, env(safe-area-inset-top)) 16px 10px;
}

.wardrobe-screen-header h2,
.wardrobe-screen-header small { margin: 0; }
.wardrobe-screen-header h2 { font-size: 17px; letter-spacing: 0; }
.wardrobe-screen-header small { color: rgba(255, 255, 255, 0.58); font-size: 10px; }
.wardrobe-back-btn {
  width: 38px;
  height: 38px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 50%;
  background: rgba(10, 13, 18, 0.48);
  color: #fff;
  font-size: 31px;
  line-height: 30px;
  backdrop-filter: blur(14px);
}
.wardrobe-screen-count { color: rgba(255, 255, 255, 0.66); font-size: 12px; font-variant-numeric: tabular-nums; }
/* CO0181：立绘改成「填满整格高度」。stage 用 flex 居中而不是让 img 自己 width:100%——
   flex 的 justify-content:center 在内容比容器宽时会向两侧对称溢出（auto margin 不会，它会靠左顶出去），
   配合 overflow:hidden 才是左右均等裁切。 */
.wardrobe-stage { position: relative; display: flex; align-items: stretch; justify-content: center; min-height: 0; overflow: hidden; }
/* CO0193 甲方：「立绘底色不统一」。见习冒险者是抠透明的（背后能看见 CO0185 的流光），
   月夜女剑士 / 兔女郎 / 咖啡馆常服是**烤死暗底**的，左右翻页时整块背景会跳一下。
   ⚠️ 抠图不在前端能力范围内（要图像处理，另有流水线）。这里做的是把落差**收敛**：
   给舞台铺一层和那几张烤死底同亮度的暗底（取样自 yuki-swordswoman/bunny 的四角，RGB 大约 9~25），
   透明立绘于是站在同一块地板上，翻页时只换人不换屋子。
   ⛔ 不是纯色：纯色会把 CO0185 的流光压成脏斑；用极低对比的竖向渐变+顶部一点冷光，
      让流光有地方可流，同时整体亮度锁在烤死底附近。 */
.wardrobe-stage.econ-outfit-media {
  height: auto;
  min-height: 0;
  background:
    radial-gradient(120% 62% at 50% 8%, rgba(38, 46, 66, 0.55), transparent 68%),
    linear-gradient(180deg, #10141d 0%, #0b0f17 52%, #070a10 100%);
}
/* CO0193 暗角：贴在立绘**之下**（::before 在 DOM 上先于 img，z-index 同为 1 → img 照常盖住它）。
   于是烤死底的立绘完全看不见这层（它自己不透明），只有透明立绘才吃到——正好补上它缺的那圈暗边，
   两类立绘的边缘亮度这才对得上。⛔ 不要改成 ::after：::after 已被 economy-store.js 的底部压暗层占用。 */
.wardrobe-stage.econ-outfit-media::before {
  position: absolute;
  z-index: 1;
  inset: 0;
  background: radial-gradient(118% 82% at 50% 40%, transparent 34%, rgba(8, 10, 15, 0.5) 76%, rgba(6, 8, 12, 0.8) 100%);
  content: "";
  pointer-events: none;
}
/* CO0181 甲方：「画面整体放大。」
   原来是 width:100% + object-fit:contain：立绘按**宽度**贴边，高度按 3:4 算完就到头了
   （现有立绘 900x1200 / 1086x1448 都是 3:4，比画框瘦长比更矮）。所以撤掉缩略图带腾出的
   ~100px 竖向空间会全变成上下黑边，立绘一个像素都不会变大——甲方要的「放大」根本不会发生。
   现在反过来：height:100% + width:auto，立绘先吃满整格高度，宽度按比例自然算出；
   算出来比画框宽就左右对称裁掉那点背景（人物在正中，裁的是空背景）。
   ⛔ 永远不做竖向裁切——服装是这一页的主角，头到脚必须完整，宁可左右少一条背景。
   max-width 是安全阀：画框极瘦长时（桌面窄列 + 高屏）不许为了填高度把人物两侧啃掉超过 10%，
   超了就退回留白，此时 object-fit:contain 保证只是留边而不是拉伸变形。 */
.wardrobe-hero,
.wardrobe-hero.econ-outfit-image {
  display: block;
  flex: 0 0 auto;
  width: auto;
  max-width: 120%;
  height: 100%;
  object-fit: contain;
  object-position: 50% 38%;
  filter: drop-shadow(0 24px 24px rgba(0, 0, 0, 0.48));
}
.wardrobe-hero.econ-outfit-image.is-zoomed {
  filter: drop-shadow(0 28px 32px rgba(0, 0, 0, 0.54));
}
.wardrobe-no-art {
  position: absolute;
  z-index: 1;
  inset: 0;
  display: grid;
  place-items: center;
  margin: 0;
  padding: 0 34px 24%;
  color: rgba(255, 255, 255, 0.58);
  font-size: 13px;
  line-height: 1.65;
  text-align: center;
}
.wardrobe-no-art[hidden] { display: none; }
/* ══ CO0185 衣橱流动特效（甲方：「做橱柜特效，流动的感觉」） ═══════════════════════
   两层，都只动 transform/opacity——合成器属性，手机 PWA 上不触发重排重绘、不掉帧。
     ① .wardrobe-flow  背景流光：两团大面积柔光在立绘背后极慢漂移(26s)，主色取当前服装的
        --econ-accent（app.js:3003 按服装写入），换一套衣服整间屋子的光就换个颜色。
     ② .wardrobe-sheen 丝光扫过：一条斜向高光带周期性掠过画面(11s 里只扫 3.3s，其余时间在画外)。
        这条是「流动」的主角——布料上有光滑过去，才像在试衣间里转身，而不是一张贴图。
   ⛔ 不做粒子、不做闪烁：立绘是商品，特效的职责是衬托它，不是抢它。
   ⛔ 节奏刻意留长间隔：连续不断的扫光在长时间停留的页面上会变成视觉噪音。 */
.wardrobe-flow {
  position: absolute;
  z-index: 0;
  inset: -18%;
  background:
    radial-gradient(42% 30% at 28% 32%, color-mix(in srgb, var(--econ-accent, #73d7ea) 40%, transparent), transparent 70%),
    radial-gradient(38% 26% at 74% 64%, color-mix(in srgb, var(--econ-accent, #73d7ea) 26%, #c58bff 18%), transparent 72%);
  filter: blur(26px);
  opacity: 0.5;
  will-change: transform;
  animation: wardrobe-flow-drift 26s ease-in-out infinite alternate;
  pointer-events: none;
}
@keyframes wardrobe-flow-drift {
  0% { transform: translate3d(-4%, -3%, 0) scale(1); }
  50% { transform: translate3d(3%, 4%, 0) scale(1.08); }
  100% { transform: translate3d(-2%, 2%, 0) scale(1.03); }
}
.wardrobe-sheen {
  position: absolute;
  z-index: 1;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.wardrobe-sheen::before {
  position: absolute;
  top: -30%;
  bottom: -30%;
  left: 0;
  width: 34%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.1) 40%, rgba(255, 255, 255, 0.17) 50%, rgba(255, 255, 255, 0.1) 60%, transparent);
  content: "";
  will-change: transform, opacity;
  animation: wardrobe-sheen-sweep 11s cubic-bezier(0.42, 0, 0.5, 1) infinite;
}
@keyframes wardrobe-sheen-sweep {
  0% { opacity: 0; transform: rotate(9deg) translate3d(-120%, 0, 0); }
  6% { opacity: 1; }
  24% { opacity: 1; }
  30%, 100% { opacity: 0; transform: rotate(9deg) translate3d(360%, 0, 0); }
}
/* 变焦查看时（CO0148 希区柯克变焦）玩家是在**细看这套衣服**，此刻扫光只会碍事，收掉。 */
.wardrobe-stage.is-zoomed .wardrobe-sheen { opacity: 0; transition: opacity 0.2s ease; }
/* ══ CO0193 立绘呼吸感（甲方：「是不是应该让角色动起来」）══════════════════════
   只做「呼吸」这一件事：9s 一个来回、幅度 1.2% 缩放 + 0.5% 上浮，慢到看不出在动、
   停下来又觉得画面死了。⛔ 不加粒子、不加闪烁、不叠第三层——CO0185 已经有流光和扫光，
   立绘是商品，再堆特效就是抢戏。
   ⚠️ 关键：用独立变换属性 scale / translate，**不能**用 transform。
      CO0148 的希区柯克变焦靠 .is-zoomed 的 transform 过渡实现；
      一个 infinite 的 transform 动画会永久压住那条 transition，点了立绘就不再变焦。
      scale/translate 是独立属性，与 transform 相乘合成，两者互不打架。
   动画列表里必须把 econ-outfit-enter 一起写上：animation 是简写，
   这条规则（.wardrobe-hero.econ-outfit-image，特异性更高）会整条覆盖 economy-store.js 注入的那条，
   漏写换装入场动画就没了。⛔ 同样不许加 fill-mode，理由见 economy-store.js 里那段注释。 */
.wardrobe-hero.econ-outfit-image {
  animation:
    econ-outfit-enter 0.36s cubic-bezier(0.22, 0.75, 0.28, 1),
    wardrobe-hero-breathe 9s ease-in-out 0.5s infinite alternate;
}
@keyframes wardrobe-hero-breathe {
  from { scale: 1; translate: 0 0; }
  to { scale: 1.012; translate: 0 -0.5%; }
}
/* 变焦细看这套衣服时，呼吸停下——此刻玩家在看细节，动的东西只会碍事（和扫光同一处理）。 */
.wardrobe-hero.econ-outfit-image.is-zoomed {
  scale: 1;
  translate: 0 0;
  animation: none;
}
@media (prefers-reduced-motion: reduce) {
  /* 减少动效：留下静态的氛围色，去掉一切移动的东西。 */
  .wardrobe-flow { animation: none; transform: none; }
  .wardrobe-sheen { display: none; }
  /* 呼吸也去掉，只保留 CO0169 的换装入场（那条是 .36s 的一次性淡入，不属于「停不下来的循环」）。 */
  .wardrobe-hero.econ-outfit-image {
    animation: econ-outfit-enter 0.36s cubic-bezier(0.22, 0.75, 0.28, 1);
    scale: 1;
    translate: 0 0;
  }
}
/* CO0169：底部压暗层与服装名必须盖在立绘之上。
   立绘现在是 z-index:1（为了压住新加的氛围光 .econ-outfit-glow），而 z-index 定位元素
   一律画在 auto 的定位元素之上——不显式抬到 2，竖构图立绘（如白兔 1000x2108 撑满整格）
   会把服装名和描述整条盖掉。 */
.wardrobe-stage-shade {
  position: absolute;
  z-index: 2;
  inset: auto 0 0;
  height: 38%;
  background: linear-gradient(transparent, rgba(7, 9, 13, 0.88));
  pointer-events: none;
}
.wardrobe-look-caption { position: absolute; z-index: 2; right: 20px; bottom: 18px; left: 20px; }
.wardrobe-look-caption small { color: #73d7ea; font-size: 11px; font-weight: 700; }
.wardrobe-look-caption h3 { margin: 3px 0 4px; font-size: 25px; letter-spacing: 0; }
.wardrobe-look-caption p { margin: 0; color: rgba(255, 255, 255, 0.66); font-size: 12px; }
/* CO0193 拥有状态徽章。做成小号 pill 而不是正文一行：外观描述才是这一屏要读的，
   状态只需要「一眼扫到」。付费服装才出现，免费默认服全程 hidden（对免费服说「已拥有」没有信息量）。 */
.wardrobe-look-caption .wardrobe-look-state {
  display: inline-block;
  margin: 0 0 6px;
  padding: 3px 9px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.5;
}
.wardrobe-look-caption .wardrobe-look-state[hidden] { display: none; }
/* 已拥有＝安心色，和标题栏眉标同一支青色，读作「这是你的」 */
.wardrobe-look-caption .wardrobe-look-state.is-owned {
  border-color: rgba(115, 215, 234, 0.42);
  background: rgba(115, 215, 234, 0.14);
  color: #a9e8f4;
}
/* 未解锁＝商品色（金），和商城价格同一支，读作「还要花钱」 */
.wardrobe-look-caption .wardrobe-look-state.is-locked {
  border-color: rgba(255, 209, 128, 0.4);
  background: rgba(255, 209, 128, 0.12);
  color: #ffd9a0;
}
.wardrobe-dock {
  z-index: 3;
  display: grid;
  gap: 12px;
  padding: 12px 16px max(14px, env(safe-area-inset-bottom));
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(8, 10, 15, 0.84);
  backdrop-filter: blur(22px);
}
.wardrobe-screen-list { display: flex; gap: 10px; overflow-x: auto; scrollbar-width: none; }
.wardrobe-screen-list::-webkit-scrollbar { display: none; }
/* ===== CO0181：翻页行（替代缩略图带） =====
   甲方：「这个不要。画面整体放大。」缩略图带（62x74 图 + 文字标签 + 间距 ≈ 100px）整条撤掉，
   换成一行 40px 的 ‹ ● ● ● ›，且只有 2 套以上才出现——只有一套时这一行不占位，
   竖向空间一分不留全给立绘（.wardrobe-stage 是 minmax(0,1fr)，dock 变矮它自动长高）。
   视觉与方位语言照抄商城 CO0169 的 .econ-outfit-pagination，只把主色换成衣橱的青(#73d7ea)。 */
/* 隐藏走全局 [hidden]{display:none!important}（styles.css:177），这里不用再补 [hidden] 规则。 */
.wardrobe-pager { display: flex; align-items: center; justify-content: center; gap: 14px; min-height: 40px; }
.wardrobe-pager-nav {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 50%;
  background: rgba(12, 11, 17, 0.66);
  color: #fff;
  font-size: 23px;
  line-height: 1;
  transition: background 0.18s ease, transform 0.18s ease;
}
.wardrobe-pager-nav:hover { background: rgba(115, 215, 234, 0.24); }
.wardrobe-pager-nav:active { transform: scale(0.94); }
.wardrobe-pager-dots { display: flex; align-items: center; justify-content: center; gap: 8px; }
.wardrobe-pager-dot {
  width: 9px;
  height: 9px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.22);
  transition: width 0.2s ease, background 0.2s ease;
}
.wardrobe-pager-dot.active { width: 28px; background: linear-gradient(90deg, #73d7ea, #8b6cff); }
@media (prefers-reduced-motion: reduce) {
  .wardrobe-pager-nav,
  .wardrobe-pager-dot { transition: none; }
}
.wardrobe-look-option {
  flex: 0 0 72px;
  display: grid;
  gap: 5px;
  padding: 4px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: rgba(255, 255, 255, 0.62);
}
.wardrobe-look-option img,
.wardrobe-look-option-noart {
  width: 62px;
  height: 74px;
  border-radius: 6px;
  background: #181d26;
}
.wardrobe-look-option img { object-fit: cover; object-position: 50% 18%; }
.wardrobe-look-option-noart {
  display: grid;
  place-items: center;
  color: rgba(185, 168, 255, 0.62);
}
.wardrobe-look-option-noart svg { width: 26px; height: 26px; }
.wardrobe-look-option-label { overflow: hidden; font-size: 10px; text-overflow: ellipsis; white-space: nowrap; }
.wardrobe-look-option.selected { border-color: #73d7ea; background: rgba(115, 215, 234, 0.1); color: #fff; }
.wardrobe-wear-btn {
  min-height: 46px;
  border: 0;
  border-radius: 8px;
  background: #73d7ea;
  color: #071116;
  font-size: 14px;
  font-weight: 800;
}
.wardrobe-wear-btn:disabled { background: rgba(255, 255, 255, 0.12); color: rgba(255, 255, 255, 0.46); }
.wardrobe-screen-status {
  min-height: 16px;
  margin: -4px 2px 0;
  color: rgba(255, 255, 255, 0.58);
  font-size: 10px;
  line-height: 1.45;
  text-align: center;
}
.wardrobe-owned-empty {
  min-height: 0;
  place-content: center;
  justify-items: center;
  gap: 10px;
  padding: 30px 24px;
  text-align: center;
}
.wardrobe-owned-empty:not([hidden]) { display: grid; }
.wardrobe-owned-empty svg {
  width: 54px;
  height: 54px;
  margin-bottom: 4px;
  color: rgba(185, 168, 255, 0.78);
}
.wardrobe-owned-empty strong { font-size: 18px; }
.wardrobe-owned-empty p {
  margin: 0;
  color: rgba(255, 255, 255, 0.58);
  font-size: 12px;
}
.wardrobe-owned-empty button {
  min-height: 42px;
  margin-top: 8px;
  padding: 0 18px;
  border: 1px solid rgba(185, 168, 255, 0.32);
  border-radius: 12px;
  background: linear-gradient(145deg, #8b6cff, #6f57ce);
  color: #fff;
  font-size: 13px;
  font-weight: 800;
}

.chat-stage {
  position: relative;
  min-height: 0;
  overflow: hidden;
  isolation: isolate;
}

.scene-background {
  position: absolute;
  z-index: -2;
  inset: -28px;
  background-color: #10141c;
  background-position: center;
  background-size: cover;
  filter: blur(20px) saturate(0.88);
  opacity: 0.72;
  transform: scale(1.08);
  transition: background-image 0.28s ease, opacity 0.28s ease;
  pointer-events: none;
}

.chat-stage::after {
  position: absolute;
  z-index: -1;
  inset: 0;
  content: "";
  background: rgba(7, 10, 15, 0.58);
  pointer-events: none;
}

.topbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 16px;
  /* CO0129：black-translucent 后页面顶到状态栏下。≤560px 已有覆盖（见下方媒体查询），
     这里兜住 >560px 的宽视口（iPad 主屏 PWA）；env() 在桌面为 0，max() 不改变原值。 */
  padding: max(18px, env(safe-area-inset-top)) 20px 14px;
  border-bottom: 1px solid var(--line);
  background: rgba(16, 18, 25, 0.86);
}

.chat-contact-btn {
  display: none;
}

.settings-membership-btn {
  min-height: 40px;
  border: 1px solid rgba(10, 132, 255, 0.35);
  border-radius: 12px;
  background: rgba(10, 132, 255, 0.08);
  color: var(--text);
  font-size: 13px;
  font-weight: 700;
}

.settings-account-card {
  display: grid;
  grid-template-columns: 46px minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--field);
}

.settings-account-avatar {
  width: 46px;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid rgba(100, 210, 255, 0.45);
  border-radius: 50%;
  background: rgba(100, 210, 255, 0.1);
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  color: #74d8f0;
  cursor: pointer;
  font-size: 19px;
  font-weight: 800;
  overflow: hidden;
}

.settings-account-avatar:focus-visible {
  outline: 2px solid #74d8f0;
  outline-offset: 3px;
}

.update-banner {
  position: fixed;
  top: max(12px, env(safe-area-inset-top));
  left: 50%;
  z-index: 10000;
  width: min(calc(100% - 24px), 406px);
  min-height: 48px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto 36px;
  align-items: center;
  gap: 8px;
  padding: 7px 7px 7px 14px;
  border: 1px solid rgba(100, 210, 255, 0.38);
  border-radius: 8px;
  background: rgba(18, 24, 36, 0.96);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.28);
  color: #f5f7fb;
  transform: translateX(-50%);
  backdrop-filter: blur(18px);
}

.update-banner[hidden] {
  display: none;
}

.update-banner > span {
  min-width: 0;
  font-size: 13px;
  font-weight: 700;
}

.update-banner > button {
  min-height: 34px;
  padding: 0 12px;
  border: 0;
  border-radius: 6px;
  background: #70d4e9;
  color: #071016;
  font-size: 12px;
  font-weight: 800;
}

.update-banner > .update-banner-dismiss {
  width: 36px;
  padding: 0;
  background: transparent;
  color: #c3cad6;
  font-size: 20px;
}

.settings-update-card {
  gap: 12px;
}

.settings-update-card code {
  max-width: 150px;
  overflow: hidden;
  color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.settings-update-card > button {
  width: 100%;
  min-height: 42px;
}

.settings-account-copy {
  min-width: 0;
  display: grid;
  gap: 3px;
}

.settings-account-copy > span,
.settings-section-head span,
.settings-membership-grid dt {
  color: var(--muted);
  font-size: 11px;
}

.settings-account-copy strong {
  overflow: hidden;
  font-size: 14px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.settings-account-copy small {
  color: var(--muted);
  font-size: 11px;
}

.settings-account-badge {
  padding: 5px 7px;
  border: 1px solid rgba(100, 210, 255, 0.35);
  border-radius: 5px;
  color: #74d8f0;
  font-size: 9px;
  font-weight: 800;
}

.settings-account-badge[data-plan="owner"] {
  border-color: rgba(255, 192, 83, 0.45);
  color: #ffc053;
}

.settings-account-badge[data-plan="monthly"],
.settings-account-badge[data-plan="annual"],
.settings-account-badge[data-plan="lifetime"],
.settings-account-badge[data-plan="member"] {
  border-color: rgba(48, 209, 88, 0.4);
  color: #30d158;
}

/* CO0114：账号卡可点击进入「个人账号」详情页 */
.settings-account-card-clickable {
  grid-template-columns: 46px minmax(0, 1fr) auto 14px;
  cursor: pointer;
}

.settings-account-card-clickable:focus-visible {
  outline: 2px solid #a88fff;
  outline-offset: 2px;
}

.settings-account-chevron {
  color: var(--muted);
  font-size: 20px;
  font-weight: 400;
  line-height: 1;
}

/* CO0114：程序设置里的三个内页入口（个人账号 / 剧本设置 / 游戏设置） */
.settings-subpage-nav {
  gap: 8px;
}

.settings-subpage-row {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) 14px;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 11px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--field);
  color: var(--text);
  text-align: left;
}

.settings-subpage-row > img {
  width: 34px;
  height: 34px;
  object-fit: contain;
  display: block;
}

.settings-subpage-row > span {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.settings-subpage-row strong {
  font-size: 13px;
  font-weight: 700;
}

.settings-subpage-row small {
  color: var(--muted);
  font-size: 10px;
}

.settings-subpage-row > b {
  color: var(--muted);
  font-size: 20px;
  font-weight: 400;
  line-height: 1;
}

.settings-subpage-row:focus-visible {
  outline: 2px solid #a88fff;
  outline-offset: 2px;
}

/* CO0114：个人账号详情页 · 删除账号按钮（危险） */
.settings-delete-btn {
  border-color: rgba(255, 99, 99, 0.5);
  color: #ff6b6b;
}

/* CO0114：剧本设置内页 */
.script-settings-icon {
  width: 38px;
  height: 38px;
  object-fit: contain;
}

.script-settings-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.settings-section {
  display: grid;
  gap: 12px;
  padding: 14px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.settings-section + .settings-section {
  border-top: 0;
}

.settings-section-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}

.settings-section-head > div {
  display: grid;
  gap: 3px;
}

.settings-section-head h3 {
  margin: 0;
  font-size: 15px;
}

.settings-section-head > strong {
  color: #30d158;
  font-size: 12px;
}

.settings-membership-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  margin: 0;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 8px;
}

.settings-membership-grid > div {
  min-width: 0;
  display: grid;
  gap: 5px;
  padding: 11px;
}

.settings-membership-grid > div + div {
  border-left: 1px solid var(--line);
}

.settings-membership-grid dd {
  min-width: 0;
  margin: 0;
  overflow: hidden;
  font-size: 13px;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.settings-membership-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.settings-membership-actions > button:only-child {
  grid-column: 1 / -1;
}

.settings-upgrade-btn {
  min-height: 42px;
  border: 0;
  border-radius: 8px;
  background: #6dd0e4;
  color: #071018;
  font-weight: 800;
}

.settings-shop-grid {
  display: grid;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 8px;
}

.settings-shop-item {
  min-width: 0;
  min-height: 58px;
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  align-items: center;
  gap: 11px;
  padding: 10px 12px;
  border: 0;
  border-radius: 0;
  background: var(--field);
  color: var(--text);
  text-align: left;
}

.settings-shop-item + .settings-shop-item {
  border-top: 1px solid var(--line);
}

.settings-shop-item i {
  width: 34px;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  border-radius: 7px;
  background: rgba(100, 210, 255, 0.12);
  color: #74d8f0;
  font-style: normal;
  font-weight: 800;
}

.settings-shop-item.crypto i {
  background: rgba(38, 161, 123, 0.14);
  color: #38c99a;
}

.settings-shop-item span {
  min-width: 0;
  display: grid;
  gap: 3px;
}

.settings-shop-item strong {
  font-size: 13px;
}

.settings-shop-item small {
  color: var(--muted);
  font-size: 10px;
}

.settings-shop-item em {
  color: var(--muted);
  font-size: 22px;
  font-style: normal;
}

.settings-shop-item:disabled {
  cursor: default;
  opacity: 0.46;
}

.settings-shop-item.is-current {
  opacity: 0.7;
}

.store-panel {
  width: min(520px, 100%);
}

.stamina-store-modal,
.stamina-empty-modal {
  z-index: 86;
}

.stamina-store-modal {
  align-items: flex-end;
  padding: 12px;
}

.stamina-store-panel {
  width: 100%;
  max-height: min(760px, calc(var(--viewport-height, 100dvh) - 24px));
  overflow-y: auto;
  padding: 18px;
  border-color: rgba(158, 119, 255, 0.28);
  border-radius: 24px 24px 18px 18px;
  background:
    radial-gradient(circle at 85% 0%, rgba(143, 101, 255, 0.16), transparent 34%),
    var(--panel-strong);
}

.stamina-balance-card {
  min-height: 76px;
  display: grid;
  grid-template-columns: 58px minmax(0, 1fr);
  align-items: center;
  gap: 13px;
  padding: 10px 13px;
  border: 1px solid rgba(160, 120, 255, 0.24);
  border-radius: 18px;
  background: linear-gradient(135deg, rgba(107, 72, 170, 0.18), rgba(71, 44, 103, 0.06));
}

.stamina-balance-card > img {
  width: 58px;
  height: 58px;
  object-fit: contain;
  filter: drop-shadow(0 8px 10px rgba(40, 20, 15, 0.18));
}

.stamina-balance-card > div {
  min-width: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: end;
  gap: 2px 9px;
}

.stamina-balance-card small {
  grid-column: 1 / -1;
  color: var(--muted);
  font-size: 10px;
}

.stamina-balance-card strong {
  color: var(--text);
  font-size: 30px;
  line-height: 1;
}

.stamina-balance-card span {
  align-self: center;
  color: var(--muted);
  font-size: 10px;
  line-height: 1.35;
}

.stamina-store-tabs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 15px;
  background: var(--field);
}

.stamina-store-tabs button {
  min-height: 42px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  border: 0;
  border-radius: 11px;
  background: transparent;
  color: var(--muted);
  font-size: 12px;
  font-weight: 760;
}

.stamina-store-tabs button.active {
  background: var(--panel-strong);
  color: var(--text);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}

.stamina-store-tabs img {
  width: 24px;
  height: 24px;
  object-fit: contain;
}

.stamina-tab-summary {
  min-height: 27px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.stamina-tab-summary p {
  margin: 0;
  color: var(--muted);
  font-size: 10px;
  line-height: 1.4;
}

.stamina-discount-badge {
  flex: none;
  padding: 5px 8px;
  border: 1px solid rgba(58, 199, 151, 0.34);
  border-radius: 999px;
  background: rgba(58, 199, 151, 0.12);
  color: #32b98c;
  font-size: 10px;
  font-weight: 800;
}

.stamina-pack-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 9px;
}

.stamina-pack-card {
  position: relative;
  min-width: 0;
  display: grid;
  justify-items: center;
  gap: 4px;
  overflow: hidden;
  padding: 8px 8px 10px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--field);
  text-align: center;
}

.stamina-pack-card.recommended {
  border-color: rgba(157, 116, 255, 0.7);
  box-shadow: inset 0 0 0 1px rgba(157, 116, 255, 0.18), 0 8px 24px rgba(90, 52, 154, 0.1);
}

.stamina-pack-recommendation {
  position: absolute;
  z-index: 2;
  top: 7px;
  left: 7px;
  padding: 4px 6px;
  border-radius: 7px;
  background: #8d66f5;
  color: #fff;
  font-size: 8px;
  font-weight: 800;
}

.stamina-pack-art {
  position: relative;
  width: 100%;
  aspect-ratio: 1.35;
  display: grid;
  place-items: center;
}

.stamina-pack-art > img:first-child {
  width: 88%;
  height: 88%;
  object-fit: contain;
  filter: drop-shadow(0 8px 10px rgba(23, 11, 24, 0.16));
}

.stamina-first-badge {
  position: absolute;
  top: -3px;
  right: -4px;
  width: 43px;
  height: 43px;
  object-fit: contain;
}

.stamina-pack-card h3 {
  margin: 0;
  color: var(--text);
  font-size: 15px;
}

.stamina-pack-card > small {
  min-height: 26px;
  color: var(--muted);
  font-size: 9px;
  line-height: 1.35;
}

.stamina-pack-card .stamina-price {
  width: 100%;
  min-height: 32px;
  display: grid;
  place-items: center;
  margin-top: 3px;
  border: 1px solid rgba(152, 110, 255, 0.28);
  border-radius: 10px;
  background: rgba(137, 94, 236, 0.1);
  color: var(--text);
  font-size: 12px;
  font-weight: 820;
}

.stamina-pack-card .stamina-price:disabled {
  cursor: default;
}

.stamina-pack-card .stamina-price s {
  margin-right: 4px;
  color: var(--muted);
  font-size: 9px;
  font-weight: 500;
}

.stamina-store-status {
  min-height: 17px;
  margin: 0;
  color: var(--muted);
  font-size: 10px;
  text-align: center;
}

.stamina-empty-panel {
  position: relative;
  width: min(348px, 100%);
  overflow: hidden;
  border: 1px solid rgba(166, 126, 255, 0.34);
  border-radius: 26px;
  background: #171421;
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.62);
}

.stamina-empty-panel > img {
  width: 100%;
  height: 265px;
  display: block;
  object-fit: cover;
  object-position: center 28%;
}

.stamina-empty-close {
  position: absolute;
  z-index: 2;
  top: 12px;
  right: 12px;
  width: 34px;
  height: 34px;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 50%;
  background: rgba(11, 9, 17, 0.6);
  color: #fff;
  font-size: 21px;
}

.stamina-empty-copy {
  display: grid;
  gap: 8px;
  padding: 20px;
  color: #f8f6ff;
}

.stamina-empty-copy small {
  color: #b99bff;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.12em;
}

.stamina-empty-copy h2,
.stamina-empty-copy p {
  margin: 0;
}

.stamina-empty-copy h2 {
  font-size: 24px;
}

.stamina-empty-copy p {
  color: rgba(255, 255, 255, 0.66);
  font-size: 12px;
  line-height: 1.65;
}

.stamina-empty-copy button {
  min-height: 44px;
  margin-top: 4px;
  border: 0;
  border-radius: 13px;
  background: linear-gradient(135deg, #8a61f1, #b082ff);
  color: #fff;
  font-weight: 820;
}

.store-intro {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.65;
}

.settings-preferences-head {
  padding-top: 4px;
}

.settings-preferences-head > small {
  max-width: 50%;
  overflow: hidden;
  color: var(--muted);
  font-size: 10px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.settings-logout-btn {
  min-height: 42px;
  border: 1px solid rgba(255, 69, 58, 0.35);
  border-radius: 8px;
  background: transparent;
  color: #ff6961;
  font-weight: 700;
}

.settings-membership-status {
  min-height: 0;
  margin: -5px 0 0;
  color: var(--muted);
  font-size: 11px;
}

.settings-membership-status:empty {
  display: none;
}

.eyebrow {
  color: var(--muted);
  font-size: 12px;
  letter-spacing: 0;
}

.script-badge {
  margin-top: 6px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid rgba(10, 132, 255, 0.35);
  background: rgba(10, 132, 255, 0.12);
  color: #9ecbff;
  font-size: 12px;
  line-height: 1.4;
}

.script-note {
  margin: 0;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.6;
}

.script-upload {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}

.script-upload summary {
  cursor: pointer;
  font-weight: 700;
}

.script-upload > p,
.field-hint,
.script-upload-status {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.55;
}

.script-upload form {
  display: grid;
  gap: 12px;
  margin-top: 14px;
}

.script-upload label {
  display: grid;
  gap: 7px;
}

.script-upload input,
.script-upload select,
.script-upload textarea {
  width: 100%;
}

.script-file input {
  padding: 10px;
  border: 1px dashed var(--line);
}

.script-translation-state {
  display: inline-flex;
  margin-left: 6px;
  color: var(--muted);
}

.script-list {
  display: grid;
  gap: 10px;
  max-height: min(62vh, 520px);
  overflow-y: auto;
  padding-right: 2px;
}

.script-card {
  text-align: left;
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 12px 14px;
  background: var(--field);
  color: var(--text);
  display: grid;
  gap: 6px;
  transition: border-color 0.15s ease, background 0.15s ease;
}

.script-card:hover {
  border-color: rgba(10, 132, 255, 0.55);
}

.script-card.active {
  border-color: rgba(10, 132, 255, 0.85);
  background: rgba(10, 132, 255, 0.14);
  box-shadow: 0 0 0 3px rgba(10, 132, 255, 0.12);
}

.script-card:disabled {
  cursor: not-allowed;
  opacity: 0.48;
}

.script-card .script-card-title {
  font-weight: 700;
  font-size: 15px;
}

.script-card .script-card-desc {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.55;
}

.script-card .script-card-meta {
  color: #7aa8d8;
  font-size: 11px;
}

.script-panel {
  width: min(520px, 100%);
}

.actor-panel {
  width: min(520px, 100%);
  max-height: calc(100dvh - 36px);
  overflow-y: auto;
}

.affection-panel {
  width: min(500px, 100%);
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
}

.contact-detail-modal {
  z-index: 74;
}

.contact-detail-panel {
  position: relative;
  width: min(356px, 100%);
  max-height: calc(100dvh - 28px);
  overflow-x: hidden;
  overflow-y: auto;
  border: 1px solid rgba(107, 202, 242, 0.3);
  border-radius: 24px;
  background:
    radial-gradient(circle at 78% 2%, rgba(108, 211, 255, 0.16), transparent 36%),
    var(--panel-strong);
  box-shadow: 0 28px 90px rgba(0, 0, 0, 0.52);
}

.contact-detail-close {
  position: absolute;
  z-index: 2;
  top: 12px;
  right: 12px;
  border-color: rgba(255, 255, 255, 0.24);
  background: rgba(12, 17, 27, 0.72);
  color: #fff;
  backdrop-filter: blur(10px);
}

.contact-detail-portrait {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-bottom: 1px solid var(--line);
  background-color: #121824;
  background-repeat: no-repeat;
}

.contact-detail-copy {
  display: grid;
  gap: 7px;
  padding: 18px 20px 20px;
}

.contact-detail-copy > span {
  color: #6bcaf2;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.contact-detail-copy h2 {
  font-size: 28px;
}

.contact-detail-copy > p {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.55;
}

.contact-detail-affection {
  display: grid;
  gap: 9px;
  margin-top: 7px;
  padding: 13px 14px;
  border: 1px solid rgba(216, 117, 148, 0.22);
  border-radius: 14px;
  background: rgba(216, 117, 148, 0.07);
}

.contact-detail-affection > div:first-child {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.contact-detail-affection span {
  color: var(--muted);
  font-size: 12px;
}

.contact-detail-affection strong {
  color: #f2a8bd;
  font-size: 14px;
}

.contact-detail-copy .contact-detail-hint {
  margin-top: 2px;
  padding: 0 2px;
  font-size: 11px;
}

@media (max-height: 620px) {
  .contact-detail-panel {
    width: min(330px, 100%);
  }

  .contact-detail-portrait {
    max-height: 48dvh;
  }
}

/* ══ CO0263 背包面板 ═══════════════════════════════════════════════════════ */
.backpack-panel {
  position: relative;
  width: min(356px, 100%);
  max-height: calc(100dvh - 28px);
  overflow-x: hidden;
  overflow-y: auto;
  padding: 18px 18px 20px;
  border: 1px solid rgba(107, 202, 242, 0.3);
  border-radius: 24px;
  background:
    radial-gradient(circle at 78% 2%, rgba(108, 211, 255, 0.12), transparent 36%),
    var(--panel-strong);
  box-shadow: 0 28px 90px rgba(0, 0, 0, 0.52);
}

.backpack-close {
  position: absolute;
  z-index: 2;
  top: 12px;
  right: 12px;
  border-color: rgba(255, 255, 255, 0.24);
  background: rgba(12, 17, 27, 0.72);
  color: #fff;
  backdrop-filter: blur(10px);
}

.backpack-head {
  display: grid;
  gap: 4px;
  margin-bottom: 14px;
}

.backpack-head .eyebrow {
  color: #6bcaf2;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.backpack-head h2 {
  margin: 0;
  font-size: 22px;
}

.backpack-list {
  display: grid;
  gap: 10px;
}

.backpack-item {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  padding: 12px 13px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.03);
}

.backpack-item.is-locked {
  opacity: 0.62;
}

.backpack-item-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border: 1px solid rgba(116, 183, 255, 0.3);
  border-radius: 13px;
  background: rgba(72, 132, 212, 0.12);
  color: #9fd4ff;
}

.backpack-item-icon svg {
  width: 22px;
  height: 22px;
}

.backpack-item-text {
  flex: 1 1 auto;
  display: grid;
  gap: 3px;
  min-width: 0;
}

.backpack-item-text strong {
  font-size: 13px;
}

.backpack-item-text small {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.5;
}

.backpack-item-text .backpack-item-count {
  color: #9fd4ff;
  font-weight: 700;
}

.backpack-item-use {
  flex: 0 0 auto;
  min-height: 36px;
  padding: 7px 11px;
  border: 1px solid rgba(159, 212, 255, 0.36);
  border-radius: 11px;
  background: linear-gradient(145deg, #638ed8, #7765d8);
  color: #fff;
  font: inherit;
  font-size: 12px;
  font-weight: 800;
  cursor: pointer;
}

.backpack-item-use:disabled {
  cursor: not-allowed;
  border-color: var(--line);
  background: rgba(255, 255, 255, 0.06);
  color: var(--muted);
}

.backpack-status {
  padding: 14px 4px;
  color: var(--muted);
  font-size: 12px;
  text-align: center;
}

.backpack-status button {
  margin-top: 10px;
  min-height: 34px;
  padding: 6px 14px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--field);
  color: var(--text);
  font: inherit;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}

.affection-note {
  margin: -2px 0 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.6;
}

.affection-list {
  display: grid;
  gap: 10px;
}

.affection-control {
  display: grid;
  gap: 11px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--field);
}

.affection-control-head {
  display: grid;
  grid-template-columns: 38px 1fr auto;
  align-items: center;
  gap: 10px;
}

.affection-control-head img {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  object-fit: cover;
  object-position: 50% 18%;
}

.affection-control-head span {
  display: grid;
  gap: 2px;
}

.affection-control-head strong { font-size: 14px; }
.affection-control-head small { color: var(--muted); font-size: 10px; }

.affection-control-head output {
  min-width: 42px;
  color: #f2a8bd;
  font-size: 18px;
  font-weight: 750;
  text-align: right;
}

.affection-slider {
  width: 100%;
  accent-color: #e78eaa;
}

.affection-stepper {
  display: grid;
  grid-template-columns: 44px 44px minmax(58px, 1fr) 44px 44px;
  gap: 6px;
}

.affection-stepper button,
.affection-stepper input {
  min-width: 0;
  height: 34px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.05);
  color: var(--text);
  text-align: center;
}

.affection-stepper button { padding: 0; }
.affection-stepper input { width: 100%; padding: 0 5px; }

.affection-history-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding-top: 4px;
  border-top: 1px solid var(--line);
}

.affection-history-head strong { font-size: 13px; }
.affection-history-head small { color: var(--muted); font-size: 10px; }

.affection-log {
  display: grid;
}

.affection-log-empty {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
}

.affection-log-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 3px 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--line);
}

.affection-log-row > span { display: flex; align-items: baseline; gap: 7px; }
.affection-log-row strong { font-size: 12px; }
.affection-log-row small { color: var(--muted); font-size: 9px; }
.affection-log-row em { font-size: 13px; font-style: normal; font-weight: 750; }
.affection-log-row em.positive { color: #74d69a; }
.affection-log-row em.negative { color: #ff8c8c; }
.affection-log-row p {
  grid-column: 1 / -1;
  margin: 0;
  color: #aeb6c2;
  font-size: 10px;
  line-height: 1.45;
}

.person-panel,
.scene-panel {
  width: min(400px, 100%);
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
}

.switch-note {
  margin: -2px 0 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.6;
}

.person-list,
.scene-list {
  display: grid;
  gap: 9px;
}

.person-option,
.scene-option {
  width: 100%;
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center;
  gap: 11px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--field);
  color: var(--text);
  text-align: left;
}

.person-option.current,
.scene-option.current {
  border-color: rgba(100, 210, 255, 0.62);
  background: rgba(100, 210, 255, 0.08);
}

.scene-option.locked,
.scene-option:disabled {
  cursor: not-allowed;
  opacity: 0.46;
  filter: grayscale(0.72);
}

.scene-option.locked em {
  color: var(--muted);
}

.person-option-avatar {
  --affection-angle: 0deg;
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  padding: 3px;
  border-radius: 50%;
  background: conic-gradient(#64d2ff var(--affection-angle), rgba(255, 255, 255, 0.13) 0);
}

.person-option-avatar i {
  width: 100%;
  height: 100%;
  display: block;
  border: 2px solid #151a23;
  border-radius: 50%;
  background-position: 50% 18%;
  background-size: cover;
}

.person-option > span:nth-child(2),
.scene-option > span {
  min-width: 0;
  display: grid;
  gap: 4px;
}

.person-option strong,
.scene-option strong {
  font-size: 14px;
}

.person-option small,
.scene-option small {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.4;
}

.person-option em,
.scene-option em {
  color: #8edcea;
  font-size: 11px;
  font-style: normal;
}

.scene-option > i {
  width: 42px;
  height: 42px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(100, 210, 255, 0.28);
  border-radius: 50%;
  overflow: hidden;
  background-color: rgba(100, 210, 255, 0.08);
  background-position: center;
  background-size: cover;
  color: #aee7f2;
  font-family: ui-serif, "Songti SC", "STSong", serif;
  font-style: normal;
}

.scene-option > i b {
  width: 100%;
  height: 100%;
  display: grid;
  place-items: center;
  border-radius: inherit;
  background: rgba(6, 10, 16, 0.42);
  font-weight: 600;
}

.actor-readonly {
  margin: -2px 0 0;
  padding: 10px 12px;
  border-left: 3px solid #64d2ff;
  border-radius: 8px;
  background: rgba(100, 210, 255, 0.08);
  color: #c6eaff;
  font-size: 12px;
  line-height: 1.55;
}

.actor-list {
  display: grid;
  gap: 10px;
}

.actor-row {
  display: grid;
  grid-template-columns: 58px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--field);
}

.actor-row.selected {
  border-color: rgba(100, 210, 255, 0.62);
  background: rgba(100, 210, 255, 0.08);
}

.actor-row > img {
  width: 58px;
  height: 72px;
  object-fit: cover;
  object-position: 50% 18%;
  border-radius: 10px;
  background: #11151e;
}

.actor-info {
  min-width: 0;
}

.actor-name {
  display: flex;
  align-items: baseline;
  gap: 7px;
  min-width: 0;
}

.actor-name strong {
  font-size: 15px;
}

.actor-name span,
.actor-name em {
  color: var(--muted);
  font-size: 10px;
  font-style: normal;
}

.actor-name em {
  margin-left: auto;
  color: #64d2ff;
}

.actor-info p,
.actor-info small {
  display: block;
  margin: 4px 0 0;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.4;
}

.actor-info small {
  color: #b7b9c2;
}

.actor-row > button {
  min-width: 58px;
  padding: 8px 9px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.06);
  color: var(--text);
  font-size: 11px;
}

.actor-row > button[aria-pressed="true"] {
  border-color: #64d2ff;
  background: #64d2ff;
  color: #071017;
  font-weight: 700;
}

.save-panel {
  width: min(560px, 100%);
  max-height: calc(100dvh - 36px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.save-note {
  margin: -2px 0 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.6;
}

.save-slots {
  border-top: 1px solid var(--line);
}

.save-slot {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px;
  padding: 15px 0;
  border-bottom: 1px solid var(--line);
}

.save-slot-info {
  min-width: 0;
}

.save-slot-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.save-slot-heading strong {
  font-size: 14px;
}

.save-slot-heading time,
.save-slot-meta {
  color: var(--muted);
  font-size: 11px;
}

.save-slot-meta {
  margin-top: 5px;
  color: #7fb7c2;
}

.save-slot-info p {
  overflow: hidden;
  margin: 7px 0 0;
  color: #c2c7d0;
  font-size: 12px;
  line-height: 1.45;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.save-slot-actions {
  display: flex;
  align-items: center;
  gap: 6px;
}

.save-slot-actions button {
  min-height: 34px;
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--field);
  color: var(--text);
  font-size: 12px;
}

.save-slot-actions .load-save {
  border-color: rgba(10, 132, 255, 0.45);
  color: #8fc7ff;
}

.save-slot-actions .delete-save {
  color: #ff9c9c;
}

h1,
h2 {
  margin: 0;
  font-size: 20px;
  letter-spacing: 0;
}

.top-actions {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.topbar-title {
  min-width: 0;
}

.topbar-title h1 {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.character-trigger,
.scene-trigger {
  width: 38px;
  height: 38px;
  flex: 0 0 38px;
  padding: 3px;
  overflow: hidden;
  border: 0;
  border-radius: 50%;
  background: conic-gradient(#64d2ff var(--affection-angle, 0deg), rgba(255, 255, 255, 0.13) 0);
  box-shadow: 0 0 0 3px rgba(10, 132, 255, 0.1);
}

.scene-trigger {
  display: grid;
  place-items: center;
  border: 1px solid rgba(118, 175, 215, 0.7);
  background: #111722;
  color: #aee7f2;
  font-family: ui-serif, "Songti SC", "STSong", serif;
  font-size: 15px;
  font-weight: 700;
}

.character-trigger .avatar-photo,
.avatar .avatar-photo {
  width: 100%;
  height: 100%;
  display: block;
  border-radius: inherit;
}

.character-trigger .avatar-photo {
  border: 2px solid #111722;
}

.avatar-photo.text-avatar {
  display: grid;
  place-items: center;
  background: linear-gradient(145deg, #263b52, #152231);
  color: #bdebf1;
  font-size: 12px;
  font-weight: 800;
}

.character-trigger.multi-character {
  width: 76px;
  flex-basis: 76px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3px 7px;
  overflow: visible;
  border-radius: 20px;
  background: rgba(17, 23, 34, 0.92);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1), 0 0 0 3px rgba(10, 132, 255, 0.08);
}

.character-trigger.multi-character .script-cast-photo {
  width: 30px;
  height: 30px;
  flex: 0 0 30px;
  background-size: cover;
  background-position: 50% 18%;
}

.character-trigger.multi-character .script-cast-photo + .script-cast-photo {
  margin-left: -9px;
}

.profile-avatar-trigger {
  padding: 0;
  border: 0;
  cursor: pointer;
}

.profile-avatar-trigger:focus-visible {
  outline: 2px solid #64d2ff;
  outline-offset: 2px;
}

.avatar-photo,
.character-portrait-photo,
.avatar-preview,
.avatar-preset-photo {
  background-position: center;
  background-repeat: no-repeat;
}

.more-btn {
  width: 38px;
  height: 38px;
  padding: 0 0 5px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--field);
  color: var(--text);
  font-size: 16px;
  letter-spacing: 2px;
}

.more-menu {
  position: absolute;
  z-index: 20;
  top: 46px;
  right: 0;
  width: min(316px, calc(100vw - 28px));
  max-height: calc(100dvh - 76px);
  display: none;
  overflow-x: hidden;
  overflow-y: auto;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: rgba(27, 31, 40, 0.98);
  box-shadow: 0 18px 55px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(24px);
}

.more-menu.show {
  display: grid;
}

.more-menu-group {
  padding: 10px 10px 5px;
  color: var(--muted);
  font-size: 10px;
  font-weight: 750;
  letter-spacing: 0.08em;
}

.more-menu-group:not(:first-child) {
  margin-top: 4px;
  border-top: 1px solid var(--line);
}

.more-menu-group.danger-label {
  color: #d78383;
}

.more-menu button {
  display: grid;
  grid-template-columns: minmax(92px, auto) minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 10px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--text);
  text-align: left;
}

.more-menu button > span {
  white-space: nowrap;
}

.more-menu button:disabled {
  cursor: default;
  opacity: 0.64;
}

.more-menu button:hover {
  background: rgba(255, 255, 255, 0.06);
}

.more-menu button.danger span {
  color: #ff9c9c;
}

.more-menu small {
  min-width: 0;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.35;
  text-align: right;
  overflow-wrap: anywhere;
}

.ghost-btn,
.icon-btn {
  border: 1px solid var(--line);
  color: var(--text);
  background: var(--field);
  border-radius: 12px;
}

.ghost-btn {
  min-width: 58px;
  padding: 8px 12px;
}

.ghost-btn.danger {
  color: #ffd4d4;
}

.icon-btn {
  width: 34px;
  height: 34px;
  font-size: 22px;
  line-height: 1;
}

.messages {
  position: relative;
  z-index: 1;
  height: 100%;
  overflow-y: auto;
  overflow-anchor: none;
  padding: 28px 24px 86px;
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.empty {
  margin: auto;
  max-width: 360px;
  color: var(--muted);
  text-align: center;
  line-height: 1.7;
}

.opening-state {
  position: relative;
  width: 100%;
  min-height: min(620px, calc(var(--viewport-height, 100dvh) - 190px));
  margin: auto 0;
  overflow: hidden;
  border-radius: 6px;
  background-color: #151a21;
  background-position: center;
  background-size: cover;
  isolation: isolate;
}

.opening-state::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 0;
  background: linear-gradient(180deg, rgba(6, 9, 13, 0.08) 10%, rgba(6, 9, 13, 0.32) 52%, rgba(6, 9, 13, 0.94) 100%);
}

.opening-state-shade {
  position: absolute;
  inset: auto 0 0;
  display: grid;
  justify-items: start;
  gap: 8px;
  padding: 34px 26px 28px;
  color: #f7f8fa;
  text-align: left;
}

.opening-state-eyebrow {
  color: rgba(255, 255, 255, 0.68);
  font-size: 10px;
  font-weight: 700;
}

.opening-state h2 {
  margin: 0;
  font-size: 25px;
  line-height: 1.25;
}

.opening-state-scene {
  margin: 0;
  color: rgba(255, 255, 255, 0.76);
  font-size: 12px;
}

.opening-state-role {
  margin: 7px 0 10px;
  color: rgba(255, 255, 255, 0.9);
  font-size: 14px;
  line-height: 1.6;
}

.opening-state-enter {
  width: 100%;
  min-height: 46px;
  border: 0;
  border-radius: 7px;
  background: #ffffff;
  color: #11151b;
  font-size: 14px;
  font-weight: 800;
}

.opening-state-enter:active {
  transform: scale(0.99);
}

:root[data-theme="wechat"] .opening-state-enter {
  background: #07c160;
  color: #ffffff;
}

@media (max-width: 560px) {
  .opening-state {
    min-height: calc(var(--viewport-height, 100dvh) - 184px);
    border-radius: 0;
  }
}

.story-turn {
  display: flex;
  flex-direction: column;
  gap: 17px;
  align-items: flex-start;
  width: 100%;
}

.story-turn.streaming {
  min-height: 52px;
}

.story-thinking-bubble {
  color: #aab2be;
  animation: story-thinking-pulse 1.2s ease-in-out infinite;
}

@keyframes story-thinking-pulse {
  0%, 100% { opacity: 0.48; }
  50% { opacity: 1; }
}

.dev-locale-preview-banner {
  position: fixed;
  top: max(8px, env(safe-area-inset-top));
  left: 50%;
  z-index: 2147483000;
  max-width: calc(100vw - 24px);
  transform: translateX(-50%);
  padding: 7px 12px;
  border: 1px solid rgba(255, 210, 92, .55);
  border-radius: 999px;
  background: rgba(32, 25, 8, .94);
  box-shadow: 0 8px 28px rgba(0, 0, 0, .32);
  color: #ffe39a;
  font: 700 12px/1.35 system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  letter-spacing: .02em;
  text-align: center;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .story-thinking-bubble {
    animation: none;
  }
}

.story-narration {
  width: min(100%, 640px);
  margin: 2px auto;
  padding: 12px 16px;
  border: 1px solid rgba(255, 255, 255, 0.085);
  border-left-color: rgba(120, 198, 211, 0.46);
  border-radius: 8px;
  background: rgba(35, 41, 53, 0.68);
  color: #aab2be;
  backdrop-filter: blur(8px);
  font-family: ui-serif, "Songti SC", "STSong", serif;
  font-size: 14px;
  line-height: 1.9;
  white-space: pre-wrap;
  word-break: break-word;
}

.story-narration.live::after {
  content: '';
  display: inline-block;
  width: 2px;
  height: 1.05em;
  margin-left: 3px;
  border-radius: 1px;
  background: #78c6d3;
  vertical-align: -0.12em;
  animation: narration-caret 0.8s steps(1, end) infinite;
}

@keyframes narration-caret {
  0%, 48% { opacity: 0.9; }
  49%, 100% { opacity: 0; }
}

.message-row {
  display: flex;
  align-items: flex-end;
  gap: 10px;
}

.message-row.user {
  justify-content: flex-end;
}

.chat-time {
  display: none;
}

.user-avatar {
  width: 34px;
  height: 34px;
  display: block;
  flex: 0 0 34px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 50%;
  background-color: #146de0;
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
}

.user-avatar.text-avatar {
  display: grid;
  place-items: center;
  color: #ffffff;
  font-size: 14px;
  font-weight: 750;
}

.dialogue-row {
  width: 100%;
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

/* CO0253：甲方「这个头像太小了，布局太不合理。调整成适配脸大小」。
   34px 的圆头像在 430px 画布上只占 8% 宽，角色的脸在里面基本看不清 ——
   而这个项目卖的就是角色，头像是玩家每一轮都在看的东西。放大到 46px（主流聊天 App 量级）。
   ⚠️ margin-top 必须跟着改：它的作用是让头像与气泡内**第一行文字**对齐，
   原来的 21px 是按 34px 配的；只放大不调这里，头像会明显掉到第一行下面。 */
.dialogue-row > .avatar {
  margin-top: 15px;
}

.avatar {
  width: 46px;
  height: 46px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  background: linear-gradient(135deg, #5ac8fa, #0a84ff);
  color: white;
  font-weight: 700;
  overflow: hidden;
}

.bubble {
  max-width: min(78%, 580px);
  padding: 12px 15px;
  border-radius: 20px;
  background: var(--assistant);
  border: 1px solid rgba(255, 255, 255, 0.06);
  line-height: 1.85;
  white-space: pre-wrap;
  word-break: break-word;
  letter-spacing: 0.01em;
}

.dialogue-content {
  max-width: min(76%, 560px);
}

.speaker-name {
  margin: 0 0 5px 4px;
  color: #8dbfca;
  font-size: 11px;
  font-weight: 650;
}

.dialogue-bubble {
  max-width: none;
  padding: 11px 14px;
  background: #202633;
  color: #f2f4f7;
  font-size: 15px;
  line-height: 1.8;
  border-bottom-left-radius: 7px;
}

.message-row.user .bubble {
  border: 0;
  border-bottom-right-radius: 7px;
  background: linear-gradient(135deg, #2d9cff, var(--user));
}

.system-strip {
  width: min(100%, 640px);
  margin: 0 auto;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 12px;
  padding: 11px 14px;
  border: 1px solid rgba(93, 177, 194, 0.22);
  border-left: 3px solid #5db1c2;
  border-radius: 8px;
  background: rgba(68, 110, 123, 0.1);
  color: #c5ccd5;
  font-size: 13px;
  line-height: 1.6;
  white-space: pre-wrap;
}

.system-strip strong {
  color: #78c6d3;
  white-space: nowrap;
}

.story-choices {
  width: min(100%, 640px);
  margin: 2px auto 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.story-choices button {
  min-height: 46px;
  display: grid;
  grid-template-columns: 24px 1fr;
  align-items: center;
  gap: 8px;
  padding: 9px 12px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.045);
  color: #e7eaf0;
  text-align: left;
  line-height: 1.45;
}

.story-choices button:hover {
  border-color: rgba(82, 169, 255, 0.55);
  background: rgba(10, 132, 255, 0.1);
}

.story-choices button span {
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(10, 132, 255, 0.15);
  color: #8fc7ff;
  font-size: 11px;
  font-weight: 750;
}

.composer {
  display: grid;
  /* CO0263：三列 = 「+」 / 输入框 / 发送。minmax(0,1fr) 防止长文本把中列撑出横向溢出。 */
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 10px;
  padding: 12px 14px calc(12px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
  background: rgba(16, 18, 25, 0.92);
}

/* ══ CO0263 输入框左侧 + 与功能托盘 ═══════════════════════════════════════
   选择器全部带 id：主题皮肤（wechat/cinema/campus）对 `.composer button` 的覆写
   特异度是 (0,3,1)，纯 class 会被它们抢走背景色；id 起步 (1,0,0)，稳赢。 */
.composer #composerPlusBtn {
  min-width: 46px;
  width: 46px;
  height: 46px;
  min-height: 46px;
  padding: 0;
  align-self: end; /* 输入框多行展开时保持底部对齐 */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--field);
  color: var(--text);
}

.composer #composerPlusBtn svg {
  width: 20px;
  height: 20px;
  transition: transform 160ms ease;
}

.composer #composerPlusBtn[aria-expanded="true"] svg {
  transform: rotate(45deg); /* + → ×，收起入口不用换图标 */
}

.composer #composerTray {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap; /* 后续图标变多时换行，不横向溢出 */
  gap: 10px;
  padding-bottom: 2px;
}

.composer #composerTray[hidden] {
  display: none;
}

.composer #composerTray button {
  min-width: 0;
  min-height: 0;
  height: auto;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 8px 12px 6px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--field);
  color: var(--text);
  font-size: 11px;
  font-weight: 600;
}

.composer #composerTray button svg {
  width: 22px;
  height: 22px;
}

.composer textarea {
  width: 100%;
  min-height: 46px;
  max-height: 132px;
  resize: none;
  border: 1px solid var(--line);
  outline: none;
  border-radius: 18px;
  padding: 12px 14px;
  background: var(--field);
  color: var(--text);
  font-size: 16px;
}

.composer textarea:focus,
.profile-panel input:focus,
.profile-panel textarea:focus,
.profile-panel select:focus {
  border-color: rgba(10, 132, 255, 0.75);
  box-shadow: 0 0 0 4px rgba(10, 132, 255, 0.12);
}

.composer.continue-mode textarea {
  cursor: text;
  text-align: left;
  font-weight: 400;
  animation: continue-nudge 3.2s ease-in-out infinite;
}

.composer.continue-mode textarea[data-continue-default="true"] {
  color: rgba(211, 225, 247, 0.78);
}

.composer.continue-mode textarea:hover,
.composer.continue-mode textarea:focus {
  border-color: rgba(100, 210, 255, 0.68);
  box-shadow: 0 0 0 4px rgba(100, 210, 255, 0.1);
}

.composer.continue-mode textarea:focus {
  text-align: left;
  font-weight: 400;
  animation: none;
}

@keyframes continue-nudge {
  0%, 8%, 16%, 100% { transform: translateX(0); }
  4% { transform: translateX(2px); }
  12% { transform: translateX(-2px); }
}

@media (prefers-reduced-motion: reduce) {
  .composer.continue-mode textarea { animation: none; }
  .composer.continue-mode #sendBtn:not(.stop)::before,
  .composer.continue-mode #sendBtn:not(.stop)::after { animation: none; }
}

.composer button,
.primary-wide {
  border: 0;
  border-radius: 16px;
  background: var(--user);
  color: #fff;
  font-weight: 700;
}

.composer button {
  min-width: 70px;
  min-height: 46px;
  padding: 0 16px;
  position: relative;
  isolation: isolate;
}

.composer button.stop {
  background: #ff453a;
}

.composer.continue-mode #sendBtn:not(.stop) {
  box-shadow: 0 0 12px rgba(255, 83, 171, 0.18);
}

.composer.continue-mode #sendBtn:not(.stop)::before,
.composer.continue-mode #sendBtn:not(.stop)::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  pointer-events: none;
  background: #fff4fb;
  box-shadow:
    0 0 4px 2px rgba(255, 255, 255, 0.82),
    0 0 10px 4px rgba(255, 79, 163, 0.7);
  offset-path: inset(-5px round 19px);
  offset-distance: 0%;
  animation: intimate-send-orbit 2.2s linear infinite;
}

.composer.continue-mode #sendBtn:not(.stop)::after {
  width: 4px;
  height: 4px;
  z-index: 1;
  opacity: 0.68;
  animation-delay: -1.1s;
}

@keyframes intimate-send-orbit {
  to { offset-distance: 100%; }
}

.modal {
  position: fixed;
  inset: 0 auto 0 50%;
  z-index: 50;
  width: min(var(--app-width), 100%);
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px;
  background: rgba(0, 0, 0, 0.54);
  backdrop-filter: blur(16px);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 180ms ease,
    visibility 0s linear 200ms;
}

.modal > [role="dialog"] {
  opacity: 0;
  transform: translateY(12px) scale(0.985);
  transition:
    opacity 180ms ease,
    transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
}

.modal.show {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition-delay: 0s;
}

.modal.show > [role="dialog"] {
  opacity: 1;
  transform: translateY(0) scale(1);
}

@media (prefers-reduced-motion: reduce) {
  .modal,
  .modal > [role="dialog"] {
    transition-duration: 1ms;
  }
}

/* 系统内确认层（替代浏览器原生 confirm 弹窗） */
.app-confirm-modal {
  z-index: 80;
}

.app-confirm-panel {
  width: min(322px, 100%);
  padding: 22px 20px 18px;
  border: 1px solid rgba(146, 111, 255, 0.28);
  border-radius: 20px;
  background: #1b1930;
  box-shadow: 0 28px 80px rgba(0, 0, 0, 0.55);
  text-align: left;
}

.app-confirm-title {
  display: block;
  color: #fff;
  font-size: 16px;
  font-weight: 700;
}

.app-confirm-body {
  margin: 10px 0 18px;
  color: rgba(255, 255, 255, 0.66);
  font-size: 12px;
  line-height: 1.62;
  white-space: pre-line;
}

.app-confirm-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.app-confirm-btn {
  min-height: 44px;
  border: 0;
  border-radius: 13px;
  font-size: 13px;
  font-weight: 700;
}

.app-confirm-cancel {
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.8);
}

.app-confirm-ok {
  background: #8b6cff;
  color: #fff;
  box-shadow: 0 8px 22px rgba(122, 83, 255, 0.34);
}

.onboarding-modal {
  z-index: 60;
  padding:
    max(20px, env(safe-area-inset-top))
    20px
    max(20px, env(safe-area-inset-bottom));
  background:
    radial-gradient(circle at 50% 26%, rgba(139, 108, 255, 0.18), transparent 42%),
    rgba(5, 5, 10, 0.88);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}

.onboarding-panel {
  position: relative;
  isolation: isolate;
  width: min(380px, 100%);
  display: grid;
  justify-items: center;
  gap: 11px;
  overflow: hidden;
  padding: 30px 22px 24px;
  border: 1px solid rgba(139, 108, 255, 0.42);
  border-radius: 28px;
  background:
    linear-gradient(155deg, rgba(30, 24, 50, 0.97), rgba(11, 13, 18, 0.98));
  box-shadow:
    0 32px 100px rgba(0, 0, 0, 0.64),
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    0 0 44px rgba(139, 108, 255, 0.12);
  text-align: center;
}

.onboarding-modal.show .onboarding-panel {
  animation: onboardingPanelEnter 480ms cubic-bezier(0.2, 0.85, 0.2, 1) both;
}

.onboarding-panel::before {
  position: absolute;
  z-index: -1;
  top: -120px;
  left: 50%;
  width: 280px;
  height: 220px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(139, 108, 255, 0.22), transparent 68%);
  content: "";
  opacity: 0.7;
  pointer-events: none;
  transform: translateX(-50%);
  animation: onboardingAura 4s ease-in-out infinite;
}

.onboarding-mark {
  width: 58px;
  height: 58px;
  display: grid;
  place-items: center;
  margin-bottom: 4px;
  border: 1px solid rgba(212, 178, 90, 0.48);
  border-radius: 50%;
  background:
    radial-gradient(circle at 45% 35%, rgba(139, 108, 255, 0.32), rgba(17, 14, 28, 0.92));
  color: #eee8ff;
  box-shadow:
    inset 0 0 18px rgba(139, 108, 255, 0.2),
    0 0 28px rgba(139, 108, 255, 0.2);
}

.onboarding-mark svg {
  width: 34px;
  height: 34px;
  filter: drop-shadow(0 0 8px rgba(139, 108, 255, 0.54));
}

.onboarding-panel .eyebrow {
  color: #d4b25a;
  font-size: 10px;
  font-weight: 760;
  letter-spacing: 0.16em;
}

.onboarding-panel h2 {
  margin: 0;
  color: #fff;
  font-size: 25px;
  letter-spacing: -0.025em;
}

.onboarding-panel > p {
  max-width: 300px;
  margin: 0 0 7px;
  color: rgba(228, 224, 239, 0.64);
  font-size: 13px;
  line-height: 1.65;
}

.gender-options {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.gender-options button {
  position: relative;
  min-height: 76px;
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  overflow: hidden;
  padding: 10px 12px;
  border: 1px solid rgba(139, 108, 255, 0.24);
  border-radius: 16px;
  background:
    linear-gradient(145deg, rgba(255, 255, 255, 0.055), rgba(139, 108, 255, 0.035));
  color: rgba(245, 243, 251, 0.86);
  text-align: left;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
  -webkit-tap-highlight-color: transparent;
  transition:
    transform 220ms cubic-bezier(0.2, 0.85, 0.2, 1),
    border-color 180ms ease,
    background 180ms ease,
    color 180ms ease,
    box-shadow 180ms ease;
}

.gender-options button:focus:not(:focus-visible) {
  outline: none;
}

.gender-options button:focus-visible {
  outline: 2px solid #8b6cff;
  outline-offset: 3px;
}

.gender-options button[aria-pressed="true"],
.gender-options button.is-selected {
  border-color: rgba(164, 135, 255, 0.94);
  background:
    linear-gradient(145deg, rgba(139, 108, 255, 0.28), rgba(77, 49, 134, 0.16));
  color: #fff;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.12),
    0 10px 26px rgba(81, 47, 160, 0.25),
    0 0 22px rgba(139, 108, 255, 0.16);
  transform: translateY(-2px);
}

.gender-options i {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(139, 108, 255, 0.24);
  border-radius: 12px;
  background: rgba(7, 8, 13, 0.42);
  color: #c8bbff;
  font-style: normal;
  transition:
    border-color 180ms ease,
    background 180ms ease,
    color 180ms ease,
    box-shadow 180ms ease;
}

.gender-options i svg {
  width: 26px;
  height: 26px;
}

.gender-options button[aria-pressed="true"] i,
.gender-options button.is-selected i {
  border-color: rgba(212, 178, 90, 0.56);
  background: rgba(139, 108, 255, 0.2);
  color: #f0dc9a;
  box-shadow: 0 0 16px rgba(139, 108, 255, 0.22);
}

.gender-options span {
  min-width: 0;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.3;
}

.onboarding-panel > small {
  margin-top: 4px;
  color: rgba(202, 196, 217, 0.5);
  font-size: 11px;
}

@media (hover: hover) {
  .gender-options button:hover {
    border-color: rgba(139, 108, 255, 0.64);
    background:
      linear-gradient(145deg, rgba(139, 108, 255, 0.16), rgba(77, 49, 134, 0.08));
    color: #fff;
    box-shadow: 0 8px 22px rgba(61, 36, 118, 0.18);
    transform: translateY(-2px);
  }
}

@media (max-width: 360px) {
  .onboarding-panel {
    padding-inline: 16px;
  }

  .gender-options {
    gap: 8px;
  }

  .gender-options button {
    grid-template-columns: 36px minmax(0, 1fr);
    gap: 7px;
    padding-inline: 9px;
  }

  .gender-options i {
    width: 34px;
    height: 34px;
  }
}

@keyframes onboardingPanelEnter {
  from {
    opacity: 0;
    transform: translateY(18px) scale(0.975);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@keyframes onboardingAura {
  0%,
  100% {
    opacity: 0.54;
    transform: translateX(-50%) scale(0.96);
  }
  50% {
    opacity: 0.86;
    transform: translateX(-50%) scale(1.04);
  }
}

@media (prefers-reduced-motion: reduce) {
  .onboarding-modal.show .onboarding-panel,
  .onboarding-panel::before {
    animation: none;
  }

  .gender-options button,
  .gender-options i {
    transition-duration: 1ms;
  }
}

.character-modal {
  overflow-y: auto;
  padding: max(14px, env(safe-area-inset-top)) 14px max(14px, env(safe-area-inset-bottom));
}

.character-sheet {
  width: min(430px, 100%);
  max-height: calc(100dvh - 28px);
  overflow-y: auto;
  border: 1px solid rgba(111, 151, 183, 0.4);
  border-radius: 22px;
  background: #121722;
  box-shadow: 0 28px 90px rgba(0, 0, 0, 0.58);
}

.script-actor-sheet {
  width: min(430px, 100%);
}

.script-actor-visual {
  min-height: 270px;
}

.script-actor-visual img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: 50% 16%;
}

.script-actor-badges {
  position: absolute;
  top: 14px;
  left: 14px;
  display: flex;
  gap: 7px;
}

.script-actor-badges span {
  padding: 5px 9px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 7px;
  background: rgba(9, 14, 21, 0.78);
  color: #e9f7ff;
  font-size: 12px;
  backdrop-filter: blur(10px);
}

.script-actor-badges span:last-child { color: #f1c45d; }

.script-actor-info {
  padding: 18px 20px 22px;
}

.script-actor-identity h2 {
  margin: 2px 0 3px;
  color: #ffffff;
  font-size: 30px;
}

.script-actor-identity p {
  margin: 0;
  color: #c6ccd5;
  font-size: 13px;
}

#scriptActorSource {
  color: #8fcfd8;
  font-size: 11px;
  font-weight: 700;
}

.script-actor-facts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin: 0;
  padding: 13px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.script-actor-facts div {
  min-width: 0;
  padding: 0 10px;
  border-right: 1px solid rgba(255, 255, 255, 0.1);
}

.script-actor-facts div:first-child { padding-left: 0; }
.script-actor-facts div:last-child { padding-right: 0; border-right: 0; }

.script-actor-facts dt {
  margin-bottom: 4px;
  color: var(--muted);
  font-size: 11px;
}

.script-actor-facts dd {
  margin: 0;
  color: #eef3f8;
  font-size: 12px;
  line-height: 1.45;
  overflow-wrap: anywhere;
}

.script-actor-detail { margin-top: 16px; }

.script-actor-detail h3 {
  margin: 0 0 6px;
  color: #83d1d7;
  font-size: 12px;
  font-weight: 700;
}

.script-actor-detail p {
  color: #e7edf4;
  font-size: 13px;
  line-height: 1.65;
}

.script-avatar-edit-btn {
  margin-top: 18px;
  border-color: rgba(100, 210, 255, 0.42);
  color: #bcefff;
}

.script-avatar-note {
  margin: 7px 4px 0;
  color: var(--muted);
  font-size: 10px;
  line-height: 1.5;
  text-align: center;
}

.personality-panel {
  margin-top: 16px;
  padding: 14px;
  border: 1px solid rgba(129, 208, 215, 0.2);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.035);
}

.personality-panel-head {
  display: flex;
  align-items: start;
  justify-content: space-between;
  gap: 12px;
}

.personality-panel-head small { color: #83d1d7; font-size: 9px; font-weight: 800; }
.personality-panel-head h3 { margin: 3px 0 0; color: #f1f5f8; font-size: 15px; }
.personality-panel-head em { color: #f2a8bd; font-size: 10px; font-style: normal; font-weight: 700; }
.personality-summary,
.personality-privacy { margin: 10px 0 0; color: #b8c1cc; font-size: 11px; line-height: 1.6; }
.personality-dimensions { display: grid; grid-template-columns: 1fr 1fr; gap: 9px 12px; margin-top: 13px; }
.personality-dimension > div { display: flex; justify-content: space-between; color: #cbd4dd; font-size: 10px; }
.personality-dimension i { display: block; height: 4px; margin-top: 5px; overflow: hidden; border-radius: 4px; background: rgba(255, 255, 255, 0.08); }
.personality-dimension b { display: block; height: 100%; border-radius: inherit; background: #70cad2; }
.personality-chain { display: grid; gap: 0; margin: 15px 0 0; padding: 0; list-style: none; }
.personality-chain li { position: relative; display: grid; grid-template-columns: 22px 1fr; gap: 9px; padding: 0 0 13px; color: #7e8996; }
.personality-chain li:not(:last-child)::before { content: ""; position: absolute; left: 10px; top: 21px; bottom: 0; width: 1px; background: rgba(255, 255, 255, 0.12); }
.personality-chain li > span { display: grid; width: 22px; height: 22px; place-items: center; border: 1px solid rgba(255, 255, 255, 0.17); border-radius: 50%; font-size: 9px; }
.personality-chain strong { color: #dfe5eb; font-size: 11px; }
.personality-chain p { margin: 3px 0 0; font-size: 10px; line-height: 1.5; }
.personality-chain li.passed > span { border-color: #70cad2; color: #70cad2; }
.personality-chain li.current > span { border-color: #f2a8bd; background: #f2a8bd; color: #15181d; }
.personality-chain li.current strong { color: #f2a8bd; }
.personality-privacy { color: #77828f; font-size: 9px; }

.character-visual {
  position: relative;
  min-height: 270px;
  overflow: hidden;
  border-radius: 21px 21px 0 0;
  background: #0c1520;
}

.character-visual::after {
  content: '';
  position: absolute;
  inset: 35% 0 0;
  background: linear-gradient(180deg, transparent, rgba(10, 14, 21, 0.94));
  pointer-events: none;
}

.character-portrait-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.character-tags {
  position: absolute;
  z-index: 2;
  top: 14px;
  left: 14px;
  display: flex;
  gap: 7px;
}

.character-tags span {
  padding: 5px 9px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 7px;
  background: rgba(9, 14, 21, 0.72);
  color: #e9f7ff;
  font-size: 12px;
  backdrop-filter: blur(10px);
}

.character-tags span:last-child {
  border-color: rgba(85, 203, 222, 0.45);
  color: #9de6ef;
}

.character-close {
  position: absolute;
  z-index: 3;
  top: 12px;
  right: 12px;
  width: 44px;
  height: 44px;
  border: 1px solid rgba(255, 255, 255, 0.9);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.9);
  box-shadow: 0 5px 18px rgba(0, 0, 0, 0.28);
  color: #111722;
  font-size: 28px;
  font-weight: 500;
  line-height: 1;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

.character-close:hover,
.character-close:focus-visible {
  border-color: #ffffff;
  background: #ffffff;
  box-shadow: 0 0 0 3px rgba(100, 210, 255, 0.65), 0 7px 22px rgba(0, 0, 0, 0.34);
  color: #000000;
}

.character-identity {
  position: absolute;
  z-index: 2;
  right: 20px;
  bottom: 18px;
  left: 20px;
}

.character-stars {
  margin-bottom: 5px;
  color: #f1c45d;
  font-size: 15px;
  letter-spacing: 2px;
}

.character-identity p {
  margin: 0;
}

#characterLatinName {
  color: #8fcfd8;
  font-size: 11px;
  font-weight: 700;
}

.character-title-line {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.character-title-line h2 {
  font-size: 30px;
}

.character-title-line span {
  color: #c7d1dd;
  font-size: 12px;
}

#characterTitle {
  margin-top: 3px;
  color: #c6ccd5;
  font-size: 13px;
}

.character-body {
  padding: 18px 20px 20px;
}

.affection-row {
  display: grid;
  gap: 8px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--line);
}

.affection-row > div:first-child,
.stat-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.affection-row span,
.stat-label span {
  color: var(--muted);
  font-size: 12px;
}

.affection-row strong {
  color: #f2a8bd;
  font-size: 13px;
}

.affection-track,
.stat-track {
  height: 5px;
  overflow: hidden;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.08);
}

.affection-track i,
.stat-track i {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: linear-gradient(90deg, #d87594, #f2a8bd);
}

.character-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px 18px;
  padding: 17px 0;
}

.character-stat {
  display: grid;
  gap: 6px;
}

.stat-label strong {
  font-size: 13px;
}

.stat-track i {
  background: #61b9ca;
}

.stat-attack .stat-track i { background: #df766f; }
.stat-defense .stat-track i { background: #d3ad61; }
.stat-speed .stat-track i { background: #77c08a; }
.stat-magic .stat-track i { background: #8f8dd9; }

.character-facts {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  margin: 0;
  padding: 14px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.character-facts div {
  min-width: 0;
  padding: 0 10px;
  border-right: 1px solid var(--line);
}

.character-facts div:first-child { padding-left: 0; }
.character-facts div:last-child { padding-right: 0; border-right: 0; }

.character-facts dt {
  color: var(--muted);
  font-size: 11px;
}

.character-facts dd {
  overflow: hidden;
  margin: 4px 0 0;
  color: #eef2f7;
  font-size: 13px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.character-body blockquote {
  margin: 15px 0 0;
  color: #aeb7c4;
  font-family: ui-serif, "Songti SC", serif;
  font-size: 13px;
  line-height: 1.7;
}

.edit-avatar-btn {
  width: 100%;
  min-height: 38px;
  margin-top: 14px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--field);
  color: #dce3eb;
  font-size: 13px;
}
.edit-avatar-btn:disabled { cursor:not-allowed; border-style:dashed; color:#7d8794; background:rgba(255,255,255,.035); }

.character-actions {
  display: grid;
  grid-template-columns: 1fr 1.35fr;
  gap: 9px;
}

.wardrobe-panel {
  width: min(420px, 100%);
  max-height: calc(100dvh - 28px);
  overflow-y: auto;
}

.wardrobe-actor-tabs {
  display: flex;
  gap: 7px;
  overflow-x: auto;
  padding-bottom: 2px;
}

.wardrobe-actor-tabs button {
  flex: 0 0 auto;
  min-height: 34px;
  padding: 0 13px;
  border: 1px solid var(--line);
  border-radius: 17px;
  background: var(--field);
  color: var(--muted);
  font-size: 12px;
}

.wardrobe-actor-tabs button.active {
  border-color: rgba(100, 210, 255, 0.72);
  background: rgba(100, 210, 255, 0.12);
  color: #dff8ff;
}

.wardrobe-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.wardrobe-card {
  position: relative;
  min-width: 0;
  overflow: hidden;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--field);
  color: var(--text);
  text-align: left;
}

.wardrobe-card.selected {
  border-color: #64d2ff;
  box-shadow: 0 0 0 2px rgba(100, 210, 255, 0.12);
}

.wardrobe-images {
  display: grid;
  grid-template-columns: 1fr;
  width: 100%;
  aspect-ratio: 4 / 5;
  overflow: hidden;
  background: #10141c;
}

.wardrobe-images.has-back {
  grid-template-columns: 1fr 1fr;
}

.wardrobe-images img {
  display: block;
  width: 100%;
  height: 100%;
  min-width: 0;
  object-fit: cover;
  object-position: 50% 18%;
  background: #10141c;
}

.wardrobe-card > span {
  display: grid;
  gap: 4px;
  min-height: 78px;
  padding: 10px;
}

.wardrobe-card strong {
  font-size: 13px;
}

.wardrobe-card small {
  color: var(--muted);
  font-size: 10px;
  line-height: 1.45;
}

.wardrobe-card i {
  position: absolute;
  top: 8px;
  right: 8px;
  padding: 4px 7px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 10px;
  background: rgba(8, 11, 16, 0.78);
  color: #d8e0e9;
  font-size: 10px;
  font-style: normal;
  backdrop-filter: blur(8px);
}

.wardrobe-card.selected i {
  border-color: #64d2ff;
  background: #64d2ff;
  color: #071017;
  font-weight: 700;
}

.avatar-panel {
  width: min(400px, 100%);
  max-height: calc(100dvh - 28px);
  overflow-y: auto;
}

.avatar-preview {
  width: 154px;
  aspect-ratio: 1;
  margin: 2px auto 4px;
  border: 1px solid rgba(111, 183, 199, 0.45);
  border-radius: 50%;
  background-color: #111722;
  box-shadow: 0 0 0 5px rgba(76, 168, 188, 0.08);
}

.avatar-presets {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 7px;
}

.avatar-preset {
  min-width: 0;
  display: grid;
  justify-items: center;
  gap: 6px;
  padding: 7px 3px;
  border: 1px solid transparent;
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  font-size: 11px;
}

.avatar-preset:hover,
.avatar-preset.active {
  border-color: rgba(93, 177, 194, 0.45);
  background: rgba(93, 177, 194, 0.09);
  color: #dff8fb;
}

.avatar-preset-photo {
  width: 48px;
  height: 48px;
  display: block;
  border-radius: 50%;
  background-color: #111722;
}

.upload-avatar-btn {
  min-height: 40px;
  display: grid;
  place-items: center;
  border: 1px dashed rgba(127, 183, 194, 0.5);
  border-radius: 9px;
  background: rgba(93, 177, 194, 0.06);
  color: #a8d8df;
  font-size: 13px;
  cursor: pointer;
}

.avatar-note {
  margin: -7px 0 0;
  color: var(--muted);
  font-size: 11px;
  text-align: center;
}

.avatar-controls {
  display: grid;
  gap: 11px;
  padding: 12px 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

.avatar-controls label {
  display: grid;
  grid-template-columns: 72px 1fr;
  align-items: center;
  gap: 10px;
}

.avatar-controls span {
  color: #bdc4ce;
  font-size: 12px;
}

.avatar-controls input {
  width: 100%;
  accent-color: #5db1c2;
}

.avatar-controls input:disabled {
  opacity: 0.3;
}

.avatar-actions {
  display: grid;
  grid-template-columns: 1fr 1.5fr;
  gap: 9px;
}

.avatar-actions > button:first-child {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--field);
  color: var(--text);
}

.visually-hidden {
  position: fixed;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

.profile-panel {
  width: min(480px, 100%);
  display: grid;
  gap: 14px;
  padding: 20px;
  border: 1px solid var(--line);
  border-radius: 24px;
  background: var(--panel-strong);
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.4);
}

.points-panel {
  width: min(420px, 100%);
}

.points-balance-card {
  display: grid;
  gap: 4px;
  padding: 20px;
  border: 1px solid rgba(100, 210, 255, 0.3);
  border-radius: 18px;
  background: linear-gradient(145deg, rgba(100, 210, 255, 0.14), rgba(10, 132, 255, 0.06));
}

.points-balance-card > span,
.points-balance-card > small,
.points-note,
.points-ledger-row small,
.points-ledger > p {
  color: var(--muted);
}

.points-balance-card > strong {
  font-size: clamp(34px, 10vw, 48px);
  line-height: 1.05;
  letter-spacing: -1px;
}

.points-balance-breakdown {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  margin-top: 5px;
}

.points-balance-breakdown small {
  display: inline-flex;
  gap: 5px;
}

.points-balance-breakdown b {
  color: var(--text);
}

.points-share-card {
  display: grid;
  gap: 10px;
  padding: 14px;
  border: 1px solid rgba(48, 209, 88, 0.3);
  border-radius: 16px;
  background: rgba(48, 209, 88, 0.07);
}

.points-share-card > div {
  display: grid;
  gap: 4px;
}

.points-share-card strong {
  font-size: 14px;
}

.points-share-card small,
.points-share-card > p {
  color: var(--muted);
  font-size: 11px;
  line-height: 1.55;
}

.points-share-card > p {
  min-height: 17px;
  margin: 0;
}

.points-share-card .primary-wide {
  min-height: 42px;
}

.points-note {
  margin: 0;
  font-size: 12px;
  line-height: 1.6;
}

.points-section-title {
  margin-bottom: 8px;
  font-size: 13px;
  font-weight: 700;
}

.points-ledger {
  display: grid;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--field);
}

.points-ledger > p {
  margin: 0;
  padding: 14px;
  font-size: 12px;
}

.points-ledger-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 13px 14px;
}

.points-ledger-row + .points-ledger-row {
  border-top: 1px solid var(--line);
}

.points-ledger-row > div {
  display: grid;
  gap: 3px;
}

.points-ledger-row strong {
  font-size: 13px;
}

.points-ledger-row small {
  font-size: 11px;
}

.points-ledger-row > b {
  font-size: 15px;
}

.points-ledger-row > b.positive {
  color: #30d158;
}

.points-ledger-row > b.negative {
  color: #ff453a;
}

.profile-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.settings-fullscreen-modal {
  z-index: 55;
  align-items: stretch;
  padding: 0;
  background: var(--panel-strong);
  backdrop-filter: none;
}

.settings-fullscreen-modal .profile-panel {
  width: 100%;
  height: 100dvh;
  max-height: none;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: max(22px, env(safe-area-inset-top)) clamp(18px, 4vw, 34px) max(18px, env(safe-area-inset-bottom));
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

/* CO0230：主页三栏导航固定在设置页上层；为最后一项预留完整底栏高度，
   确保“退出账户”等内容可以滚到导航上方，不再被遮挡。 */
:root.home-tabbar .settings-fullscreen-modal .profile-panel {
  padding-bottom: calc(var(--home-nav-h) + max(18px, env(safe-area-inset-bottom)));
}

.settings-fullscreen-modal .profile-head {
  position: sticky;
  top: calc(-1 * max(22px, env(safe-area-inset-top)));
  z-index: 4;
  min-height: 72px;
  margin: calc(-1 * max(22px, env(safe-area-inset-top))) calc(-1 * clamp(18px, 4vw, 34px)) 0;
  padding: max(22px, env(safe-area-inset-top)) clamp(18px, 4vw, 34px) 13px;
  border-bottom: 1px solid var(--line);
  background: var(--panel-strong);
}

.settings-context-banner {
  width: min(430px, 100%);
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 3px 12px;
  margin: 14px auto 12px;
  padding: 14px 16px;
  border: 1px solid rgba(65, 181, 224, 0.24);
  border-radius: 14px;
  background: rgba(65, 181, 224, 0.065);
}

.settings-context-banner > span {
  grid-row: 1 / span 2;
  align-self: center;
  padding: 5px 8px;
  border-radius: 6px;
  background: rgba(65, 181, 224, 0.12);
  color: #299bc6;
  font-size: 10px;
  font-weight: 800;
}

.settings-context-banner strong { font-size: 14px; }
.settings-context-banner small { color: var(--muted); font-size: 11px; line-height: 1.45; }

.game-character-card {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
}

.game-character-avatar {
  width: 64px;
  height: 64px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background-color: var(--field);
  background-repeat: no-repeat;
}

.game-character-copy { min-width: 0; }
.game-character-copy > span,
.settings-card-note {
  color: var(--muted);
  font-size: 11px;
}
.game-character-copy h3 { margin: 3px 0; font-size: 20px; }
.game-character-copy small { color: var(--muted); }
.game-character-actions {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

/* ══ CO0266 已登场演员列表 ═══════════════════════════════════════════════ */
.game-cast-list {
  display: grid;
  gap: 8px;
  max-height: 320px; /* 列表可能很长：390×844 下自己滚，不撑爆设置页 */
  overflow-y: auto;
  overscroll-behavior: contain;
}

.game-cast-row {
  display: flex;
  align-items: center;
  gap: 11px;
  min-width: 0;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--field);
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.game-cast-row.is-current {
  border-color: rgba(116, 183, 255, 0.42);
  background: rgba(72, 132, 212, 0.1);
}

.game-cast-row .game-cast-photo {
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background-color: var(--field);
  background-repeat: no-repeat;
  overflow: hidden;
}

.game-cast-copy {
  flex: 1 1 auto;
  display: grid;
  gap: 2px;
  min-width: 0; /* 长名字/长定位截断，390 宽不横向溢出 */
}

.game-cast-copy strong {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.game-cast-copy small {
  color: var(--muted);
  font-size: 11px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.game-cast-current {
  flex: 0 0 auto;
  padding: 1px 7px;
  border: 1px solid rgba(116, 183, 255, 0.42);
  border-radius: 999px;
  color: #9fd4ff;
  font-size: 10px;
  font-style: normal;
  font-weight: 800;
}

.game-cast-affection {
  flex: 0 0 auto;
  color: #f2a8bd;
  font-size: 11px;
  font-weight: 700;
}

.settings-game-explainer p,
.settings-card-note {
  margin: 0;
  line-height: 1.6;
}

.settings-audio-card {
  display: grid;
  gap: 12px;
}

.settings-audio-list {
  display: grid;
  gap: 8px;
}

.profile-panel .settings-audio-toggle {
  position: relative;
  min-height: 58px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 46px;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--field);
  color: var(--text);
  cursor: pointer;
}

.settings-audio-toggle > span {
  min-width: 0;
  display: grid;
  gap: 3px;
}

.settings-audio-toggle strong {
  font-size: 13px;
}

.settings-audio-toggle small {
  color: var(--muted);
  font-size: 10px;
  line-height: 1.4;
}

.profile-panel .settings-audio-toggle input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  opacity: 0;
  pointer-events: none;
}

.settings-audio-toggle > i {
  position: relative;
  width: 44px;
  height: 26px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 999px;
  background: rgba(128, 128, 138, 0.34);
  transition: background 160ms ease, border-color 160ms ease;
}

.settings-audio-toggle > i::after {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.24);
  content: "";
  transition: transform 180ms cubic-bezier(0.22, 1, 0.36, 1);
}

.settings-audio-toggle input:checked + i {
  border-color: rgba(139, 108, 255, 0.7);
  background: #8b6cff;
}

.settings-audio-toggle input:checked + i::after {
  transform: translateX(18px);
}

.settings-audio-toggle input:focus-visible + i {
  outline: 2px solid #8b6cff;
  outline-offset: 3px;
}

.settings-points-card .settings-section-head strong {
  color: #299bc6;
  font-size: 24px;
  font-variant-numeric: tabular-nums;
}

.settings-back-btn {
  font-family: Arial, sans-serif;
  font-size: 32px;
  font-weight: 300;
  line-height: 28px;
}

.settings-page-grid {
  width: min(430px, 100%);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
  gap: 18px;
  margin: 4px auto 0;
}

.settings-page-column {
  min-width: 0;
  display: grid;
  gap: 14px;
}

.settings-preferences-card,
.settings-appearance-card,
.settings-owner-section {
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--field);
}

.settings-owner-section {
  border-color: rgba(255, 192, 83, 0.34);
  background: rgba(255, 192, 83, 0.055);
}

.owner-only-badge {
  padding: 4px 7px;
  border: 1px solid rgba(255, 192, 83, 0.45);
  border-radius: 5px;
  color: #d79a2a;
  font-size: 9px;
  font-weight: 800;
}

.owner-settings-note,
.owner-current-context {
  margin: 0;
  color: var(--muted);
  font-size: 11px;
  line-height: 1.55;
}

.settings-save-bar {
  position: sticky;
  z-index: 4;
  right: 0;
  bottom: calc(-1 * max(18px, env(safe-area-inset-bottom)));
  left: 0;
  width: min(430px, 100%);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(160px, 240px);
  align-items: center;
  gap: 16px;
  margin: 4px auto calc(-1 * max(18px, env(safe-area-inset-bottom)));
  padding: 13px 0 max(18px, env(safe-area-inset-bottom));
  border-top: 1px solid var(--line);
  background: var(--panel-strong);
}

.settings-save-bar > span {
  color: var(--muted);
  font-size: 11px;
}

.settings-save-bar .primary-wide:disabled {
  cursor: default;
  opacity: 0.42;
}

.profile-panel label {
  display: grid;
  gap: 7px;
  color: var(--muted);
  font-size: 13px;
}

.profile-panel input,
.profile-panel textarea,
.profile-panel select {
  width: 100%;
  border: 1px solid var(--line);
  outline: none;
  border-radius: 14px;
  padding: 11px 12px;
  background: var(--field);
  color: var(--text);
}

.profile-panel textarea {
  resize: vertical;
  min-height: 86px;
}

@media (max-width: 700px) {
  .settings-save-bar {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  .settings-save-bar > span {
    text-align: center;
  }

  .settings-context-banner {
    grid-template-columns: 1fr;
  }

  .settings-context-banner > span {
    grid-row: auto;
    justify-self: start;
  }
}

.theme-picker {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.theme-picker legend {
  margin-bottom: 7px;
  color: var(--muted);
  font-size: 13px;
}

.theme-options {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.theme-options label {
  min-width: 0;
  display: block;
  cursor: pointer;
}

.theme-options input {
  position: fixed;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.theme-option {
  min-height: 70px;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 9px;
  padding: 10px 6px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--field);
  color: var(--text);
  transition: border-color 0.16s ease, box-shadow 0.16s ease, transform 0.16s ease;
}

.theme-option i {
  display: flex;
  gap: 4px;
  font-style: normal;
}

.theme-option b {
  width: 14px;
  height: 14px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 50%;
}

.theme-option strong {
  max-width: 100%;
  overflow: hidden;
  font-size: 11px;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* CO0135：紫色主题 swatch（第一槽）。 */
.theme-option-violet b:nth-child(1) { background: #0f0b1a; }
.theme-option-violet b:nth-child(2) { background: #271d3d; }
.theme-option-violet b:nth-child(3) { background: #8b6cff; }
.theme-option-midnight b:nth-child(1) { background: #0b0d12; }
.theme-option-midnight b:nth-child(2) { background: #232838; }
.theme-option-midnight b:nth-child(3) { background: #0a84ff; }
.theme-option-campus b:nth-child(1) { background: #f8fbfd; }
.theme-option-campus b:nth-child(2) { background: #a9c8dc; }
.theme-option-campus b:nth-child(3) { background: #3b8edb; }
.theme-option-cinema b:nth-child(1) { background: #050505; }
.theme-option-cinema b:nth-child(2) { background: #8a6a35; }
.theme-option-cinema b:nth-child(3) { background: #d6c4a1; }
.theme-option-wechat b:nth-child(1) { background: #ededed; }
.theme-option-wechat b:nth-child(2) { background: #ffffff; }
.theme-option-wechat b:nth-child(3) { background: #95ec69; }

.theme-options input:checked + .theme-option {
  border-color: #64bde5;
  box-shadow: 0 0 0 3px rgba(70, 171, 218, 0.14);
}

.theme-options input:focus-visible + .theme-option {
  outline: 2px solid #64bde5;
  outline-offset: 2px;
}

/* 校园 Galgame：明亮、轻快，保留聊天效率。 */
:root[data-theme="campus"] .app {
  background: rgba(244, 249, 252, 0.8);
  box-shadow: 0 0 60px rgba(55, 79, 99, 0.16);
}

:root[data-theme="campus"] .topbar,
:root[data-theme="campus"] .composer {
  background: rgba(248, 252, 254, 0.94);
}

:root[data-theme="campus"] .scene-background {
  filter: blur(12px) saturate(0.72) brightness(1.08);
  opacity: 0.5;
}

:root[data-theme="campus"] .chat-stage::after {
  background: rgba(239, 246, 250, 0.55);
}

:root[data-theme="campus"] .story-narration {
  border-color: rgba(75, 122, 151, 0.2);
  border-left-color: #6da7bd;
  background: rgba(250, 253, 255, 0.74);
  color: #556776;
}

:root[data-theme="campus"] .dialogue-bubble {
  border-color: rgba(63, 91, 112, 0.13);
  background: rgba(255, 255, 255, 0.94);
  color: #24313d;
  box-shadow: 0 8px 24px rgba(66, 91, 111, 0.1);
}

:root[data-theme="campus"] .speaker-name { color: #39738a; }
:root[data-theme="campus"] .more-menu { background: rgba(253, 254, 255, 0.98); box-shadow: 0 18px 55px rgba(55, 79, 99, 0.2); }
:root[data-theme="campus"] .more-menu button:hover { background: rgba(63, 116, 153, 0.08); }
:root[data-theme="campus"] .story-choices button { border-color: rgba(55, 79, 99, 0.14); background: rgba(255, 255, 255, 0.7); color: #263746; }
:root[data-theme="campus"] .system-strip { background: rgba(87, 155, 175, 0.09); color: #526572; }
:root[data-theme="campus"] .character-trigger.multi-character { background: rgba(248, 252, 254, 0.94); }
:root[data-theme="campus"] .character-trigger .avatar-photo { border-color: #eef5f8; }

/* 电影叙事：弱化控件，以字幕和场景为中心。 */
:root[data-theme="cinema"] .app {
  background: rgba(3, 3, 3, 0.7);
  box-shadow: 0 0 90px rgba(0, 0, 0, 0.72);
}

:root[data-theme="cinema"] .topbar,
:root[data-theme="cinema"] .composer {
  background: rgba(4, 4, 4, 0.88);
}

:root[data-theme="cinema"] .scene-background {
  filter: blur(7px) saturate(0.78) brightness(0.74);
  opacity: 0.9;
}

:root[data-theme="cinema"] .chat-stage::after { background: rgba(0, 0, 0, 0.38); }

:root[data-theme="cinema"] .story-turn { gap: 20px; }

:root[data-theme="cinema"] .story-narration {
  border: 0;
  border-left: 2px solid rgba(196, 157, 91, 0.62);
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.34);
  color: #c8c0b3;
  font-size: 13px;
}

:root[data-theme="cinema"] .dialogue-bubble {
  border-color: rgba(214, 196, 161, 0.18);
  border-radius: 6px;
  background: rgba(5, 5, 5, 0.8);
  color: #f0ece3;
  font-family: ui-serif, "Songti SC", "STSong", serif;
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.34);
}

:root[data-theme="cinema"] .speaker-name { color: #c6a86e; }
:root[data-theme="cinema"] .message-row.user .bubble { border-radius: 6px; background: #7d6032; }
:root[data-theme="cinema"] .story-choices { grid-template-columns: 1fr; }
:root[data-theme="cinema"] .story-choices button { border-color: rgba(214, 196, 161, 0.17); border-radius: 5px; background: rgba(5, 5, 5, 0.66); color: #ece6da; }
:root[data-theme="cinema"] .story-choices button span { background: rgba(157, 123, 64, 0.2); color: #d4b87f; }
:root[data-theme="cinema"] .more-menu { background: rgba(12, 12, 11, 0.98); }
:root[data-theme="cinema"] .composer textarea { border-radius: 8px; }
:root[data-theme="cinema"] .composer button { border-radius: 8px; background: #806236; }

/* 经典聊天：严格沿用参考图的浅灰会话、左右头像与绿色己方气泡。 */
:root[data-theme="wechat"] .app {
  background: #ededed;
  box-shadow: none;
}

:root[data-theme="wechat"] .topbar {
  position: relative;
  min-height: 62px;
  justify-content: stretch;
  padding: 0 16px;
  border-bottom-color: rgba(0, 0, 0, 0.08);
  background: #ededed;
  box-shadow: none;
}

:root[data-theme="wechat"] .top-actions {
  width: 100%;
  justify-content: space-between;
}

:root[data-theme="wechat"] .chat-contact-btn {
  position: absolute;
  z-index: 2;
  left: 50%;
  top: 50%;
  display: block;
  max-width: 58%;
  overflow: hidden;
  padding: 0;
  border: 0;
  background: transparent;
  color: #171717;
  font-size: 18px;
  font-weight: 650;
  text-overflow: ellipsis;
  transform: translate(-50%, -50%);
  white-space: nowrap;
}

:root[data-theme="wechat"] .chat-contact-btn:disabled {
  color: #171717;
}

:root[data-theme="wechat"] .character-trigger {
  display: none;
}

:root[data-theme="wechat"] .scene-trigger {
  width: 38px;
  height: 44px;
  flex-basis: 38px;
  padding: 0;
  overflow: visible;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  color: #171717;
}

:root[data-theme="wechat"] .scene-trigger span {
  display: none;
}

:root[data-theme="wechat"] .scene-trigger::before {
  content: "‹";
  display: block;
  font-family: Arial, sans-serif;
  font-size: 42px;
  font-weight: 300;
  line-height: 36px;
  transform: translateY(-1px);
}

:root[data-theme="wechat"] .more-btn {
  width: 42px;
  height: 44px;
  padding: 0 0 7px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: #171717;
  box-shadow: none;
  font-size: 18px;
  font-weight: 800;
  letter-spacing: 3px;
}

:root[data-theme="wechat"] .game-topbar {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) 44px;
  justify-content: initial;
  padding: 8px 12px;
}

:root[data-theme="wechat"] .game-topbar.stamina-enabled {
  grid-template-columns: 44px minmax(0, 1fr) auto 44px;
}

:root[data-theme="wechat"] .stamina-hud {
  border-color: rgba(124, 84, 204, 0.24);
  background: #fff;
  color: #231b2e;
  box-shadow: none;
}

:root[data-theme="wechat"] .game-topbar .chat-contact-btn {
  position: static;
  left: auto;
  top: auto;
  max-width: none;
  color: #171717;
  transform: none;
}

:root[data-theme="wechat"] .game-home-back,
:root[data-theme="wechat"] .game-settings-trigger {
  color: #171717;
}

:root[data-theme="wechat"] .game-settings-trigger {
  border-color: rgba(0, 0, 0, 0.08);
  background: rgba(255, 255, 255, 0.62);
}

:root[data-theme="wechat"] .more-menu {
  top: 50px;
  border-color: rgba(0, 0, 0, 0.09);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.98);
  box-shadow: 0 10px 32px rgba(0, 0, 0, 0.16);
}

:root[data-theme="wechat"] .more-menu button:hover {
  background: rgba(0, 0, 0, 0.05);
}

:root[data-theme="wechat"] .scene-background,
:root[data-theme="wechat"] .chat-stage::after {
  display: none;
}

:root[data-theme="wechat"] .chat-stage,
:root[data-theme="wechat"] .messages {
  background: #ededed;
}

:root[data-theme="wechat"] .messages {
  gap: 18px;
  padding: 26px 12px 88px;
}

:root[data-theme="wechat"] .chat-time {
  align-self: center;
  display: block;
  margin: 2px 0 4px;
  color: #adadad;
  font-size: 12px;
  line-height: 1.4;
}

:root[data-theme="wechat"] .story-turn {
  gap: 16px;
}

:root[data-theme="wechat"] .dialogue-row {
  align-items: flex-start;
  gap: 10px;
}

:root[data-theme="wechat"] .dialogue-row > .avatar {
  margin-top: 0;
}

:root[data-theme="wechat"] .avatar,
:root[data-theme="wechat"] .user-avatar {
  width: 40px;
  height: 40px;
  flex: 0 0 40px;
  border: 0;
  border-radius: 4px;
  background-color: #d8d8d8;
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
  box-shadow: none;
  overflow: hidden;
}

:root[data-theme="wechat"] .user-avatar {
  display: block;
}

:root[data-theme="wechat"] .user-avatar.text-avatar {
  display: grid;
  place-items: center;
  background-color: #146de0;
  background-image: none;
  color: #fff;
  font-size: 16px;
  font-weight: 750;
}

:root[data-theme="wechat"] .dialogue-content {
  max-width: calc(100% - 96px);
}

:root[data-theme="wechat"] .speaker-name {
  display: none;
}

:root[data-theme="wechat"] .bubble,
:root[data-theme="wechat"] .dialogue-bubble {
  position: relative;
  max-width: calc(100% - 96px);
  padding: 10px 13px;
  border: 0;
  border-radius: 4px;
  color: #171717;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang SC", "Microsoft YaHei", sans-serif;
  font-size: 16px;
  font-weight: 400;
  line-height: 1.55;
  letter-spacing: 0;
  box-shadow: none;
}

:root[data-theme="wechat"] .dialogue-bubble {
  max-width: 100%;
  background: #ffffff;
}

:root[data-theme="wechat"] .dialogue-bubble::before {
  position: absolute;
  top: 13px;
  left: -6px;
  width: 0;
  height: 0;
  content: "";
  border-top: 6px solid transparent;
  border-right: 7px solid #ffffff;
  border-bottom: 6px solid transparent;
}

:root[data-theme="wechat"] .message-row.user {
  align-items: flex-start;
  gap: 10px;
}

:root[data-theme="wechat"] .message-row.user .bubble {
  border-radius: 4px;
  background: #95ec69;
  color: #171717;
}

:root[data-theme="wechat"] .message-row.user .bubble::after {
  position: absolute;
  top: 13px;
  right: -6px;
  width: 0;
  height: 0;
  content: "";
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  border-left: 7px solid #95ec69;
}

:root[data-theme="wechat"] .story-narration {
  width: 86%;
  margin: 3px auto;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: #8d8d8d;
  backdrop-filter: none;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "PingFang SC", sans-serif;
  font-size: 13px;
  line-height: 1.7;
  text-align: center;
}

:root[data-theme="wechat"] .story-narration.live::after {
  background: #8d8d8d;
}

:root[data-theme="wechat"] .system-strip {
  width: auto;
  max-width: 86%;
  grid-template-columns: 1fr;
  gap: 3px;
  padding: 6px 10px;
  border: 0;
  border-radius: 4px;
  background: #dedede;
  color: #777777;
  font-size: 12px;
  text-align: center;
}

:root[data-theme="wechat"] .system-strip strong {
  color: #696969;
}

:root[data-theme="wechat"] .story-choices {
  width: calc(100% - 50px);
  margin-left: 50px;
  grid-template-columns: 1fr;
  gap: 8px;
}

:root[data-theme="wechat"] .story-choices button {
  min-height: 42px;
  border: 0;
  border-radius: 4px;
  background: #ffffff;
  color: #171717;
  box-shadow: none;
}

:root[data-theme="wechat"] .story-choices button span {
  background: #e8e8e8;
  color: #777777;
}

:root[data-theme="wechat"] .composer {
  gap: 8px;
  padding: 9px 10px calc(9px + env(safe-area-inset-bottom));
  border-top-color: rgba(0, 0, 0, 0.09);
  background: #f7f7f7;
}

:root[data-theme="wechat"] .composer textarea {
  min-height: 42px;
  padding: 10px 12px;
  border: 0;
  border-radius: 5px;
  background: #ffffff;
  color: #171717;
  box-shadow: none;
}

:root[data-theme="wechat"] .composer textarea:focus {
  border: 0;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}

:root[data-theme="wechat"] .composer.continue-mode textarea[data-continue-default="true"] {
  color: #888888;
}

:root[data-theme="wechat"] .composer button {
  min-width: 58px;
  min-height: 42px;
  padding: 0 12px;
  border-radius: 5px;
  background: #07c160;
  color: #ffffff;
  font-size: 14px;
}

:root[data-theme="wechat"] .profile-panel {
  background: #ffffff;
}

:root[data-theme="wechat"] .avatar-preset:hover,
:root[data-theme="wechat"] .avatar-preset.active {
  border-color: #69b8ca;
  background: #eaf7fa;
  color: #173f48;
}

:root[data-theme="wechat"] .upload-avatar-btn {
  border-color: #9bbfc7;
  background: #f7fbfc;
  color: #3b626b;
}

.primary-wide {
  min-height: 46px;
}

@media (max-width: 560px) {
  html,
  body {
    touch-action: manipulation;
  }

  .app {
    position: fixed;
    top: var(--viewport-offset-top, 0px);
    right: 0;
    bottom: auto;
    left: 0;
    width: 100%;
    height: var(--viewport-height, 100dvh);
    margin: 0;
    border: 0;
    box-shadow: none;
  }

  .game-shell {
    position: fixed;
    top: var(--viewport-offset-top, 0px);
    right: 0;
    bottom: auto;
    left: 0;
    width: 100%;
    height: var(--viewport-height, 100dvh);
  }

  .game-home {
    border: 0;
  }

  .topbar {
    min-height: calc(50px + env(safe-area-inset-top));
    padding: max(8px, env(safe-area-inset-top)) 12px 8px;
    gap: 8px;
  }

  h1 {
    font-size: 18px;
  }

  .actor-row {
    grid-template-columns: 50px minmax(0, 1fr) auto;
    gap: 8px;
  }

  .actor-row > img {
    width: 50px;
    height: 66px;
  }

  .actor-info small {
    display: none;
  }

  .ghost-btn {
    min-width: 0;
    padding: 7px 8px;
    font-size: 12px;
  }

  .character-trigger,
  .scene-trigger {
    width: 34px;
    height: 34px;
    flex-basis: 34px;
  }

  .more-btn {
    width: 34px;
    height: 34px;
  }

  .messages {
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-y;
    padding: 18px 14px 28px;
  }

  .composer {
    position: relative;
    z-index: 12;
    align-items: end;
    gap: 8px;
    min-height: 60px;
    padding: 8px 10px max(8px, env(safe-area-inset-bottom));
  }

  .composer textarea,
  :root[data-theme="wechat"] .composer textarea {
    min-height: 44px;
    max-height: 96px;
    padding: 11px 13px;
    border-radius: 16px;
    line-height: 20px;
    font-size: 16px;
  }

  .composer button,
  :root[data-theme="wechat"] .composer button {
    min-width: 62px;
    min-height: 44px;
    height: 44px;
    padding: 0 13px;
    border-radius: 14px;
  }

  /* CO0263：+ 按钮在手机上跟 44px 的输入框/发送键对齐 */
  .composer #composerPlusBtn {
    min-width: 44px;
    width: 44px;
    height: 44px;
    min-height: 44px;
    padding: 0;
    border-radius: 14px;
  }

  :root.keyboard-open .topbar {
    min-height: 50px;
    padding-top: 8px;
  }

:root.keyboard-open .composer,
  :root.keyboard-open[data-theme="wechat"] .composer {
    min-height: 60px;
    padding-bottom: 8px;
  }

  :root.access-cooldown:not([data-ai-connection-mode="personal"]) .composer textarea,
  :root.access-cooldown[data-theme="wechat"]:not([data-ai-connection-mode="personal"]) .composer textarea {
    pointer-events: none;
  }

  .bubble {
    max-width: 82%;
    font-size: 15px;
  }

  .dialogue-content {
    max-width: calc(100% - 46px);
  }

  .dialogue-bubble {
    max-width: 100%;
  }

  .story-narration {
    padding: 11px 12px;
    font-size: 13px;
  }

  .story-choices {
    grid-template-columns: 1fr;
  }

  .save-slot {
    grid-template-columns: 1fr;
    gap: 10px;
  }

  .save-slot-actions {
    justify-content: flex-end;
  }

  .character-visual {
    min-height: 245px;
  }

  .character-title-line h2 {
    font-size: 26px;
  }
}
/* Authentication and paid-access shell */
.access-shell {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: grid;
  place-items: center;
  padding: 24px;
  background: #090c12;
  color: #f5f7fb;
}

.access-shell.inside-game {
  align-items: end;
  padding: 18px;
  background: rgba(9, 12, 18, 0.56);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}

.access-shell.inside-game .access-panel {
  width: min(100%, 420px);
  max-height: min(680px, calc(100dvh - 36px));
  overflow-y: auto;
  border-color: rgba(117, 212, 230, 0.42);
}

.access-shell[hidden],
.access-panel[hidden] {
  display: none;
}

.access-panel {
  position: relative;
  width: min(100%, 390px);
  padding: 34px 28px 28px;
  border: 1px solid #2d3441;
  border-radius: 8px;
  background: #151a23;
  box-shadow: 0 28px 70px rgba(0, 0, 0, 0.42);
}

.access-language-select {
  position: absolute;
  top: 16px;
  right: 16px;
  width: auto;
  min-width: 108px;
}

.access-oauth {
  display: grid;
  gap: 9px;
  margin-top: 18px;
}

.access-oauth-divider {
  display: flex;
  align-items: center;
  gap: 10px;
  color: rgba(255, 255, 255, 0.38);
  font-size: 11px;
}

.access-oauth-divider::before,
.access-oauth-divider::after {
  height: 1px;
  flex: 1;
  background: rgba(255, 255, 255, 0.09);
  content: "";
}

.access-oauth > button {
  display: grid;
  grid-template-columns: 30px 1fr auto;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 48px;
  padding: 8px 12px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  border-radius: 13px;
  background: rgba(255, 255, 255, 0.035);
  color: rgba(255, 255, 255, 0.68);
  text-align: left;
}

.access-oauth > button:disabled {
  cursor: not-allowed;
  opacity: 0.62;
}

.access-oauth-icon {
  display: grid;
  width: 30px;
  height: 30px;
  place-items: center;
  border: 1px solid rgba(185, 168, 255, 0.28);
  border-radius: 9px;
  color: #d9ceff;
  font-size: 13px;
  font-weight: 800;
}

.access-oauth strong {
  font-size: 13px;
}

.access-oauth small {
  color: rgba(255, 255, 255, 0.38);
  font-size: 10px;
}

.access-loading {
  display: grid;
  justify-items: center;
  gap: 12px;
  text-align: center;
}

.access-mark {
  display: grid;
  width: 48px;
  height: 48px;
  place-items: center;
  margin-bottom: 22px;
  border: 1px solid #65bed2;
  border-radius: 50%;
  color: #a4e8f4;
  font-size: 20px;
}

.access-loading .access-mark { margin: 0; }
.access-loading p { margin: 0; color: #9ca6b5; }

.access-eyebrow {
  color: #74c7d9;
  font-size: 11px;
  font-weight: 750;
  text-transform: uppercase;
}

.access-panel h1 {
  margin: 8px 0 10px;
  font-size: 28px;
  letter-spacing: 0;
}

.access-panel > p {
  margin: 0 0 24px;
  color: #aab2c0;
  font-size: 14px;
  line-height: 1.65;
}

.secret-period {
  display: inline;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: default;
}

.access-form {
  display: grid;
  gap: 10px;
}

.access-form label {
  color: #cbd2dc;
  font-size: 12px;
  font-weight: 700;
}

.access-form input {
  width: 100%;
  height: 48px;
  padding: 0 14px;
  border: 1px solid #343c49;
  border-radius: 6px;
  outline: none;
  background: #0f131a;
  color: #fff;
  font-size: 16px;
}

.access-form input:focus { border-color: #69c7da; box-shadow: 0 0 0 3px rgba(105, 199, 218, 0.12); }

.access-form button,
.access-primary,
.access-secondary {
  min-height: 48px;
  border: 0;
  border-radius: 6px;
  font-size: 15px;
  font-weight: 750;
  cursor: pointer;
}

.access-form button,
.access-primary { background: #75d4e6; color: #071014; }
.access-secondary { background: #252c38; color: #edf2f7; }
.access-form button:disabled,
.access-primary:disabled { opacity: 0.55; cursor: wait; }

.access-message {
  min-height: 20px;
  margin: 14px 0 0 !important;
  color: #84d8e8 !important;
  font-size: 12px !important;
}

.access-message.error { color: #ff8d98 !important; }

.access-delivery-hint {
  margin: 14px 0 6px !important;
  color: #818b99 !important;
  font-size: 12px !important;
  line-height: 1.55 !important;
}

.access-resend {
  justify-self: start;
  padding: 4px 0;
  color: #84d8e8;
  font-weight: 700;
}

.access-resend:disabled {
  color: #66707e;
  cursor: default;
}

.access-back {
  position: absolute;
  top: 18px;
  right: 18px;
  width: 36px;
  height: 36px;
  border: 1px solid #343c49;
  border-radius: 50%;
  background: transparent;
  color: #fff;
  font-size: 28px;
}

.paywall-panel { display: grid; gap: 12px; }
.paywall-panel .access-mark { margin-bottom: 6px; }
.paywall-panel > p { margin-bottom: 4px; }

:root.access-cooldown:not([data-ai-connection-mode="personal"]) .composer {
  cursor: pointer;
  background: var(--panel-strong);
}

:root.access-cooldown:not([data-ai-connection-mode="personal"]) .composer textarea {
  cursor: pointer;
  color: var(--muted);
  opacity: 0.82;
}

:root.access-cooldown:not([data-ai-connection-mode="personal"]) .composer button {
  min-width: 76px;
  background: #202733;
  color: #bfeaf2;
}

:root[data-theme="wechat"].access-cooldown:not([data-ai-connection-mode="personal"]) .composer button {
  background: #dfe4e7;
  color: #3e6068;
}

.upgrade-panel {
  width: min(380px, 100%);
}

.upgrade-modal {
  z-index: 80;
}

.upgrade-description {
  margin: 0;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.65;
}

.upgrade-price {
  display: flex;
  align-items: baseline;
  gap: 7px;
  padding: 8px 0 2px;
}

.upgrade-price strong { font-size: 32px; }
.upgrade-price span { color: var(--muted); font-size: 13px; }

.upgrade-secondary {
  min-height: 44px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--field);
  color: var(--text);
  font-weight: 650;
}

.price-line { display: flex; align-items: baseline; gap: 7px; margin: 8px 0; }
.price-line strong { font-size: 34px; }
.price-line span { color: #929dac; }

.benefit-list {
  display: grid;
  gap: 10px;
  margin: 6px 0 16px;
  padding: 0;
  list-style: none;
  color: #d2d8e1;
  font-size: 14px;
}

.benefit-list li::before { content: '✓'; margin-right: 9px; color: #75d4e6; }

.access-link {
  border: 0;
  background: none;
  color: #929dac;
  font-size: 13px;
  cursor: pointer;
}

@media (max-width: 430px) {
  .access-shell { padding: 0; }
  .access-panel {
    min-height: 100dvh;
    width: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    border: 0;
    border-radius: 0;
    /* CO0129：面板全屏化后顶边即状态栏，顶部内边距吃进 safe-area。 */
    padding: max(32px, calc(env(safe-area-inset-top) + 16px)) 24px 32px;
  }
  /* CO0129：返回键与语言选择器是绝对定位在面板顶角的，全屏化后要让过状态栏时钟/电量。 */
  .access-back { top: max(18px, calc(env(safe-area-inset-top) + 6px)); }
  .access-language-select { top: max(16px, calc(env(safe-area-inset-top) + 6px)); }
  .access-panel[hidden] { display: none; }

  .access-shell.inside-game {
    align-items: end;
    padding: 12px;
  }

  .access-shell.inside-game .access-panel {
    min-height: 0;
    max-height: calc(100dvh - 24px);
    border: 1px solid rgba(117, 212, 230, 0.42);
    border-radius: 14px;
    padding: 28px 22px calc(22px + env(safe-area-inset-bottom));
  }

  .access-shell.inside-game .access-mark {
    width: 40px;
    height: 40px;
    margin-bottom: 14px;
  }

  .access-shell.inside-game .access-panel h1 {
    font-size: 24px;
  }
}

/* 黑底高端登录加载页 */
.access-shell { background: radial-gradient(120% 90% at 50% 30%, #16131f 0%, #000 62%) !important; }
.access-loading { background: transparent !important; border: 0 !important; box-shadow: none !important; }
.lux-loader { position: relative; width: 92px; height: 92px; margin: 0 auto 28px; display: grid; place-items: center; }
.lux-ring { position: absolute; inset: 0; border-radius: 50%; border: 1.5px solid rgba(255,255,255,0.07); border-top-color: rgba(180,150,255,0.95); animation: luxSpin 1.1s linear infinite; }
.lux-ring::after { content: ""; position: absolute; inset: -10px; border-radius: 50%; background: radial-gradient(circle, rgba(139,108,255,0.28), transparent 70%); animation: luxPulse 2.4s ease-in-out infinite; }
.lux-mark { font-family: ui-serif, "Songti SC", serif; font-size: 30px; font-weight: 600; background: linear-gradient(135deg, #ffffff, #cbb8ff); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.lux-title { margin: 0 0 9px; font-size: 17px; font-weight: 600; letter-spacing: 0.2em; color: #fff; }
.lux-sub { margin: 0; font-size: 11px; letter-spacing: 0.16em; color: rgba(255,255,255,0.42); animation: luxFade 1.8s ease-in-out infinite; }
@keyframes luxSpin { to { transform: rotate(360deg); } }
@keyframes luxPulse { 0%, 100% { opacity: 0.4; } 50% { opacity: 1; } }
@keyframes luxFade { 0%, 100% { opacity: 0.35; } 50% { opacity: 0.7; } }

/* 加载页 icon 图片(替代"由"字) */
.lux-mark-img { width: 62px; height: 62px; border-radius: 50%; object-fit: cover; object-position: 50% 22%; box-shadow: 0 4px 20px rgba(139,108,255,0.35); }

/* ══ CO0253 造物主 · 好感度调节（点头像面板内）══════════════════════════════
   ⛔ 只在 OWNER_MODE 下由 JS 摘掉 hidden；普通玩家永远看不到这一块。 */
.contact-detail-creator[hidden] { display: none; }
.contact-detail-creator {
  margin-top: 14px;
  padding: 12px 14px;
  border: 1px solid rgba(212, 178, 90, 0.28);
  border-radius: 12px;
  background: rgba(212, 178, 90, 0.06);
}
.contact-detail-creator > label {
  display: block;
  margin-bottom: 8px;
  color: #e4c879;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
}
.contact-detail-creator-row {
  display: flex;
  align-items: center;
  gap: 12px;
}
.contact-detail-creator-row input[type="range"] {
  flex: 1;
  accent-color: #d4b25a;
}
.contact-detail-creator-row output {
  min-width: 3ch;
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.contact-detail-creator-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 10px;
}
.contact-detail-creator-presets button {
  min-height: 32px;
  padding: 5px 11px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.05);
  color: #e9e4f5;
  font-size: 12px;
  cursor: pointer;
}
.contact-detail-creator-presets button:hover {
  border-color: rgba(212, 178, 90, 0.5);
  background: rgba(212, 178, 90, 0.12);
}
.contact-detail-creator-status {
  margin: 9px 0 0;
  min-height: 1.2em;
  color: rgba(255, 255, 255, 0.55);
  font-size: 11.5px;
}
