/* 暖语AI - 简洁清爽风格 */
:root {
  --bg: #f7f8fa;
  --panel: #ffffff;
  --border: #e8ebf0;
  --text: #2b2f36;
  --text-sub: #8a94a3;
  --primary: #4f7cff;
  --primary-soft: #eef3ff;
  --danger: #e5484d;
  --radius: 14px;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { height: 100%; }
/* 横竖屏切换时别让 Safari 自作主张改字号 */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
body {
  font-family: -apple-system, "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif;
  background: var(--bg);
  color: var(--text);
  overflow: hidden;
}
#app { display: flex; height: 100vh; height: 100dvh; } /* dvh：手机地址栏收起时不会把输入框顶出屏幕 */

/* ---------- 侧边栏 ---------- */
#sidebar {
  width: 264px; flex-shrink: 0;
  background: var(--panel);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  padding: 18px 14px;
  gap: 18px;
}
.logo { font-size: 19px; font-weight: 700; padding: 2px 8px; letter-spacing: .5px; display: flex; align-items: center; justify-content: space-between; }
/* 手机上侧栏是抽屉：抽屉里必须有个关得掉它的按钮，不然只能刷新页面 */
.sidebar-close {
  display: none;
  width: 32px; height: 32px; flex-shrink: 0;
  border: 1px solid var(--border); border-radius: 9px;
  background: var(--panel); color: var(--text-sub);
  font-size: 15px; line-height: 1; cursor: pointer;
  align-items: center; justify-content: center;
}
.sidebar-close:hover { background: #f2f4f8; color: var(--text); }
.sidebar-section { display: flex; flex-direction: column; gap: 8px; min-height: 0; }
.section-title {
  font-size: 12px; color: var(--text-sub); font-weight: 600;
  padding: 0 8px; letter-spacing: 1px;
}
#character-list, #session-list { display: flex; flex-direction: column; gap: 4px; overflow-y: auto; max-height: 260px; }
#session-list { max-height: 300px; }
.side-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border-radius: 10px; cursor: pointer;
  font-size: 14px; transition: background .15s;
  border: none; background: none; text-align: left; width: 100%;
  color: var(--text); font-family: inherit;
}
.side-item:hover { background: #f2f4f8; }
.side-item.active { background: var(--primary-soft); color: var(--primary); font-weight: 600; }
.side-item .avatar-sm { font-size: 20px; width: 26px; text-align: center; flex-shrink: 0; }
.side-item .name-sm { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-footer { margin-top: auto; display: flex; gap: 6px; }
.sidebar-footer .btn { flex: 1; padding: 9px 4px; font-size: 13px; }

/* ---------- 按钮 ---------- */
.btn {
  border: none; border-radius: 10px; cursor: pointer;
  font-size: 14px; font-family: inherit;
  padding: 9px 16px; transition: all .15s;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.btn-block { width: 100%; }
.btn-primary { background: var(--primary); color: #fff; }
.btn-primary:hover { background: #3f6ae6; }
.btn-primary:disabled { opacity: .5; cursor: not-allowed; }
.btn-light { background: #f2f4f8; color: var(--text); }
.btn-light:hover { background: #e6eaf1; }
.btn-ghost { background: transparent; color: var(--text-sub); }
.btn-ghost:hover { background: #f2f4f8; color: var(--text); }
.btn-danger { background: #fdebec; color: var(--danger); }
.btn-danger:hover { background: #fbdadd; }

/* ---------- 主区域 ---------- */
#main { flex: 1; display: flex; flex-direction: column; min-width: 0; min-height: 0; position: relative; }
/* 回到最新：翻历史时浮在输入框上方，不挡消息 */
.jump-bottom {
  position: absolute; right: 22px; bottom: 84px; z-index: 20;
  border: 1px solid var(--border); background: var(--panel); color: var(--primary);
  border-radius: 999px; padding: 7px 14px; font-size: 12.5px; font-family: inherit;
  cursor: pointer; box-shadow: 0 4px 14px rgba(20,30,60,.14);
}
.jump-bottom:hover { background: var(--primary-soft); }
#chat-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 22px; background: var(--panel); border-bottom: 1px solid var(--border);
}
.chat-header-left { display: flex; align-items: center; gap: 12px; }
.chat-avatar {
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--primary-soft); display: flex; align-items: center; justify-content: center;
  font-size: 22px;
}
.chat-name { font-weight: 700; font-size: 16px; }
.chat-status { font-size: 12px; color: var(--text-sub); }
.chat-header-actions { display: flex; gap: 4px; }

#chat-body {
  flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  /* 手机上滚动跟手的关键：浏览器可以跳过屏幕外那些气泡的排版与绘制 */
  content-visibility: auto;
  contain-intrinsic-size: auto 600px;
}
#empty-state {
  height: 100%; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 10px;
  color: var(--text-sub); text-align: center; padding: 20px;
}
.empty-icon { font-size: 52px; }
#empty-state h2 { color: var(--text); font-size: 20px; }
.empty-tip { font-size: 13px; background: var(--panel); padding: 10px 18px; border-radius: 10px; border: 1px dashed var(--border); }

#messages { width: 100%; margin: 0; padding: 24px 22px 12px; display: flex; flex-direction: column; gap: 16px; }
/* 离屏气泡不参与绘制：长对话（上千条）滚动时不再每帧重排整页。
   预留高度按"最普通的一条"（头像行 20 + 间隙 5 + 单行气泡 48 + 时间 15 + 列表间距 16 ≈ 104）取，
   估太大会让滚动条一路缩、估太小会跳；auto 关键字会在真渲染过一次后记住真实高度 */
#messages > .msg {
  content-visibility: auto;
  contain-intrinsic-size: auto 104px;
}
/* 纵向布局：头像移到气泡上方，气泡因此能贴到容器边框（左右对齐） */
.msg { display: flex; flex-direction: column; gap: 5px; }
.msg-head { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-sub); }
.msg.user .msg-head { flex-direction: row-reverse; }
.msg-head-avatar {
  width: 20px; height: 20px; border-radius: 50%; overflow: hidden; flex-shrink: 0;
  background: var(--primary-soft); display: flex; align-items: center; justify-content: center; font-size: 12px;
}
.msg.user .msg-head-avatar { background: #e9f7ef; }
.msg-head-name { font-weight: 500; }
.msg-avatar {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  background: var(--primary-soft); display: flex; align-items: center; justify-content: center; font-size: 17px;
}
.msg.user .msg-avatar { background: #e9f7ef; }
/* 气泡贴边框：AI 靠左顶格、用户靠右顶格；宽度仍按内容伸缩，不会撑满整行 */
.msg-body { max-width: 86%; min-width: 0; display: flex; flex-direction: column; }
.msg.ai .msg-body { align-self: flex-start; align-items: flex-start; }
.msg.user .msg-body { align-self: flex-end; align-items: flex-end; }
.msg-bubble {
  max-width: 100%; padding: 11px 15px; border-radius: 16px;
  font-size: 15px; line-height: 1.65; white-space: pre-wrap; word-break: break-word;
}
.msg.ai .msg-bubble { background: var(--panel); border: 1px solid var(--border); }
.msg.user .msg-bubble { background: var(--primary); color: #fff; }
/* 气泡正文：单独包一层，改了正文只换这里的节点，不会把旁边的图片/视频冲掉 */
.msg-text { display: inline; }
.msg-bubble .typing-cursor { display: inline-block; width: 2px; height: 16px; background: var(--primary); vertical-align: middle; animation: blink 1s infinite; margin-left: 2px; }
@keyframes blink { 50% { opacity: 0; } }
.msg-time { font-size: 11px; color: var(--text-sub); margin-top: 4px; }
.msg.user .msg-time { text-align: right; }

/* 喇叭：贴在时间后面，不抢眼；播的时候变成停止键并轻微跳动 */
.msg-tts {
  border: none; background: none; cursor: pointer; padding: 0 2px;
  font-size: 12px; line-height: 1; color: var(--text-sub);
  opacity: .55; transition: opacity .15s;
}
.msg-tts:hover { opacity: 1; }
.msg-tts.playing { opacity: 1; color: var(--primary); animation: tts-pulse .9s ease-in-out infinite; }
@keyframes tts-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.25); } }

/* 设置里「每个角色一个声音」 */
.tts-role {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  padding: 8px 0; border-bottom: 1px dashed var(--border);
}
.tts-role:last-child { border-bottom: none; }
.tts-role-name { min-width: 108px; font-size: 13.5px; }
.tts-role select { flex: 1; min-width: 150px; }
.tts-speed { width: 68px; flex: none; }
.tts-role .btn { padding: 4px 10px; font-size: 12.5px; }

/* 声音克隆：预置只有 8 个，不够就自己传一段 */
.tts-clone {
  margin: 10px 0 6px; padding: 12px 14px; border-radius: 12px;
  background: var(--primary-soft);
  border: 1px dashed var(--border);
}
.tts-clone-hint { margin: 0 0 10px; }
.tts-clone b { color: var(--text); }
.tts-clone .inline-row { margin: 6px 0; }
.tts-clone #tts-ref-file { font-size: 12.5px; max-width: 100%; }
.tts-custom-list:not(:empty) { margin-top: 10px; }
.tts-custom-row {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 0; border-top: 1px dashed var(--border);
}
.tts-custom-name { flex: 1; font-size: 13px; }
/* 气质标注：萝莉/御姐这类，比名字小一号、淡一点，一眼能扫到 */
.tts-custom-tag {
  margin-left: 6px; padding: 1px 6px; border-radius: 999px;
  font-size: 11px; font-weight: 400; color: var(--text-sub);
  background: var(--chip, rgba(127, 127, 127, 0.12));
  white-space: nowrap;
}
.tts-custom-row .btn { padding: 4px 10px; font-size: 12.5px; }

/* 撤回 / 引用：不再常驻按钮，长按或右键某一条气泡才弹菜单（微信式） */
.msg-menu {
  position: fixed; z-index: 120; min-width: 122px;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: 0 12px 32px rgba(28, 22, 40, .18);
  padding: 5px; display: flex; flex-direction: column; gap: 1px;
  animation: mm-in .12s ease-out;
}
@keyframes mm-in { from { opacity: 0; transform: translateY(4px); } }
.mm-item {
  display: flex; align-items: center; gap: 9px; width: 100%;
  border: 0; background: transparent; color: var(--text);
  font-family: inherit; font-size: 14px; line-height: 1;
  padding: 10px 12px; border-radius: 8px; cursor: pointer; text-align: left;
}
.mm-item:hover, .mm-item:active { background: var(--primary-soft); color: var(--primary); }
.mm-ico { width: 16px; text-align: center; font-size: 13px; color: var(--text-sub); }
.mm-item:hover .mm-ico { color: var(--primary); }
/* 菜单正在操作的那一条描个边，明确"就是这一句" */
.msg.menu-open .msg-bubble { box-shadow: 0 0 0 2px var(--primary); }
.msg.user.menu-open .msg-bubble { box-shadow: 0 0 0 2px rgba(255, 255, 255, .75), 0 0 0 4px var(--primary); }
/* 触屏：长按只弹菜单，不要顺手选中文字 / 冒出系统的拷贝气泡 */
@media (hover: none) {
  .msg-bubble { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
}

/* 「正在输入中」：微信同款三个点 */
.msg-typing { display: inline-flex; align-items: center; gap: 6px; }
.typing-label { font-size: 13px; color: var(--text-sub); }
.typing-dots { display: inline-flex; gap: 3px; }
.typing-dots i {
  width: 5px; height: 5px; border-radius: 50%; background: var(--text-sub);
  animation: typing-bounce 1.2s infinite;
}
.typing-dots i:nth-child(2) { animation-delay: .18s; }
.typing-dots i:nth-child(3) { animation-delay: .36s; }
@keyframes typing-bounce {
  0%, 60%, 100% { transform: translateY(0); opacity: .45; }
  30% { transform: translateY(-4px); opacity: 1; }
}
.header-typing i { font-style: normal; animation: dot-fade 1.2s infinite; }
.header-typing i:nth-child(2) { animation-delay: .18s; }
.header-typing i:nth-child(3) { animation-delay: .36s; }
@keyframes dot-fade { 0%, 100% { opacity: .3; } 50% { opacity: 1; } }

/* ---------- 朋友圈 ---------- */
#moments-view { flex: 1; display: flex; flex-direction: column; height: 100%; background: var(--bg); }
.moments-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 18px; border-bottom: 1px solid var(--border); background: var(--panel);
}
.moments-title { font-weight: 600; font-size: 15px; }
.moments-body { flex: 1; overflow-y: auto; padding: 16px 18px 40px; }
.load-older {
  text-align: center; font-size: 12.5px; color: var(--text-sub);
  padding: 10px; cursor: pointer; user-select: none; opacity: .85;
}
.load-older:hover { color: var(--primary); }
.moments-empty { text-align: center; color: var(--text-sub); font-size: 13px; padding: 60px 0; line-height: 1.8; }
.moment { display: flex; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--border); }
.moment-side { flex: none; }
.moment-avatar {
  width: 42px; height: 42px; border-radius: 10px; background: var(--bg);
  display: flex; align-items: center; justify-content: center; font-size: 22px;
  border: 1px solid var(--border);
}
.moment-main { flex: 1; min-width: 0; }
.moment-name { font-size: 13.5px; font-weight: 600; color: #4a6bb5; margin-bottom: 4px; }
.moment-text { font-size: 14px; line-height: 1.7; white-space: pre-wrap; word-break: break-word; }
.moment-foot { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.moment-time { font-size: 11.5px; color: var(--text-sub); }
.moment-acts { margin-left: auto; display: flex; gap: 6px; }
.moment-acts .btn { font-size: 11.5px; padding: 2px 8px; }
.moment-del { cursor: pointer; opacity: 0; font-size: 12px; transition: opacity .15s; }
.moment:hover .moment-del { opacity: .7; }
.moment-comments { margin-top: 6px; background: var(--bg); border-radius: 10px; padding: 8px 10px; }
.moment-comments:empty { display: none; }
.moment-comment { font-size: 12.5px; line-height: 1.7; color: var(--text); }
.moment-comment b { color: #4a6bb5; font-weight: 600; }
/* 她的朋友同事：颜色区分得出来，一看就不是你和她两个人在说话 */
.moment-comment.is-guest b { color: #a0619b; }
.moment-comment.is-me b { color: #2f8a6e; }
.mc-av { display: inline-block; width: 16px; text-align: center; margin-right: 4px; opacity: .9; }
.mc-reply { opacity: .7; font-size: 11.5px; }
/* 名字后面「（闺蜜）」这类关系提示，一眼看出这人是谁 */
.mc-rel { font-size: 11px; color: var(--text-sub); font-weight: 400; margin-left: 1px; }
.moment-likers .mc-rel { color: inherit; opacity: .75; }
.moment-likers { font-size: 11.5px; color: #b06fa0; margin-top: 6px; line-height: 1.6; }
.moment-likers:empty { display: none; }
.social-btn.loading { opacity: .6; }
/* 每条评论右侧的「↩ 回复」：点一下就把这条的说话人设成回复对象 */
.moment-comment { cursor: pointer; border-radius: 6px; }
.moment-comment:hover { background: rgba(0,0,0,.025); }
.mc-act {
  float: right; font-size: 11.5px; color: var(--text-sub); opacity: 0; padding: 0 4px;
  cursor: pointer; transition: opacity .15s;
}
.moment-comment:hover .mc-act { opacity: .8; }
/* 每条评论右侧的「✕ 删除」 */
.mc-del {
  float: right; font-size: 11px; color: var(--text-sub); opacity: 0; padding: 0 4px;
  cursor: pointer; transition: opacity .15s;
}
.moment-comment:hover .mc-del { opacity: .5; }
.mc-del:hover { opacity: 1; color: #c8553d; }
.moment-reply { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.reply-to { font-size: 11.5px; color: var(--text-sub); display: flex; align-items: center; gap: 5px; }
.reply-to b { color: #a0619b; font-weight: 600; }
.reply-to .rt-x { cursor: pointer; opacity: .6; padding: 0 3px; }
.reply-to .rt-x:hover { opacity: 1; }
.reply-line { display: flex; gap: 8px; }
.moment-reply input {
  flex: 1; padding: 7px 12px; border: 1px solid var(--border); border-radius: 10px;
  font-size: 13px; outline: none;
}
.moment-reply input:focus { border-color: var(--primary); }
#moment-character { width: 100%; padding: 8px 12px; border: 1px solid var(--border); border-radius: 10px; font-size: 13px; }

/* ---------- 输入区 ---------- */
/* 脚本没更新到新版时的顶部提示 */
.build-tip {
  position: fixed; top: 8px; left: 8px; right: 8px; z-index: 300;
  display: flex; align-items: center; gap: 8px; flex-wrap: nowrap;
  max-width: 560px; margin: 0 auto;
  background: #fff7e6; border: 1px solid #ffd591; color: #7a4b00;
  font-size: 12.5px; padding: 8px 12px; border-radius: 10px;
  box-shadow: 0 4px 14px rgba(20,30,60,.12);
}
/* 手机上宽度不够时，让文字换行，按钮保持一整块，不许挤成竖排 */
.build-tip > span { flex: 1 1 auto; min-width: 0; line-height: 1.45; word-break: break-word; }
.build-tip button {
  flex: 0 0 auto; white-space: nowrap;
  border: none; background: #ffeccc; color: #7a4b00; font-family: inherit;
  font-size: 12.5px; padding: 4px 10px; border-radius: 8px; cursor: pointer;
}
.build-tip button:hover { background: #ffe0ad; }
.build-tip #btn-tip-close { background: none; padding: 2px 4px; }
/* 提示条出现时把整个界面往下让，避免盖住顶部的角色名和按钮 */
body.has-build-tip #app { padding-top: 54px; }

/* 输入栏的引用入口 */
.btn-quote-entry { flex: 0 0 auto; font-size: 12px; padding: 6px 10px; white-space: nowrap; align-self: flex-end; }

/* 引用选择器：从最近消息里挑一条 */
#quote-picker { position: fixed; inset: 0; background: rgba(0,0,0,.35); display: flex; align-items: center; justify-content: center; z-index: 60; }
#quote-picker .qp-box { width: min(520px, 92vw); max-height: 70vh; background: var(--panel); border-radius: 12px; display: flex; flex-direction: column; overflow: hidden; box-shadow: 0 10px 40px rgba(0,0,0,.25); }
#quote-picker .qp-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px; border-bottom: 1px solid var(--border); font-weight: 600; }
#quote-picker .qp-close { background: none; border: none; cursor: pointer; font-size: 16px; color: var(--text-sub); }
#quote-picker .qp-list { overflow-y: auto; padding: 6px; }
#quote-picker .qp-item { padding: 8px 10px; border-radius: 8px; cursor: pointer; }
#quote-picker .qp-item:hover { background: #f2f4f7; }
#quote-picker .qp-item-head { display: flex; gap: 8px; align-items: baseline; font-size: 12px; color: var(--text-sub); }
#quote-picker .qp-item-who { font-weight: 600; color: var(--text); }
#quote-picker .qp-item-text { margin-top: 3px; font-size: 13px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* 轻提示 */
.toast {
  position: fixed; left: 50%; bottom: 108px; transform: translateX(-50%);
  z-index: 200; max-width: 80vw;
  background: rgba(43, 47, 54, .94); color: #fff; font-size: 13px;
  padding: 9px 16px; border-radius: 999px; box-shadow: 0 6px 18px rgba(20,30,60,.2);
}

/* 点引用条跳回去时被引用那条闪一下 */
.msg.quote-flash .msg-bubble { box-shadow: 0 0 0 2px var(--primary); }

/* 引用条：输入框上方那一小条 */
#quote-bar {
  cursor: pointer;
  display: flex; align-items: center; gap: 8px;
  margin: 0 22px; padding: 8px 12px;
  background: var(--primary-soft); border: 1px solid #dbe5ff;
  border-radius: 10px 10px 0 0; font-size: 12.5px; color: var(--text-sub);
  max-width: 100%;
}
.quote-bar-label { color: var(--primary); font-weight: 600; flex-shrink: 0; }
.quote-bar-who { color: var(--text); font-weight: 600; flex-shrink: 0; }
.quote-bar-text {
  flex: 1; min-width: 0; color: var(--text-sub);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.quote-bar-close {
  flex-shrink: 0; border: none; background: none; cursor: pointer;
  color: var(--text-sub); font-size: 15px; font-family: inherit; line-height: 1;
  /* 手机上 13px 的字加 2px 内边距，实际可点区域只有十几像素，基本点不中——
     看着像「点了没反应」。给足 28px 的热区，再用负外边距把视觉位置拉回原处。 */
  min-width: 28px; min-height: 28px; padding: 4px 6px; margin: -4px -6px -4px 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 8px; touch-action: manipulation;
}
.quote-bar-close:hover { color: var(--danger); }
/* 气泡上方的引用块 */
.msg-quote {
  display: flex; align-items: baseline; gap: 6px; max-width: 86%;
  margin-bottom: 4px; padding: 5px 10px;
  border-left: 2px solid var(--primary); border-radius: 6px;
  background: #f2f4f9; font-size: 12px; color: var(--text-sub); line-height: 1.4;
}
.msg-quote .q-mark { color: var(--primary); }
.msg-quote .q-who { font-weight: 600; color: var(--text); flex-shrink: 0; }
.msg-quote .q-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

#input-bar {
  display: flex; gap: 10px; align-items: flex-end;
  width: 100%; margin: 0;
  padding: 14px 22px 18px;
}
#input {
  flex: 1; resize: none; border: 1px solid var(--border); border-radius: 14px;
  padding: 12px 16px; font-size: 15px; font-family: inherit; line-height: 1.5;
  background: var(--panel); outline: none; max-height: 140px;
  transition: border-color .15s;
}
#input:focus { border-color: var(--primary); }
#btn-send { padding: 12px 22px; }

/* ---------- 弹窗 ---------- */
.modal-mask {
  position: fixed; inset: 0; background: rgba(30,35,45,.4);
  display: flex; align-items: center; justify-content: center; z-index: 100;
  /* 全屏毛玻璃在老手机（尤其 iPhone Safari）上是逐帧重算的，开一次就要几百毫秒，
     关掉只靠半透明遮罩，视觉几乎看不出差别，但打开/关闭弹窗会跟手很多 */
}
.modal {
  background: var(--panel); border-radius: 18px; width: min(560px, 92vw);
  max-height: 88vh; display: flex; flex-direction: column;
  box-shadow: 0 20px 60px rgba(0,0,0,.15);
  animation: pop .2s ease;
}
@keyframes pop { from { transform: scale(.96); opacity: 0; } to { transform: scale(1); opacity: 1; } }
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 18px 22px 0; }
.modal-head h3 { font-size: 17px; }
.modal-body { padding: 16px 22px; overflow-y: auto; display: flex; flex-direction: column; gap: 14px; }
.modal-foot { display: flex; justify-content: flex-end; gap: 10px; padding: 0 22px 20px; }

.form-row { display: flex; flex-direction: column; gap: 6px; }
.form-row label { font-size: 13px; font-weight: 600; color: var(--text); }
.req { color: var(--danger); }
.form-row input, .form-row textarea, .form-row select {
  border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px;
  font-size: 14px; font-family: inherit; outline: none; background: var(--bg);
  transition: border-color .15s; resize: vertical;
}
.form-row input:focus, .form-row textarea:focus, .form-row select:focus { border-color: var(--primary); }
.hint { font-size: 12px; color: var(--text-sub); line-height: 1.5; }
/* 滑杆下方的档位说明：一眼看懂每一段对应什么状态 */
.bands { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }
.band {
  padding: 3px 9px; border-radius: 8px; font-size: 11.5px; line-height: 1.5;
  background: var(--bg); border: 1px solid var(--border); color: var(--text-sub);
  white-space: nowrap;
}
.form-row .hint + .bands { margin-top: -2px; }
.emoji-picker { display: flex; gap: 6px; flex-wrap: wrap; }
.emoji-picker button {
  width: 36px; height: 36px; border-radius: 10px; border: 1px solid transparent;
  background: var(--bg); font-size: 19px; cursor: pointer;
}
.emoji-picker button.selected { border-color: var(--primary); background: var(--primary-soft); }
.preset-row { display: flex; gap: 6px; flex-wrap: wrap; }
.preset-row button {
  border: 1px solid var(--border); background: var(--bg); border-radius: 8px;
  padding: 4px 10px; font-size: 12px; cursor: pointer; color: var(--text-sub); font-family: inherit;
}
.preset-row button:hover { border-color: var(--primary); color: var(--primary); }

/* 记忆 */
.memory-add { display: flex; gap: 8px; }
.memory-add input {
  flex: 1; border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px;
  font-size: 13px; font-family: inherit; outline: none; background: var(--bg);
}
.memory-item {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  background: var(--bg); border-radius: 10px; padding: 10px 12px; font-size: 13px;
  margin-top: 8px; line-height: 1.5;
}
.memory-item .del { color: var(--text-sub); cursor: pointer; border: none; background: none; font-size: 13px; flex-shrink: 0; }
.memory-item .del:hover { color: var(--danger); }

/* 记忆卡：她自己滚出来的那份，能看能改 */
.mem-block {
  display: flex; flex-direction: column; gap: 8px;
  border: 1px solid var(--border); border-radius: 12px; padding: 13px 14px; background: var(--panel);
}
.mem-block b { font-size: 14px; }
.mem-block-head { display: flex; align-items: center; gap: 8px; }
.mem-block-head b { flex: 1; }
.mem-block .form-row { gap: 4px; }
.mem-block .form-row label { font-size: 12px; color: var(--text-sub); }
.mem-block textarea { font-size: 13px; line-height: 1.55; padding: 8px 10px; }
.pin-item { border-left: 3px solid var(--primary); }
.pin-item .pin-text { flex: 1; cursor: pointer; }
.pin-item .pin-text:hover { color: var(--primary); }

/* 她主动发起的消息：名字旁一个小标记 */
.pro-tag {
  font-size: 11px; color: var(--primary); background: var(--primary-soft);
  border: 1px solid #dbe6ff; border-radius: 999px; padding: 0 8px; line-height: 1.6;
}
/* 设置弹窗：开关行 / 小输入框 */
.check-row { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 400; color: var(--text); cursor: pointer; }
.check-row input { width: 16px; height: 16px; accent-color: var(--primary); }
.inline-row { display: flex; align-items: center; gap: 6px; }
.mini-input { width: 72px !important; flex-shrink: 0; }

/* 滚动条 */
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-thumb { background: #d8dde6; border-radius: 4px; }
::-webkit-scrollbar-track { background: transparent; }

/* 情绪与状态选择 */
.chip-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.chip-group-label {
  width: 100%; font-size: 12px; font-weight: 600; color: var(--text-sub);
  margin: 6px 0 -2px; letter-spacing: .5px;
}
.chip-group-label:first-child { margin-top: 0; }
.chip { padding: 6px 14px; border-radius: 999px; border: 1px solid var(--border); background: var(--panel); color: var(--text); font-size: 13px; cursor: pointer; transition: all .15s; }
.chip:hover { border-color: var(--primary); color: var(--primary); }
.chip.selected { background: var(--primary); border-color: var(--primary); color: #fff; }
.chip-add { display: flex; gap: 8px; margin-top: 10px; }
.chip-add input { flex: 1; padding: 8px 12px; border: 1px solid var(--border); border-radius: 10px; font-size: 13px; outline: none; }
.chip-add input:focus { border-color: var(--primary); }
.chip-search { width: 100%; box-sizing: border-box; padding: 7px 12px; border: 1px solid var(--border); border-radius: 10px; font-size: 12.5px; outline: none; margin-bottom: 8px; background: var(--panel); color: var(--text); }
.chip-search:focus { border-color: var(--primary); }
.chip-empty { font-size: 12.5px; color: var(--text-sub); padding: 4px 2px; }
.row-tip { font-size: 11.5px; color: var(--text-sub); font-weight: normal; }
.cast-list { display: flex; flex-direction: column; gap: 8px; margin-top: 2px; }
.cast-item {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 8px 12px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--panel); transition: all .15s; user-select: none;
}
.cast-item:hover { border-color: var(--primary); color: var(--primary); }
.cast-item.checked { border-color: var(--primary); background: var(--primary-soft, var(--panel)); }
.cast-item input { width: 16px; height: 16px; accent-color: var(--primary); cursor: pointer; margin: 0; flex: none; }
.cast-item .cast-av { font-size: 18px; flex: none; }
.cast-item .cast-name { font-size: 13.5px; flex: 1; }
.cast-item .cast-rel { font-size: 11.5px; color: var(--text-sub); flex: none; }
/* 编辑弹窗里的「人设卡」：系统从设定翻译出来的演出清单 */
/* 「用我的设定生成」：贴设定的框要够高，一行字太窄看不清自己在写什么；
   预览沿用 .persona-card 的外观，只把高度放宽一点（生成的卡比手改的短，但要能滚完） */
#brief-text { min-height: 190px; line-height: 1.75; }
#brief-preview { max-height: 320px; }
#brief-result-tip { margin-left: 6px; }
/* 三个小按钮挤在 label 的 float 里，窄屏会跟标题叠在一起——改成两头对齐的 flex，换行也不会掉 */
#persona-card-label {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; flex-wrap: wrap;
}
.pc-tools { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.btn-re-read { float: none; font-size: 11.5px; padding: 2px 8px; }
.persona-card {
  margin-top: 6px; padding: 8px 10px; border-radius: 10px; background: var(--bg);
  font-size: 12px; line-height: 1.75; color: var(--text); max-height: 220px; overflow: auto;
}
.persona-card .pc-row { display: flex; gap: 6px; }
.persona-card .pc-k { flex: 0 0 76px; color: var(--text-sub); }
.persona-card .pc-v { flex: 1; }
.persona-card .pc-empty { color: var(--text-sub); font-size: 11.5px; }
/* 手改过 / 设定超长的提示条 */
.persona-card .pc-manual {
  margin-bottom: 6px; padding: 6px 8px; border-radius: 8px;
  background: #fff7e6; color: #8a6a1f; font-size: 11.5px; line-height: 1.6;
}
/* 「你删掉的 N 条已经记住了」：和上面那条区分开，用冷色 */
.persona-card .pc-dropped {
  margin-bottom: 6px; padding: 6px 8px; border-radius: 8px;
  background: #eef4ff; color: #3b5b8c; font-size: 11.5px; line-height: 1.6;
}
.persona-card .pc-edit-note {
  margin: 0 0 8px; padding: 6px 8px; border-radius: 8px;
  background: #eef4ff; color: #3b5b8c; font-size: 11.5px; line-height: 1.6;
}
/* 编辑态：一行一个输入框，改完直接存 */
.persona-card .pc-edit { display: flex; flex-direction: column; }
.persona-card .pc-edit label { font-size: 11.5px; color: var(--text-sub); margin: 8px 0 3px; }
.persona-card .pc-edit label:first-child { margin-top: 0; }
.persona-card .pc-edit label small { font-weight: 400; opacity: .8; margin-left: 4px; }
.persona-card .pc-edit input,
.persona-card .pc-edit textarea {
  width: 100%; box-sizing: border-box; padding: 6px 8px; border-radius: 8px;
  border: 1px solid var(--border); background: #fff; color: var(--text);
  font-size: 16px; font-family: inherit; line-height: 1.6; resize: vertical;
}
.persona-card .pc-edit-foot {
  display: flex; gap: 8px; align-items: center; margin: 0 0 10px;
  position: sticky; top: 0; z-index: 2; background: var(--bg); padding: 4px 0 8px;
}
.persona-card .pc-edit-hint { flex: 1; font-size: 11px; color: var(--text-sub); line-height: 1.5; }

/* ---------- 列表项操作按钮（编辑 / 删除） ---------- */
.side-item .name-sm { flex: 1; min-width: 0; }
.side-item .item-edit,
.side-item .item-del {
  flex-shrink: 0; font-size: 13px; line-height: 1;
  padding: 3px 5px; border-radius: 6px; color: var(--text-sub);
  opacity: 0; transition: opacity .15s, background .15s;
}
.side-item .item-ops { display: flex; gap: 2px; flex-shrink: 0; }
.side-item:hover .item-edit,
.side-item:hover .item-del,
.side-item:hover .item-ops .item-edit,
.side-item:hover .item-ops .item-del { opacity: 1; }
.side-item .item-edit:hover { background: var(--primary-soft); color: var(--primary); }
.side-item .item-del:hover { background: #fdecec; color: var(--danger); }
@media (hover: none) {
  .side-item .item-edit, .side-item .item-del { opacity: .6; }
}

/* ---------- 头像（图片 / emoji） ---------- */
.avatar-img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block; }
.side-item .avatar-sm { width: 26px; height: 26px; display: flex; align-items: center; justify-content: center; }
.avatar-edit { display: flex; gap: 14px; align-items: flex-start; }
.avatar-preview {
  width: 64px; height: 64px; flex-shrink: 0; border-radius: 50%;
  background: var(--primary-soft); display: flex; align-items: center; justify-content: center;
  font-size: 30px; overflow: hidden; border: 1px solid var(--border);
}
.avatar-edit-actions { flex: 1; display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.avatar-edit-actions .hint { margin-top: 4px; }
.avatar-edit-actions input { width: 100%; padding: 7px 10px; border: 1px solid var(--border); border-radius: 9px; font-size: 13px; outline: none; }
.avatar-edit-actions input:focus { border-color: var(--primary); }

/* ---------- 设置弹窗：手机访问 / 备份 ---------- */
.sep { border: none; border-top: 1px solid var(--border); margin: 4px 0; }
.btn-row { display: flex; gap: 8px; flex-wrap: wrap; }
.lan-list { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.lan-item {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  background: var(--bg); border: 1px solid var(--border); border-radius: 9px; padding: 6px 6px 6px 12px;
}
.lan-item code { font-size: 13px; color: var(--primary); word-break: break-all; }

/* ---------- 搜索 ---------- */
.search-input {
  width: 100%; padding: 8px 11px; border: 1px solid var(--border);
  border-radius: 10px; font-size: 13px; outline: none; font-family: inherit;
}
.search-input:focus { border-color: var(--primary); }
#search-results { display: flex; flex-direction: column; gap: 4px; max-height: 260px; overflow-y: auto; }
.search-item {
  padding: 8px 10px; border-radius: 9px; cursor: pointer; background: var(--bg);
  border: 1px solid transparent;
}
.search-item:hover { border-color: var(--primary); background: var(--primary-soft); }
.search-meta { font-size: 11px; color: var(--text-sub); margin-bottom: 3px; }
.search-snippet { font-size: 13px; line-height: 1.45; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.search-empty { padding: 10px; text-align: center; }

/* ---------- 移动端：侧边栏抽屉 ---------- */
.sidebar-toggle {
  display: none; position: absolute; top: 10px; left: 10px; z-index: 30;
  width: 36px; height: 36px; border-radius: 10px; border: 1px solid var(--border);
  background: var(--panel); color: var(--text); font-size: 16px; cursor: pointer;
}
@media (max-width: 720px) {
  .sidebar-toggle { display: block; }
  #sidebar {
    position: fixed; left: 0; top: 0; bottom: 0; z-index: 40;
    width: 250px; transform: translateX(-100%);
    transition: transform .22s ease; box-shadow: 2px 0 16px rgba(0,0,0,.12);
  }
  #app.sidebar-open #sidebar { transform: translateX(0); }
  #app.sidebar-open #main::after {
    content: ''; position: absolute; inset: 0; background: rgba(0,0,0,.28); z-index: 35;
    pointer-events: none; /* 遮挡层只负责变暗，点击由 JS 在 #main 上兜住 */
  }
  .sidebar-close { display: inline-flex; }
  #main { position: relative; }
  #chat-header { padding-left: 54px !important; }
  .msg-body { max-width: 94%; }
  .chat-header-actions { gap: 4px; }
  .chat-header-actions .btn { padding: 6px 8px; font-size: 12px; }
  .modal { width: 94vw !important; max-height: 88vh; }
  /* 手机上弹窗不做缩放动画：动画期间浏览器要反复重排整屏，开弹窗会明显顿一下 */
  .modal { animation: none; box-shadow: 0 8px 28px rgba(0,0,0,.14); }
  /* 侧栏滑入滑出是最常触发的动画之一：只动 transform，并让它独占合成层 */
  #sidebar { will-change: transform; }
}

/* 头像容器支持图片：图片铺满圆形，emoji 保持原样居中 */
.chat-avatar, .msg-avatar { overflow: hidden; }
.chat-avatar > .avatar-img, .msg-avatar > .avatar-img { background: #fff; }

/* ---------- 情绪显示：头部徽章 + 温度 ---------- */
.chat-status { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.status-dot {
  width: 7px; height: 7px; border-radius: 50%; background: #22c55e; flex-shrink: 0;
  box-shadow: 0 0 0 3px rgba(34,197,94,.16);
}
.emo-badge {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 2px 9px; border-radius: 999px; font-size: 12px; line-height: 1.6;
  background: var(--primary-soft); color: var(--primary); border: 1px solid #dbe6ff;
}
.status-meta { font-size: 12px; color: var(--text-sub); }
/* 亲密举动：单独一行，和情绪/状态区分开 */
#chat-status .status-actions { display: inline-flex; align-items: center; gap: 5px; flex-wrap: wrap; }
#chat-status .status-actions .emo-badge {
  background: #fff1f5; color: #d1477a; border: 1px solid #ffd6e3;
}
/* 状态栏情绪徽章可点击调整 */
.chat-status.clickable { cursor: pointer; border-radius: 8px; padding: 3px 6px; margin-left: -6px; transition: background .15s; }
.chat-status.clickable:hover { background: var(--primary-soft); }
.memory-text { cursor: pointer; flex: 1; }
.memory-text:hover { color: var(--primary); text-decoration: underline dotted; }

/* ---------- 访问口令门禁 ---------- */
#access-gate {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  background: linear-gradient(160deg, #f7f5ff 0%, #eef3ff 55%, #fdf2f7 100%);
  padding: 20px;
}
.gate-card {
  width: 100%; max-width: 380px; background: var(--panel);
  border: 1px solid var(--border); border-radius: 18px;
  padding: 30px 26px 26px; text-align: center;
  box-shadow: 0 12px 40px rgba(60, 60, 120, .12);
}
.gate-logo { font-size: 42px; margin-bottom: 6px; }
.gate-card h2 { font-size: 19px; margin: 0 0 10px; font-weight: 600; }
.gate-tip { font-size: 13px; color: var(--text-sub); line-height: 1.65; margin: 0 0 18px; text-align: left; }
#access-input {
  width: 100%; padding: 11px 14px; border: 1px solid var(--border);
  border-radius: 11px; font-size: 15px; outline: none; text-align: center;
  font-family: inherit; letter-spacing: 2px;
}
#access-input:focus { border-color: var(--primary); }
.gate-error { min-height: 20px; font-size: 13px; color: var(--danger); margin-top: 8px; }
/* 输口令这一页的「拉最新版」：口令页面最容易被缓存卡住，这个入口无论如何都得看得见 */
.gate-update { margin-top: 14px; font-size: 13px; color: var(--text-sub); }
.gate-update:hover { color: var(--primary); border-color: var(--primary); }

/* 括号内的动作/神态描写：浅色斜体，与台词区分开 */
.act-desc { color: var(--text-sub); font-style: italic; }
.msg.ai .msg-bubble .act-desc { opacity: .82; }
/* 你这边是紫底白字：台词实白、描写用半透明白，深浅差一档，和 TA 那侧是同一种层次关系 */
.msg.user .msg-bubble .act-desc { color: rgba(255, 255, 255, .74); opacity: 1; }

/* 选项变多后：情绪/身体/举动区域各自独立滚动，下面的滑杆始终可见 */
#emotion-grid { max-height: 220px; overflow-y: auto; padding-right: 2px; }
#body-grid { max-height: 160px; overflow-y: auto; padding-right: 2px; }
#action-grid { max-height: 220px; overflow-y: auto; padding-right: 2px; }

/* ---------- 群聊 ---------- */
#group-list { display: flex; flex-direction: column; gap: 6px; }
.grp-item {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; border-radius: 10px; cursor: pointer;
  border: 1px solid transparent;
}
.grp-item:hover { background: var(--bg); }
.grp-item.active { background: var(--primary-soft); border-color: var(--primary); }
.grp-av { display: flex; flex: none; }
.grp-av span { font-size: 17px; margin-left: -6px; }
.grp-av span:first-child { margin-left: 0; }
.grp-av img { width: 20px; height: 20px; border-radius: 50%; object-fit: cover; margin-left: -6px; border: 1.5px solid var(--panel); }
.grp-av img:first-child { margin-left: 0; }
.grp-name { flex: 1; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.grp-count { font-size: 11px; color: var(--text-sub); flex: none; }
.grp-item.empty-tip { cursor: default; color: var(--text-sub); font-size: 12.5px; background: none; }
/* 群聊头部：几个人的头像叠在一起 */
.chat-avatar-stack { display: flex; flex: none; }
.chat-avatar-stack span { font-size: 20px; margin-left: -9px; }
.chat-avatar-stack span:first-child { margin-left: 0; }
.chat-avatar-stack img { width: 34px; height: 34px; border-radius: 50%; object-fit: cover; margin-left: -9px; border: 2px solid var(--panel); }
.chat-avatar-stack img:first-child { margin-left: 0; }
/* 群里不同成员的气泡：跟 MeVelody 的单人气泡区分开 */
.msg.ai.msg-member .msg-head-name { color: var(--primary); }
.grp-status-item { display: inline-flex; align-items: center; gap: 4px; margin-right: 8px; }
.grp-status-item .grp-status-name { font-weight: 600; color: var(--text); }
/* 群设置弹窗：成员 / 关系两个页签 */
.modal-wide { max-width: 620px !important; }
.grp-tabs { display: flex; gap: 8px; margin-bottom: 14px; }
.grp-tab {
  flex: 1; padding: 9px 10px; border-radius: 10px; cursor: pointer;
  border: 1px solid var(--border); background: var(--panel);
  font-size: 13.5px; font-family: inherit; color: var(--text-sub);
}
.grp-tab.active { border-color: var(--primary); color: var(--primary); background: var(--primary-soft); font-weight: 600; }
.rel-hint { line-height: 1.7; margin-bottom: 12px; }
/* 关系卡片：一对人一张 */
.rel-card { border: 1px solid var(--border); border-radius: 12px; padding: 12px; margin-bottom: 10px; background: var(--panel); }
.rel-pair { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.rel-pair .rel-av { font-size: 22px; }
.rel-pair .rel-names { flex: 1; font-size: 14px; font-weight: 600; }
.rel-pair .rel-names small { font-weight: 400; color: var(--text-sub); font-size: 11.5px; display: block; }
/* 三十几种关系挑花眼时的骰子：懒得翻就让她替你抽一种 */
.rel-pair .rel-dice {
  flex: none; width: 30px; height: 30px; line-height: 1; font-size: 15px; cursor: pointer;
  border: 1px solid var(--border); border-radius: 9px; background: var(--panel); color: var(--text);
  transition: background .15s, transform .15s;
}
.rel-pair .rel-dice:hover { background: var(--hover); transform: rotate(18deg); }
.rel-chip-sel { padding: 7px 9px; border: 1px solid var(--border); border-radius: 9px; font-size: 13px; font-family: inherit; background: var(--panel); color: var(--text); }
.rel-row { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.rel-row label { font-size: 12.5px; color: var(--text-sub); flex: none; }
.rel-row input[type=range] { flex: 1; accent-color: var(--primary); }
.rel-close-val { font-size: 12.5px; color: var(--primary); font-weight: 600; width: 62px; text-align: right; flex: none; }
.rel-note { width: 100%; margin-top: 8px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 9px; font-size: 13px; font-family: inherit; outline: none; color: var(--text); background: var(--panel); }
.rel-note:focus { border-color: var(--primary); }
/* @ 点名选择器 */
#at-picker {
  position: absolute; left: 12px; right: 12px; bottom: 72px; z-index: 40;
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 10px 30px rgba(40,50,80,.12); max-width: 560px; margin: 0 auto;
}
@media (max-width: 720px) {
  .rel-card { padding: 10px; }
  .grp-tabs { flex-direction: column; }
}

/* ---------- 表情包 ---------- */
/* 选表情的面板：和 @ 点名、引用选择器一样贴在输入框上方 */
#sticker-picker {
  position: absolute; left: 12px; right: 12px; bottom: 72px; z-index: 41;
  background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 10px 30px rgba(40,50,80,.14); max-width: 560px; margin: 0 auto;
  max-height: 46vh; display: flex; flex-direction: column; overflow: hidden;
}
.sk-head { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--border); }
.sk-title { font-weight: 600; font-size: 14px; }
.sk-sub { flex: 1; font-size: 12px; color: var(--text-sub); }
.sk-close { background: none; border: none; cursor: pointer; font-size: 15px; color: var(--text-sub); }
.sk-grid { display: flex; flex-direction: column; gap: 4px; padding: 8px 12px 12px; overflow-y: auto; }
.sk-group { display: flex; flex-direction: column; gap: 6px; }
.sk-group + .sk-group { margin-top: 6px; }
.sk-group-head {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--text-sub); font-weight: 600;
  position: sticky; top: 0; background: var(--panel); padding: 4px 0; z-index: 1;
}
.sk-group-head em { font-style: normal; font-weight: 400; font-size: 11px; color: var(--text-sub); opacity: .7; }
.sk-group-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: 8px; }
.sk-item {
  width: 100%; aspect-ratio: 1 / 1; padding: 4px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: 10px; background: var(--panel);
}
.sk-item:hover { background: #f2f4f7; }
.sk-item img { max-width: 100%; max-height: 100%; object-fit: contain; }
.sk-emoji { font-size: 28px; line-height: 1; }
.sk-empty { padding: 12px; font-size: 13px; color: var(--text-sub); }

/* 聊天里的一张表情包：不套气泡底色和内边距，图自己撑满 */
.msg-sticker { display: inline-flex; align-items: center; justify-content: center; }
.msg-sticker-img { max-width: 132px; max-height: 132px; border-radius: 10px; display: block; }
.msg-sticker-emoji { font-size: 54px; line-height: 1.05; display: block; }
.msg-bubble.sticker-only { background: transparent; border: none; box-shadow: none; padding: 0; }

/* 设置里的导入区：先选图、逐张归心情，再一次性入库 */
.sk-import { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.sk-pick { cursor: pointer; }
.sk-stage {
  border: 1px dashed var(--border); border-radius: 10px; padding: 8px 10px;
  display: flex; flex-direction: column; gap: 8px; max-height: 320px; overflow-y: auto;
}
.sk-stage-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.sk-stage-list { display: flex; flex-direction: column; gap: 6px; }
.sk-stage-item { display: flex; align-items: center; gap: 8px; }
.sk-stage-item img { width: 42px; height: 42px; object-fit: contain; border: 1px solid var(--border); border-radius: 8px; background: var(--panel); flex: none; }
.sk-stage-name { flex: 1; font-size: 12px; color: var(--text-sub); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sk-stage-tag { width: 92px; flex: none; }
.sk-stage-item .sk-del { position: static; flex: none; }

/* 设置里的表情包列表：一行一个心情，右边一排缩略图 */
.sticker-mine { display: flex; flex-direction: column; gap: 10px; margin-top: 8px; }
.sk-mine-row { display: flex; gap: 10px; align-items: flex-start; }
.sk-mine-tag { width: 56px; flex: none; font-size: 12px; color: var(--text-sub); padding-top: 6px; }
.sk-mine-tag em { font-style: normal; margin-left: 3px; opacity: .65; }
.sk-mine-list { display: flex; flex-wrap: wrap; gap: 8px; flex: 1; }
.sk-mine-item { position: relative; width: 64px; display: flex; flex-direction: column; align-items: center; gap: 2px; }
.sk-mine-item img { width: 56px; height: 56px; object-fit: contain; border: 1px solid var(--border); border-radius: 8px; background: var(--panel); }
.sk-mine-item em { font-style: normal; font-size: 11px; color: var(--text-sub); }
.sk-del {
  position: absolute; top: -6px; right: 2px; width: 18px; height: 18px; border-radius: 50%;
  background: rgba(0,0,0,.55); color: #fff; font-size: 11px; line-height: 18px; text-align: center; cursor: pointer;
}

/* ---------- 聊天里的图片 ---------- */
/* 待发送的图片：输入框上面一排缩略图 */
.attach-bar {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 8px 12px; border-top: 1px solid var(--border); background: var(--panel-2, var(--panel));
}
.attach-item { position: relative; width: 62px; height: 62px; }
.attach-item img { width: 100%; height: 100%; object-fit: cover; border-radius: 8px; border: 1px solid var(--border); }
.attach-del {
  position: absolute; top: -6px; right: -6px; width: 20px; height: 20px; border-radius: 50%;
  border: none; background: rgba(0,0,0,.6); color: #fff; font-size: 12px; line-height: 1;
  cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.attach-del:hover { background: rgba(0,0,0,.8); }
/* 气泡里的图：单独一张撑到 220px，多张排九宫格式的方图 */
.msg-images { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.msg-images.multi { display: grid; grid-template-columns: repeat(3, 1fr); }
.msg-image {
  display: block; max-width: 220px; max-height: 280px; width: auto; height: auto;
  border-radius: 10px; cursor: zoom-in; object-fit: cover; background: rgba(0,0,0,.04);
}
.msg-images.multi .msg-image { width: 100%; max-width: none; height: 88px; }
.msg-bubble:has(.msg-images:empty) { padding-bottom: 0; }
/* 没有文字只有图的气泡：别留一圈多余的留白 */
.msg-bubble > .msg-images:first-child { margin-top: 0; }
/* 看大图 */
.lightbox {
  position: fixed; inset: 0; z-index: 999; background: rgba(0,0,0,.86);
  align-items: center; justify-content: center; cursor: zoom-out;
}
.lightbox img { max-width: 92vw; max-height: 92vh; border-radius: 8px; }
.lightbox-close {
  position: absolute; top: 18px; right: 20px; width: 36px; height: 36px; border-radius: 50%;
  border: none; background: rgba(255,255,255,.18); color: #fff; font-size: 18px; cursor: pointer;
}
@media (max-width: 720px) {
  .msg-image { max-width: 200px; }
  .msg-images.multi .msg-image { height: 74px; }
}
.msg-bubble.img-only { padding: 4px; }

/* ---------- 视频 ---------- */
/* 待发送的视频：缩略图 + 时长角标 */
.attach-video { position: relative; }
.attach-video-play {
  position: absolute; left: 4px; bottom: 4px; padding: 1px 5px; border-radius: 6px;
  background: rgba(0,0,0,.55); color: #fff; font-size: 11px; line-height: 1.5;
}
.attach-video-empty {
  width: 100%; height: 100%; border-radius: 8px; border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center; font-size: 22px; background: rgba(0,0,0,.05);
}
/* 气泡里的视频：默认只放封面，点开才在灯箱里播放（省流量，也避免一屏好几个视频同时加载） */
.msg-video {
  position: relative; display: inline-block; max-width: 240px; border-radius: 10px;
  overflow: hidden; cursor: pointer; background: #000;
}
.msg-video-el { display: block; width: 100%; max-height: 300px; object-fit: cover; }
.msg-video-play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  width: 44px; height: 44px; border-radius: 50%; background: rgba(0,0,0,.5); color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 16px; padding-left: 3px;
}
.msg-bubble > .msg-video:first-child { margin-top: 0; }
#lightbox-video { max-width: 92vw; max-height: 92vh; border-radius: 8px; background: #000; }
/* 🖼 用 label 包着隐藏的 file input：点一下就直接弹选择器，移动端也不会卡在 onclick 里 */
.btn-media { cursor: pointer; display: inline-flex; align-items: center; }

/* ---------- 一句话长成人（长在角色表单里，不单独开门） ---------- */
/* 虚线框把它和下面正式的几栏分开：这里只是「起草」，填进去还没保存 */
.forge-inline {
  padding: 12px 14px; border: 1px dashed var(--border); border-radius: 14px;
  background: var(--bg);
}
.forge-inline > label { margin-bottom: 6px; }
.forge-inline-foot { display: flex; gap: 8px; align-items: center; margin-top: 8px; }
.forge-inline-foot input { flex: 1; min-width: 0; }
.forge-inline-foot .btn { flex: none; white-space: nowrap; }
.forge-inline .forge-stage { margin-top: 10px; }
/* 写完之后的一行回执：名字 + 一句话介绍，不用往下翻也知道成了 */
.forge-done {
  margin-top: 10px; padding: 9px 12px; border-radius: 10px;
  background: var(--primary-soft); border-left: 3px solid var(--primary);
  font-size: 12.5px; line-height: 1.65; color: var(--text);
}
/* 示例提示词：点一下填进输入框，再接着改。做成小圆角标签，不像按钮那么重，不会被当成「必须选一个」 */
.forge-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.forge-chip {
  max-width: 100%; padding: 5px 10px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--border); background: var(--bg); color: var(--text-sub);
  font-size: 11.5px; line-height: 1.55; text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: all .15s;
}
.forge-chip:hover { border-color: var(--primary); color: var(--primary); background: var(--primary-soft); }
/* 生成中：一行转圈 + 分阶段的说明，让人知道它没死 */
.forge-stage {
  display: flex; align-items: flex-start; gap: 10px; margin-top: 4px;
  padding: 12px 14px; border-radius: 12px;
  background: var(--primary-soft); border: 1px solid #dfe8ff;
}
.forge-stage-text { font-size: 13px; color: var(--text); line-height: 1.6; }
.forge-stage .hint { margin-top: 3px; }
.forge-dot {
  flex: none; width: 9px; height: 9px; margin-top: 5px; border-radius: 50%;
  background: var(--primary); animation: forgePulse 1.15s ease-in-out infinite;
}
@keyframes forgePulse {
  0%, 100% { opacity: .25; transform: scale(.75); }
  50% { opacity: 1; transform: scale(1.1); }
}


/* ---------- 手机上点输入框会整页放大 ----------
   iOS Safari 的规矩：input/textarea 的字号只要小于 16px，一聚焦它就自己把页面放大，
   而且不会自动缩回去 —— 就是你看到的"点开输入就变大"。
   光靠 maximum-scale=1 能压住，但那样连正常双指缩放也没了，不合算。
   正解是把可聚焦的输入控件在窄屏下一律给到 16px。 */
@media (max-width: 820px) {
  #input,
  #access-input,
  #moment-content,
  #moment-character,
  .form-row input,
  .form-row textarea,
  .form-row select,
  .chip-add input,
  .avatar-edit-actions input { font-size: 16px; }
  /* 16px 下同一行能塞的字变少，行高稍微收一点，气泡不会显得胖 */
  #input { line-height: 1.45; }
}

/* 设置里的蒸馏列表：一行一个伴侣，左边「学了多少、学到了什么」，右边两个按钮 */
.distill-list { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.distill-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--panel);
}
.distill-who { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.distill-who strong { font-size: 13px; font-weight: 600; color: var(--text); }
.distill-who .hint {
  font-size: 12px; color: var(--text-sub);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.distill-btns { display: flex; gap: 6px; flex: none; }
.distill-btns .btn { white-space: nowrap; }

/* 「这句怎么念」卡片：把这一条气泡当时的场景和语气摊开，贴底居中，不挡聊天 */
.dir-card {
  position: fixed; left: 50%; bottom: 96px; transform: translateX(-50%);
  z-index: 210; width: min(440px, calc(100vw - 36px));
  background: var(--panel); color: var(--text);
  border: 1px solid var(--border); border-radius: 14px;
  padding: 12px 14px 10px; box-shadow: 0 10px 30px rgba(20, 30, 60, .18);
}
.dir-card .dc-head {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 600; margin-bottom: 8px;
}
.dir-card .dc-badge {
  font-size: 11px; font-weight: 400; color: var(--text-sub);
  border: 1px solid var(--border); border-radius: 999px; padding: 1px 7px;
}
.dir-card .dc-scene {
  font-size: 12px; color: var(--text-sub); line-height: 1.55; margin-bottom: 6px;
}
.dir-card .dc-dir {
  font-size: 13px; line-height: 1.65; color: var(--text);
  background: var(--bg, rgba(127, 127, 127, .06));
  border-radius: 9px; padding: 9px 10px;
}
.dir-card .dc-close { margin-top: 9px; width: 100%; }

/* ---------- 语音条：她主动发来的那条会显示成一条音频 ---------- */
.vn-wrap { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.vn-pill {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 8px 15px 8px 12px; border-radius: 18px;
  background: var(--primary-soft); border: 1px solid #dbe6ff;
  cursor: pointer; user-select: none; min-width: 108px;
  transition: background .15s ease, transform .1s ease;
}
.vn-pill:hover { background: #e3edff; }
.vn-pill:active { transform: scale(.985); }
.vn-pill.playing { background: #dfeaff; border-color: #b9cffd; }
.vn-play { font-size: 11px; color: var(--primary); width: 12px; text-align: center; }
.vn-wave { display: inline-flex; align-items: flex-end; gap: 2px; height: 14px; }
.vn-wave i {
  display: block; width: 2px; border-radius: 1px; background: #7f9ef0; height: 6px;
}
.vn-wave i:nth-child(1) { height: 5px; }
.vn-wave i:nth-child(2) { height: 10px; }
.vn-wave i:nth-child(3) { height: 7px; }
.vn-wave i:nth-child(4) { height: 12px; }
.vn-wave i:nth-child(5) { height: 6px; }
.vn-pill.playing .vn-wave i { animation: vnWave .9s ease-in-out infinite; }
.vn-pill.playing .vn-wave i:nth-child(2) { animation-delay: .12s; }
.vn-pill.playing .vn-wave i:nth-child(3) { animation-delay: .24s; }
.vn-pill.playing .vn-wave i:nth-child(4) { animation-delay: .36s; }
.vn-pill.playing .vn-wave i:nth-child(5) { animation-delay: .48s; }
@keyframes vnWave { 0%, 100% { transform: scaleY(.6); } 50% { transform: scaleY(1.5); } }
.vn-sec { font-size: 12px; color: #5b7bd5; }
.vn-more {
  font-size: 11px; color: var(--text-sub); cursor: pointer;
  border-bottom: 1px dashed currentColor; padding-bottom: 1px;
}
.vn-more:hover { color: var(--primary); }
.vn-body { display: block; width: 100%; margin-top: 2px; }
.vn-body[hidden] { display: none; }

/* ---------- 「添加到手机主屏幕」引导 ---------- */
.install-mask {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(24,28,36,.42);
  backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
  display: flex; align-items: center; justify-content: center;
  padding: 22px; padding-bottom: calc(22px + env(safe-area-inset-bottom));
}
.install-card {
  width: 100%; max-width: 340px;
  background: var(--panel); border-radius: 18px;
  padding: 22px 20px 16px;
  box-shadow: 0 18px 50px rgba(20,26,40,.24);
  text-align: center;
  animation: installUp .22s ease-out;
}
@keyframes installUp { from { transform: translateY(14px); opacity: 0; } to { transform: none; opacity: 1; } }
.install-logo { font-size: 34px; line-height: 1; margin-bottom: 8px; }
.install-card h3 { font-size: 17px; font-weight: 700; margin-bottom: 6px; }
.install-sub { font-size: 13px; color: var(--text-sub); line-height: 1.6; margin-bottom: 14px; }
.install-steps {
  text-align: left; font-size: 13px; line-height: 1.85;
  background: var(--primary-soft); border-radius: 12px;
  padding: 11px 13px; margin-bottom: 16px; color: var(--text);
}
.install-steps b { color: var(--primary); font-weight: 700; }
.install-steps .k {
  display: inline-block; padding: 0 5px; border-radius: 5px;
  background: #fff; border: 1px solid #dbe4ff; font-size: 12px;
}
.install-card .btn { margin-top: 8px; }
.install-card .btn:first-of-type { margin-top: 0; }
