/* 大肥鱼 · 手机 App（PWA）——移动优先、暗色、安全区适配 */
:root {
  --bg: #0b0e14;
  --bg-soft: #0f1420;
  --panel: #141a28;
  --panel-2: #182033;
  --line: #253049;
  --text: #e9edf6;
  --muted: #8e99ad;
  --faint: #66718a;
  --accent: #4f8cff;
  --accent-2: #8b5cf6;
  --danger: #ff5f6d;
  --ok: #3ddc97;
  --warn: #ffb020;
  --bubble-user: #2f6df0;
  --bubble-ai: #1a2336;
  --radius: 16px;
  --radius-sm: 12px;
  --tabh: 58px;
  --shadow: 0 10px 30px rgba(0, 0, 0, .38);
  --app-height: 100dvh;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}

body {
  display: flex;
  flex-direction: column;
  height: var(--app-height);
  background:
    radial-gradient(1200px 600px at 15% -10%, rgba(79, 140, 255, .16), transparent 60%),
    radial-gradient(900px 500px at 110% 0%, rgba(139, 92, 246, .13), transparent 55%),
    var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
    "Hiragino Sans GB", "Microsoft YaHei", system-ui, sans-serif;
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-size-adjust: 100%;
}

h1, h2, h3 { margin: 0; font-weight: 650; letter-spacing: .2px; }
h1 { font-size: 18px; }
h2 { font-size: 19px; }
h3 { font-size: 15px; }
p { margin: 0; }
code {
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: .92em;
  background: rgba(255, 255, 255, .06);
  padding: 1px 5px;
  border-radius: 6px;
}
button, input, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
.hidden { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.muted { color: var(--muted); }
.small { font-size: 12.5px; }
.hint { color: var(--faint); font-size: 12px; line-height: 1.7; }

/* ------------------------------------------------------------ 顶栏 / 离线条 */
.offline-bar {
  flex: none;
  z-index: 40;
  padding: max(6px, env(safe-area-inset-top)) 14px 6px;
  background: rgba(255, 176, 32, .14);
  border-bottom: 1px solid rgba(255, 176, 32, .28);
  color: #ffd08a;
  font-size: 12.5px;
  text-align: center;
}

/* 历史缓存状态细条：缓存 · 正在更新…（灰）/ 离线 · 本地缓存（黄）。
   放在顶栏下面，不占太多高度；加载完 1.5 秒后淡出。 */
.hist-cache-bar {
  flex: none;
  align-self: center;
  max-width: calc(100% - 28px);
  margin: 6px 14px 0;
  padding: 4px 12px;
  border-radius: 999px;
  font-size: 11.5px;
  line-height: 1.5;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity .28s ease, transform .28s ease;
  pointer-events: none;
}
.hist-cache-bar.show { opacity: 1; transform: none; }
.hist-cache-bar.loading {
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .08);
  color: var(--faint);
}
.hist-cache-bar.offline {
  background: rgba(255, 176, 32, .13);
  border: 1px solid rgba(255, 176, 32, .32);
  color: #ffd08a;
}

/* ------------------------------------------------------------ 登录 */
.login {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(24px + env(safe-area-inset-top)) 20px
           calc(24px + env(safe-area-inset-bottom));
}
.login-card {
  width: 100%;
  max-width: 380px;
  text-align: center;
}
.login-logo {
  width: 92px;
  height: 92px;
  border-radius: 24px;
  box-shadow: var(--shadow);
  margin-bottom: 16px;
}
.login-card h1 { font-size: 26px; letter-spacing: 2px; }
.login-sub { color: var(--muted); margin: 6px 0 26px; font-size: 13.5px; }
.login form { display: flex; flex-direction: column; gap: 12px; }
.pin-input {
  width: 100%;
  padding: 15px 16px;
  text-align: center;
  letter-spacing: 10px;
  font-size: 22px;
  font-variant-numeric: tabular-nums;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
.pin-input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(79, 140, 255, .18);
}
.remember {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  color: var(--muted);
  font-size: 13px;
  user-select: none;
}
.remember input { accent-color: var(--accent); width: 16px; height: 16px; }
.err { min-height: 18px; color: var(--danger); font-size: 13px; }

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 11px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--line);
  background: var(--panel-2);
  color: var(--text);
  font-weight: 600;
  transition: transform .08s, filter .15s, background .15s;
}
.btn:active { transform: scale(.985); }
.btn.primary {
  border: 0;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: #fff;
  box-shadow: 0 8px 22px rgba(79, 140, 255, .28);
}
.btn.danger { color: #ffd7da; background: rgba(255, 95, 109, .12); border-color: rgba(255, 95, 109, .38); }
.btn:disabled { opacity: .55; }
.ghost {
  padding: 6px 10px;
  border-radius: 9px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  font-size: 12.5px;
}
.ghost:active { background: rgba(255, 255, 255, .05); }

/* ------------------------------------------------------------ 外壳 */
.shell {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding-bottom: calc(var(--tabh) + env(safe-area-inset-bottom));
  overflow: hidden;
}
.topbar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: calc(56px + env(safe-area-inset-top));
  padding: calc(9px + env(safe-area-inset-top)) 16px 9px;
  border-bottom: 1px solid rgba(255, 255, 255, .05);
  background: rgba(11, 14, 20, .72);
  backdrop-filter: blur(12px);
}
.topbar-title { display: flex; align-items: center; gap: 8px; min-width: 0; }
.topbar-title h1 {
  min-width: 0;
  font-size: 17px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.topbar-actions {
  flex: none;
  display: flex;
  align-items: center;
  gap: 2px;
}
.top-icon-btn {
  position: relative;
  flex: none;
  width: 36px;
  height: 36px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  color: var(--muted);
  transition: color .15s, background .15s, border-color .15s;
}
/* 视觉 36px，点击热区扩到 44px */
.top-icon-btn::after {
  content: "";
  position: absolute;
  inset: -4px;
}
.top-icon-btn:active { background: rgba(255, 255, 255, .08); color: var(--text); }
.top-devmode-btn.on {
  color: #cfe0ff;
  background: rgba(79, 140, 255, .18);
  border-color: rgba(79, 140, 255, .55);
  box-shadow: 0 0 0 1px rgba(79, 140, 255, .08) inset;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 46vw;
  padding: 3px 9px;
  border-radius: 999px;
  background: rgba(79, 140, 255, .14);
  border: 1px solid rgba(79, 140, 255, .32);
  color: #b9d0ff;
  font-size: 11.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.chip.world { background: rgba(139, 92, 246, .14); border-color: rgba(139, 92, 246, .34); color: #d7c6ff; }
.conn {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ok);
  box-shadow: 0 0 0 4px rgba(61, 220, 151, .12);
}
.conn.bad { background: var(--danger); box-shadow: 0 0 0 4px rgba(255, 95, 109, .12); }
.conn.wait { background: var(--warn); box-shadow: 0 0 0 4px rgba(255, 176, 32, .12); }

.views { flex: 1; min-height: 0; display: flex; }
.view {
  display: none;
  flex: 1;
  min-height: 0;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 14px 14px 18px;
}
.view.active { display: flex; }
.view#view-chat { padding: 0; overflow: hidden; }
/* 世界页和聊天页一样：整页不滚，中间正文区自己滚，输入框永远贴底 */
.view#view-world { padding: 0; overflow: hidden; }
#worldListWrap {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 14px;
}
#worldReader.reader {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  padding: 10px 14px 0;
}
#worldReader .reader-head,
#worldReader #worldTitle,
#worldReader #worldMeta,
#worldReader #worldStatus,
#worldReader #worldForm { flex: none; }
.world-scroll {
  flex: 1;
  min-height: 0;
  /* 只让这一层负责滚动（#worldScroll），上下各留一点呼吸位；
     顶部 10px 是给第一条气泡的，避免贴着标题 / 顶栏阴影被裁掉。 */
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 10px 0 6px;
}

.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin: 2px 2px 14px;
}
.page-head .muted { margin-top: 3px; font-size: 12.5px; }

/* ------------------------------------------------------------ 聊天 */
.banner {
  flex: none;
  margin: 10px 14px 0;
  padding: 8px 12px;
  border-radius: 12px;
  background: rgba(79, 140, 255, .1);
  border: 1px solid rgba(79, 140, 255, .22);
  color: #bcd2ff;
  font-size: 12.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.messages {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 14px 6px;
  scroll-behavior: smooth;
  /* 「加载更早」时自己接管 scrollTop，别让浏览器 scroll anchoring 再动一次 */
  overflow-anchor: none;
}
.msg {
  max-width: 84%;
  padding: 10px 13px;
  border-radius: 16px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: break-word;
  font-size: 14.5px;
  box-shadow: 0 1px 0 rgba(0, 0, 0, .12);
}
.msg.assistant {
  align-self: flex-start;
  background: var(--bubble-ai);
  border: 1px solid rgba(255, 255, 255, .055);
  border-bottom-left-radius: 6px;
}
.msg.user {
  align-self: flex-end;
  background: linear-gradient(135deg, #2f6df0, #4f8cff);
  color: #fff;
  border-bottom-right-radius: 6px;
}
.msg.system {
  align-self: center;
  max-width: 94%;
  background: transparent;
  border: 1px dashed var(--line);
  color: var(--muted);
  font-size: 12.5px;
  text-align: center;
}
.msg-time {
  display: block;
  margin-top: 4px;
  color: rgba(255, 255, 255, .45);
  font-size: 10.5px;
  text-align: right;
}
.msg.user .msg-time { color: rgba(255, 255, 255, .7); }

.empty {
  margin: auto;
  padding: 30px 20px;
  text-align: center;
  color: var(--muted);
  font-size: 13.5px;
}
.empty .big { font-size: 40px; margin-bottom: 10px; }

.typing {
  flex: none;
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 4px 20px 8px;
}
.typing span {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  opacity: .35;
  animation: blink 1.15s infinite ease-in-out;
}
.typing span:nth-child(2) { animation-delay: .18s; }
.typing span:nth-child(3) { animation-delay: .36s; }
@keyframes blink {
  0%, 80%, 100% { opacity: .25; transform: translateY(0); }
  40% { opacity: 1; transform: translateY(-3px); }
}

.retry {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 4px 14px 8px;
  color: var(--danger);
  font-size: 12.5px;
}
.retry button {
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid rgba(255, 95, 109, .45);
  background: rgba(255, 95, 109, .12);
  color: #ffd7da;
  font-size: 12.5px;
}

.composer {
  flex: none;
  display: flex;
  align-items: flex-end;
  gap: 8px;
  padding: 8px 10px calc(10px);
  border-top: 1px solid rgba(255, 255, 255, .06);
  background: rgba(11, 14, 20, .9);
  backdrop-filter: blur(12px);
}
.composer textarea,
.composer input[type="text"] {
  flex: 1;
  min-width: 0;
  /* 和聊天页统一：44px 高、左右 14px、圆角 20px。
     padding 10px（不是 11px）是为了 21px 行高 + 20px padding + 2px 边框 = 43，
     再由下面的 height/min-height 钉到 44px，三页 computed style 完全一致。 */
  height: 44px;
  padding: 10px 14px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 20px;
  outline: none;
  font-size: 15px;
  line-height: 1.4;
  resize: none;
}
.composer textarea {
  max-height: 118px;
  min-height: 44px;
}
.composer textarea:focus,
.composer input[type="text"]:focus {
  border-color: rgba(79, 140, 255, .6);
  box-shadow: 0 0 0 3px rgba(79, 140, 255, .14);
}
.send {
  flex: none;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: #fff;
  box-shadow: 0 6px 18px rgba(79, 140, 255, .32);
}
.send:active { transform: scale(.95); }
.send:disabled { opacity: .5; box-shadow: none; }

/* ------------------------------------------------------------ 酒馆 */
.card-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  padding-bottom: 6px;
}
.role-card {
  position: relative;
  min-width: 0;
  padding: 12px;
  border-radius: var(--radius);
  background: linear-gradient(160deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line);
  text-align: left;
  transition: transform .1s, border-color .15s;
}
.role-card:active { transform: scale(.985); }
.role-card.current { border-color: rgba(79, 140, 255, .62); box-shadow: 0 0 0 1px rgba(79, 140, 255, .35) inset; }
.role-avatar {
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 12px;
  margin-bottom: 9px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 40px;
  background:
    radial-gradient(120% 100% at 20% 0%, rgba(79, 140, 255, .38), transparent 60%),
    linear-gradient(150deg, #223055, #171e30);
  overflow: hidden;
}
.role-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.role-name {
  font-weight: 650;
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.role-tag {
  margin-top: 3px;
  color: var(--muted);
  font-size: 11.5px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.role-badges { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 7px; }
.tag {
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .06);
  color: var(--muted);
  font-size: 10.5px;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tag.main { background: rgba(61, 220, 151, .14); color: #8af0c4; }

/* ------------------------------------------------------------ 世界 */
.list { display: flex; flex-direction: column; gap: 10px; padding-bottom: 6px; }
.world-item {
  width: 100%;
  text-align: left;
  padding: 13px 14px;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
}
.world-item.current { border-color: rgba(139, 92, 246, .55); }
.world-item h3 { font-size: 15px; display: flex; align-items: center; gap: 7px; }
.world-item .desc {
  margin-top: 4px;
  color: var(--muted);
  font-size: 12.5px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.world-meta { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; color: var(--faint); font-size: 11px; }
.world-meta .dot::before { content: "·"; margin-right: 6px; }

.reader { display: flex; flex-direction: column; min-height: 0; }
.reader-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
}
.reader h2 { margin-bottom: 4px; }
.story {
  margin-top: 14px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.section {
  padding: 14px;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
}
.section h3 {
  font-size: 12.5px;
  color: var(--accent-2);
  margin-bottom: 8px;
  letter-spacing: .4px;
}
.section .body {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-size: 14.5px;
  line-height: 1.75;
}
.choices { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.choice {
  width: 100%;
  text-align: left;
  padding: 12px 14px;
  border-radius: 13px;
  border: 1px solid rgba(139, 92, 246, .32);
  background: rgba(139, 92, 246, .09);
  color: #ded3ff;
  font-size: 13.5px;
}
.choice:active { background: rgba(139, 92, 246, .18); }
.choice b { color: #b79cff; margin-right: 6px; }
#worldStatus { min-height: 16px; margin-top: 10px; }
#view-world .composer { margin-top: 10px; border-radius: 16px; border-top: 0; padding: 0; background: transparent; backdrop-filter: none; }

/* ------------------------------------------------------------ 创作占位 */
.place-list { display: flex; flex-direction: column; gap: 10px; }
.place {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px dashed var(--line);
}
.place-ico {
  flex: none;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 13px;
  background: rgba(255, 255, 255, .05);
  font-size: 21px;
}
.place-body { flex: 1; min-width: 0; }
.place-body h3 { font-size: 14.5px; }
.place-body p { color: var(--muted); font-size: 12px; margin-top: 2px; }
.badge {
  flex: none;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(255, 176, 32, .12);
  border: 1px solid rgba(255, 176, 32, .3);
  color: #ffd08a;
  font-size: 10.5px;
}

/* ------------------------------------------------------------ 创作：四张卡 */
.create-grid { display: flex; flex-direction: column; gap: 12px; }
.create-card {
  padding: 14px;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
  min-width: 0;
  overflow: hidden;
}
.create-head { display: flex; align-items: center; gap: 9px; margin-bottom: 10px; }
.create-head h3 { font-size: 15px; }
.create-ico {
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 11px;
  background: rgba(255, 255, 255, .05);
  font-size: 18px;
}
.create-input {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px;
  background: rgba(0, 0, 0, .18);
  border: 1px solid var(--line);
  border-radius: 13px;
  color: var(--text);
  outline: none;
  font-size: 14px;
  line-height: 1.5;
  resize: vertical;
  min-height: 64px;
}
.create-input:focus { border-color: rgba(79, 140, 255, .6); }
.seg-row { display: flex; gap: 7px; margin: 10px 0; flex-wrap: wrap; }
.seg {
  flex: 1 1 0;
  min-width: 62px;
  padding: 7px 10px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, .03);
  color: var(--muted);
  font-size: 12.5px;
}
.seg.active {
  border-color: rgba(79, 140, 255, .6);
  background: rgba(79, 140, 255, .16);
  color: #e8f1ff;
}
.create-action { width: 100%; }
.btn-row { display: flex; flex-wrap: wrap; gap: 8px; }
.media-progress { margin-top: 11px; }
.progress-track {
  height: 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .08);
  overflow: hidden;
}
.progress-track i {
  display: block;
  width: 0;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
  transition: width .35s ease;
}
.media-progress span {
  display: block;
  margin-top: 5px;
  color: var(--muted);
  font-size: 12px;
}
.media-result { margin-top: 11px; display: flex; flex-direction: column; gap: 9px; }
.media-result img,
.media-result video {
  width: 100%;
  max-width: 100%;
  border-radius: 13px;
  border: 1px solid var(--line);
  background: #000;
  display: block;
}
.media-result video { max-height: 62vh; }
.media-result img { cursor: zoom-in; }
.link-row { display: flex; gap: 8px; }
.link-row input {
  flex: 1;
  min-width: 0;
  padding: 10px 12px;
  background: rgba(0, 0, 0, .18);
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--text);
  outline: none;
  font-size: 13.5px;
}
.link-row input:focus { border-color: rgba(79, 140, 255, .6); }
.link-result { margin-top: 12px; }
.link-result h4 { font-size: 14px; line-height: 1.45; margin-bottom: 7px; word-break: break-word; }
.link-meta { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.link-cover {
  width: 100%;
  max-height: 200px;
  object-fit: cover;
  border-radius: 12px;
  border: 1px solid var(--line);
  margin-bottom: 9px;
}
#linkSummary { white-space: pre-wrap; word-break: break-word; line-height: 1.6; }
.upload-preview { margin: 10px 0; }
.upload-preview img {
  width: 100%;
  max-height: 240px;
  object-fit: contain;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: rgba(0, 0, 0, .2);
}
.upload-result { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.ok-line { color: var(--ok); font-size: 13px; }

/* 聊天输入框旁的工具按钮 / 待发送缩略图 / 链接提示 */
#composer { gap: 6px; }
.composer-tool {
  flex: none;
  width: 32px;
  height: 40px;
  padding: 0;
  border: 0;
  border-radius: 11px;
  background: transparent;
  color: var(--muted);
  font-size: 17px;
  line-height: 1;
}
.composer-tool:active { background: rgba(255, 255, 255, .07); }
.composer-attach {
  flex: none;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 8px 12px 0;
  max-height: 92px;
  overflow-y: auto;
  background: rgba(11, 14, 20, .9);
}
.composer-attach .attach-item { position: relative; flex: none; }
.composer-attach img {
  width: 54px;
  height: 54px;
  object-fit: cover;
  border-radius: 10px;
  border: 1px solid var(--line);
  display: block;
}
.composer-attach .attach-item button {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 20px;
  height: 20px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: rgba(0, 0, 0, .72);
  color: #fff;
  font-size: 13px;
  line-height: 1;
}
.link-tip {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 10px 6px;
  padding: 8px 10px;
  border-radius: 12px;
  border: 1px solid rgba(79, 140, 255, .35);
  background: rgba(79, 140, 255, .1);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  font-size: 12.5px;
}
.link-tip #linkTipText {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.link-tip-switch {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--muted);
  font-size: 11.5px;
  white-space: nowrap;
  cursor: pointer;
}
.link-tip-switch input {
  width: 14px;
  height: 14px;
  margin: 0;
  accent-color: var(--accent);
}
.bubble-image {
  display: block;
  max-width: 100%;
  width: 180px;
  max-height: 240px;
  object-fit: cover;
  border-radius: 11px;
  margin-bottom: 6px;
  cursor: zoom-in;
}
.msg-row.media { justify-content: center; padding: 4px 0; }
.media-bubble {
  max-width: 86%;
  padding: 7px;
  border-radius: 14px;
  background: var(--panel);
  border: 1px solid var(--line);
}
.media-bubble img,
.media-bubble video {
  display: block;
  width: 100%;
  max-height: 56vh;
  border-radius: 10px;
  background: #000;
}
.media-bubble .media-cap {
  margin-top: 5px;
  color: var(--faint);
  font-size: 11px;
  text-align: center;
}

/* 气泡里的链接卡片（B 站 / 抖音自动解析） */
.link-card {
  display: flex;
  gap: 8px;
  min-width: 0;
  margin-bottom: 8px;
  padding: 7px;
  border-radius: 11px;
  border: 1px solid rgba(255, 255, 255, .12);
  background: rgba(0, 0, 0, .22);
}
.link-card-cover {
  flex: none;
  width: 76px;
  height: 57px;
  object-fit: cover;
  border-radius: 8px;
  display: block;
  background: #000;
}
.link-card-body { flex: 1; min-width: 0; }
.link-card-title {
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.link-card-meta {
  margin-top: 3px;
  color: rgba(255, 255, 255, .62);
  font-size: 11px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.link-card-desc {
  margin-top: 3px;
  color: rgba(255, 255, 255, .55);
  font-size: 11px;
  line-height: 1.45;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.msg-row.send-failed .msg-bubble {
  outline: 1px dashed rgba(255, 95, 109, .55);
  outline-offset: 2px;
}
/* 本地缓存里没发出去的 pending 消息：虚线框 + 很小的「待重试」角标 */
.msg-row.pending-retry .msg-bubble {
  outline: 1px dashed rgba(255, 176, 32, .55);
  outline-offset: 2px;
}
.pending-tag {
  display: inline-block;
  margin-top: 4px;
  padding: 0 6px;
  border-radius: 999px;
  background: rgba(0, 0, 0, .18);
  color: rgba(255, 255, 255, .82);
  font-size: 10.5px;
  line-height: 1.6;
  white-space: nowrap;
}

/* ------------------------------------------------------------ 创作：两个入口 + 生图 / 生视频页 */
.create-hub { display: flex; flex-direction: column; gap: 12px; }
.create-entry {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 18px 16px;
  text-align: left;
  border-radius: 18px;
  border: 1px solid rgba(255, 255, 255, .08);
  background: linear-gradient(135deg, rgba(32, 43, 68, .92), rgba(17, 22, 35, .94));
  color: var(--text);
  box-shadow: 0 10px 26px rgba(0, 0, 0, .22);
}
.create-entry:active { transform: scale(.985); }
.create-entry .entry-ico {
  flex: none;
  width: 46px;
  height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 14px;
  background: rgba(255, 255, 255, .06);
  font-size: 24px;
}
.create-entry .entry-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.create-entry .entry-body b { font-size: 16px; }
.create-entry .entry-body small { color: var(--muted); font-size: 12px; }
.entry-arrow { flex: none; color: var(--faint); font-size: 22px; }
.create-page { display: flex; flex-direction: column; gap: 12px; }
.create-subhead { display: flex; align-items: center; gap: 10px; }
.create-subhead h2 { font-size: 18px; }
.create-back { flex: none; padding: 6px 11px; border-radius: 10px; }
.history-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-top: 4px;
}
.history-head h3 { font-size: 14px; white-space: nowrap; }
.history-search {
  flex: 1;
  min-width: 0;
  max-width: 190px;
  padding: 7px 11px;
  border-radius: 11px;
  border: 1px solid rgba(255, 255, 255, .1);
  background: rgba(255, 255, 255, .04);
  color: var(--text);
  font-size: 12.5px;
  outline: none;
}
.history-search:focus { border-color: rgba(79, 140, 255, .6); }
.media-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.media-item {
  position: relative;
  padding: 0;
  aspect-ratio: 1 / 1;
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  background: var(--panel);
}
.media-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.media-item:active { transform: scale(.98); }
.media-item.fresh,
.media-row.fresh {
  border-color: rgba(79, 140, 255, .8);
  box-shadow: 0 0 0 2px rgba(79, 140, 255, .35), 0 8px 22px rgba(79, 140, 255, .22);
  animation: freshpop 1.2s ease;
}
@keyframes freshpop {
  0% { transform: scale(.94); }
  60% { transform: scale(1.02); }
  100% { transform: none; }
}
.media-list { display: flex; flex-direction: column; gap: 8px; }
.media-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px;
  text-align: left;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--text);
}
.media-row:active { transform: scale(.99); }
.media-thumb {
  position: relative;
  flex: none;
  width: 104px;
  aspect-ratio: 16 / 9;
  border-radius: 9px;
  overflow: hidden;
  background: #000;
}
.media-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.media-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 15px;
  background: rgba(0, 0, 0, .28);
}
.media-row-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.media-row-title {
  font-size: 13px;
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.media-row-meta { color: var(--faint); font-size: 11.5px; }
.media-row-arrow { flex: none; color: var(--faint); font-size: 20px; }
.history-empty { color: var(--faint); font-size: 12.5px; padding: 14px 2px; text-align: center; }
.history-more { width: 100%; }

/* 作品预览：全屏，图片左右滑，视频直接播 */
.media-viewer {
  position: fixed;
  inset: 0;
  z-index: 55;   /* 高于底部 Tab，低于 toast(60) / sheet(90)，提示能看到 */
  display: flex;
  flex-direction: column;
  padding: max(10px, env(safe-area-inset-top)) 10px
           calc(14px + env(safe-area-inset-bottom));
  background: rgba(4, 6, 12, .95);
  -webkit-backdrop-filter: blur(18px);
  backdrop-filter: blur(18px);
}
.viewer-close {
  position: absolute;
  top: calc(8px + env(safe-area-inset-top));
  right: 10px;
  z-index: 2;
  width: 38px;
  height: 38px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .16);
  background: rgba(0, 0, 0, .45);
  color: #fff;
  font-size: 20px;
  line-height: 1;
}
.viewer-stage {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  touch-action: pan-y;
}
.viewer-stage img,
.viewer-stage video {
  max-width: 100%;
  max-height: 100%;
  border-radius: 12px;
  display: block;
  background: #000;
}
.viewer-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 38px;
  height: 54px;
  padding: 0;
  border: 0;
  border-radius: 12px;
  background: rgba(0, 0, 0, .4);
  color: #fff;
  font-size: 26px;
  line-height: 1;
}
.viewer-nav.prev { left: 0; }
.viewer-nav.next { right: 0; }
.viewer-bar { flex: none; display: flex; flex-direction: column; gap: 9px; padding: 10px 4px 0; }
.viewer-meta {
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.5;
  white-space: pre-line;
  max-height: 4.8em;
  overflow: hidden;
}
.viewer-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.viewer-actions button {
  flex: 1 1 0;
  min-width: 96px;
  padding: 10px 8px;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, .12);
  background: rgba(255, 255, 255, .06);
  color: var(--text);
  font-size: 12.5px;
}

/* ------------------------------------------------------------ 设置 */
.card {
  padding: 14px;
  border-radius: var(--radius);
  background: var(--panel);
  border: 1px solid var(--line);
  margin-bottom: 12px;
}
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.card h3 { margin-bottom: 10px; }
.card-head h3 { margin-bottom: 0; }
.kv { display: flex; flex-direction: column; gap: 7px; font-size: 13px; }
.kv .row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.kv .row span:last-child {
  color: var(--text);
  text-align: right;
  overflow-wrap: anywhere;
}
.kv .dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; background: var(--faint); margin-right: 6px; }
.kv .dot.on { background: var(--ok); }
.kv .dot.off { background: var(--danger); }
.stack { display: flex; flex-direction: column; gap: 9px; }
.stack input {
  padding: 11px 13px;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 11px;
  outline: none;
}
.stack input:focus { border-color: rgba(79, 140, 255, .6); }

/* ------------------------------------------------------------ 底部 Tab */
.tabbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  display: flex;
  align-items: stretch;
  height: calc(var(--tabh) + env(safe-area-inset-bottom));
  padding-bottom: env(safe-area-inset-bottom);
  background: rgba(13, 17, 26, .92);
  border-top: 1px solid rgba(255, 255, 255, .07);
  backdrop-filter: blur(16px);
}
.tab {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  border: 0;
  background: transparent;
  color: var(--faint);
  font-size: 10.5px;
  padding: 4px 0 6px;
  position: relative;
}
.tab span {
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tab.active { color: var(--accent); }
.tab.active::after {
  content: "";
  position: absolute;
  top: 0;
  width: 22px;
  height: 2.5px;
  border-radius: 0 0 3px 3px;
  background: linear-gradient(90deg, var(--accent), var(--accent-2));
}
/* 未读角标：挂在图标右上角，不压住图标本身 */
.tab-ico {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.tab-badge {
  position: absolute;
  top: -4px;
  right: -8px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: #ff3b4d;
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  font-style: normal;
  letter-spacing: 0;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .5);
  pointer-events: none;
}
.tab-badge.hidden { display: none; }
/* 卡池 / 世界列表上的小红点 */
.unread-dot {
  position: absolute;
  top: 9px;
  right: 9px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #ff3b4d;
  box-shadow: 0 0 0 2px rgba(11, 14, 20, .85);
}
.unread-dot.hidden { display: none; }
.world-item { position: relative; }

/* ------------------------------------------------------------ 回到最新消息
   离底部超过 400px 才淡入；三个对话各一个按钮，切 Tab 互不影响。 */
.scroll-bottom {
  position: fixed;
  right: 14px;
  bottom: calc(var(--tabh, 56px) + env(safe-area-inset-bottom) + 78px);
  width: 40px;
  height: 40px;
  padding: 0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(255, 255, 255, .16);
  background: rgba(16, 22, 34, .66);
  color: var(--text);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 4px 14px rgba(0, 0, 0, .35);
  z-index: 24;
  opacity: 1;
  transition: opacity .18s ease, transform .12s ease;
}
.scroll-bottom.is-off { opacity: 0; pointer-events: none; }
.scroll-bottom:active { transform: scale(.88); }
.scroll-bottom .scroll-arrow { font-size: 17px; line-height: 1; }
.scroll-bottom .scroll-count {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: #ff3b4d;
  color: #fff;
  font-size: 10px;
  font-style: normal;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  box-shadow: 0 0 0 2px rgba(11, 14, 20, .9);
}
.scroll-bottom .scroll-count.is-off { display: none; }
@media (prefers-reduced-motion: reduce) {
  .scroll-bottom { transition: none; }
}

/* ------------------------------------------------------------ Toast */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--tabh) + env(safe-area-inset-bottom) + 18px);
  z-index: 60;
  max-width: min(86vw, 420px);
  transform: translateX(-50%);
  padding: 10px 16px;
  border-radius: 12px;
  background: rgba(28, 36, 54, .96);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  color: var(--text);
  font-size: 13px;
  text-align: center;
  overflow-wrap: anywhere;
}

/* ------------------------------------------------------------ 宽屏 */
@media (min-width: 620px) {
  .card-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .views { max-width: 760px; width: 100%; margin: 0 auto; }
  .topbar, .tabbar { max-width: 760px; left: 50%; transform: translateX(-50%); right: auto; width: 100%; }
  .tabbar { border-radius: 16px 16px 0 0; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ============================================================ 第三阶段增强
   背景 / 聊天气泡 / Markdown / 语音 / 头像 */
:root {
  --bg-blur: 6px;
  --bg-dim: .45;
}
.app-bg {
  position: fixed;
  inset: -36px;
  z-index: 0;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  filter: blur(var(--bg-blur));
  transform: scale(1.06);
  pointer-events: none;
  transition: filter .18s ease;
}
.app-bg-veil {
  position: fixed;
  inset: 0;
  z-index: 0;
  background: rgba(4, 7, 12, var(--bg-dim));
  pointer-events: none;
}
.login, .shell { position: relative; z-index: 1; }
.topbar { z-index: 2; }
.top-avatar {
  position: relative;
  flex: none;
  width: 32px;
  height: 32px;
  padding: 0;
  border-radius: 50%;
  overflow: visible;
  border: 1px solid rgba(255, 255, 255, .18);
  background: linear-gradient(135deg, #26334f, #171f30);
}
.top-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 50%;
}
/* 在线小圆点嵌在头像右下角（像 QQ），父元素是头像按钮本身 */
.avatar-badge {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid #0b0e14;
  background: var(--ok);
  box-sizing: border-box;
  pointer-events: none;
  z-index: 2;
  transition: background .15s;
}
.avatar-badge.ok { background: var(--ok); }
.avatar-badge.warn { background: var(--warn); }
.avatar-badge.bad { background: #66718a; }
.topbar-title { flex: 1; }
.card, .world-item, .section {
  background: rgba(20, 26, 40, .82);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.role-card {
  background: linear-gradient(160deg, rgba(24, 32, 51, .92), rgba(20, 26, 40, .8));
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}

/* ------------------------------------------------------------ 消息行 */
.messages { gap: 0; }
.msg-row {
  display: flex;
  align-items: flex-start;
  /* 头像与气泡的 8px 间距交给 .bubble-avatar 的 margin：
     她（正常方向）和自己（row-reverse）两侧写法对称，不会一边 8px 一边 16px */
  gap: 0;
  margin: 7px 0;
  max-width: 100%;
}
/* 她（开发者回复同属这一侧）：头像在左、气泡在右 */
.msg-row.assistant { justify-content: flex-start; padding-right: 9%; }
.msg-row.assistant .bubble-avatar { margin: 0 8px 0 0; }
/* 自己：row-reverse 把头像翻到右侧（QQ 布局），气泡贴左；flex-start 在
   row-reverse 里是「靠右」，右对齐和原来一致，不靠 justify-content: flex-end */
.msg-row.user {
  flex-direction: row-reverse;
  justify-content: flex-start;
  padding-left: 9%;
}
.msg-row.user .bubble-avatar { margin: 0 0 0 8px; }
.msg-row.cont { margin-top: 2px; }
.msg-row.cont.assistant { padding-left: 48px; }
.msg-row.cont.user { padding-right: 48px; }
.bubble-avatar {
  flex: none;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 50%;
  overflow: hidden;
  background: linear-gradient(135deg, #26334f, #171f30);
  color: var(--text);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.bubble-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.avatar-letter {
  width: 100%;
  height: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #3b6fd4;
  color: #fff;
  font-weight: 650;
  font-size: 17px;
}
.msg-col {
  min-width: 0;
  max-width: calc(100% - 48px);
  display: flex;
  flex-direction: column;
  /* 一条回复可能拆成「对话气泡 + 叙述块」多块：各自按内容宽，别互相撑宽 */
  align-items: flex-start;
}
.msg-row.user .msg-col { align-items: flex-end; }
.msg-bubble {
  position: relative;
  min-width: 0;
  max-width: 100%;
  padding: 9px 12px;
  border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, .09);
  font-size: 14.5px;
  line-height: 1.55;
  overflow-wrap: anywhere;
  word-break: break-word;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.msg-row.assistant .msg-bubble {
  background: rgba(24, 32, 48, .58);
  color: var(--text);
  border-bottom-left-radius: 6px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, .18);
}
.msg-row.user .msg-bubble {
  background: rgba(47, 109, 240, .82);
  border-color: rgba(130, 175, 255, .38);
  color: #fff;
  border-bottom-right-radius: 6px;
  box-shadow: 0 4px 18px rgba(20, 60, 160, .22);
}
.msg-bubble::after {
  content: "";
  position: absolute;
  bottom: 9px;
  width: 0;
  height: 0;
  border: 7px solid transparent;
  pointer-events: none;
}
.msg-row.assistant .msg-bubble::after {
  left: -14px;
  border-right-color: rgba(24, 32, 48, .58);
}
.msg-row.user .msg-bubble::after {
  right: -14px;
  border-left-color: rgba(47, 109, 240, .82);
}
.msg-body { min-width: 0; white-space: normal; }
.msg-body.plain { white-space: pre-wrap; }
.msg-tools { display: flex; gap: 6px; margin-top: 3px; padding: 0 2px; min-height: 18px; }
.tts-btn {
  border: 0;
  padding: 1px 6px;
  border-radius: 999px;
  background: rgba(8, 12, 20, .46);
  color: rgba(233, 237, 246, .78);
  font-size: 12px;
  line-height: 1.6;
}
.tts-btn.playing { background: rgba(79, 140, 255, .28); color: #dbe8ff; }
.tts-btn.loading { opacity: .55; }

/* ------------------------------------------------------------ 语音消息气泡 */
/* 一条真正的音频消息：播放键 + 自绘波形/进度 + 时长；点击播放，拖动 seek。 */
.voice-msg {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 208px;
  max-width: 100%;
  padding: 1px 0;
  color: inherit;
}
.voice-play {
  flex: none;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(79, 140, 255, .24);
  color: #dbe8ff;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
.msg-row.user .voice-play { background: rgba(255, 255, 255, .22); color: #fff; }
.voice-play:active { transform: scale(.94); }
.voice-play.loading { opacity: .6; }
.voice-track {
  position: relative;
  flex: 1;
  min-width: 110px;
  height: 32px;
  display: flex;
  align-items: center;
  cursor: pointer;
  touch-action: none;
  outline: none;
}
.voice-track:focus-visible { box-shadow: 0 0 0 2px rgba(79, 140, 255, .55); border-radius: 8px; }
.voice-msg .voice-wave {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 26px;
  display: flex;
  align-items: center;
  gap: 2px;
  pointer-events: none;
}
.voice-msg .voice-wave i {
  flex: 1 1 0;
  min-width: 2px;
  max-width: 4px;
  border-radius: 2px;
  background: currentColor;
  opacity: .26;
  animation: none;
  transition: opacity .12s ease, background .12s ease;
}
.voice-msg .voice-wave i.on { opacity: .95; background: var(--accent); }
.msg-row.user .voice-msg .voice-wave i.on { background: #fff; opacity: 1; }
.voice-progress {
  position: absolute;
  left: 0;
  bottom: 3px;
  width: 0;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
  opacity: .85;
  pointer-events: none;
}
.msg-row.user .voice-progress { background: #fff; }
.voice-time {
  flex: none;
  min-width: 36px;
  text-align: right;
  font-size: 11.5px;
  line-height: 1.2;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.msg-row.user .voice-time { color: rgba(255, 255, 255, .84); }
.voice-msg.playing .voice-play { background: rgba(79, 140, 255, .42); }
.msg-row.user .voice-msg.playing .voice-play { background: rgba(255, 255, 255, .32); }
.voice-msg.failed .voice-time { color: var(--danger); }
.voice-msg.failed .voice-wave i { opacity: .12; }
.msg-row.voice-message .msg-bubble { padding-right: 10px; }
.msg-row.system { justify-content: center; margin: 8px 0; }

/* ------------------------------------------------------------ 酒馆：对话 / 叙述 / 动作 */
/* 对话还是普通聊天气泡（.msg-bubble），.msg-dialogue 只做语义标记；
   叙述 / 动作没有气泡尾巴和底色，用左侧 2px 竖线 + 更淡的字区分开。 */
.msg-narration,
.msg-action {
  max-width: 100%;
  padding: 2px 0 2px 10px;
  border-left: 2px solid rgba(255, 255, 255, .16);
  background: transparent;
  color: rgba(230, 235, 245, .72);
  font-size: 13.5px;
  line-height: 1.7;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.msg-action {
  border-left-color: rgba(139, 92, 246, .42);
  color: rgba(214, 222, 240, .58);
  font-style: italic;
}
.msg-narration .msg-body,
.msg-action .msg-body { white-space: normal; }
/* 同一头像下的多块之间留一点缝，但不影响单独一条气泡 */
.msg-col > .msg-dialogue:not(:first-child),
.msg-col > .msg-narration:not(:first-child),
.msg-col > .msg-action:not(:first-child) { margin-top: 5px; }
@media (hover: none) {
  .msg-bubble { -webkit-touch-callout: none; user-select: none; }
  .msg-body pre, .msg-body code { user-select: text; }
}
.system-bubble {
  max-width: 92%;
  padding: 7px 12px;
  border-radius: 12px;
  border: 1px dashed var(--line);
  background: rgba(11, 14, 20, .46);
  color: var(--muted);
  font-size: 12.5px;
  text-align: center;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.time-divider { display: flex; justify-content: center; margin: 10px 0 3px; padding: 0 8px; }
.time-divider span {
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(8, 12, 20, .5);
  border: 1px solid rgba(255, 255, 255, .06);
  color: rgba(233, 237, 246, .64);
  font-size: 11px;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

/* ------------------------------------------------------------ Markdown */
.msg-body p { margin: 0 0 7px; }
.msg-body p:last-child { margin-bottom: 0; }
.msg-body h1, .msg-body h2, .msg-body h3, .msg-body h4 {
  margin: 8px 0 5px;
  line-height: 1.35;
}
.msg-body h1 { font-size: 18px; }
.msg-body h2 { font-size: 16.5px; }
.msg-body h3 { font-size: 15.5px; }
.msg-body h4 { font-size: 14.5px; }
.msg-body ul, .msg-body ol { margin: 4px 0 7px; padding-left: 20px; }
.msg-body li { margin: 2px 0; }
.msg-body blockquote {
  margin: 6px 0;
  padding: 2px 0 2px 10px;
  border-left: 3px solid rgba(79, 140, 255, .6);
  color: rgba(233, 237, 246, .84);
}
.msg-body hr {
  border: 0;
  height: 1px;
  margin: 9px 0;
  background: rgba(255, 255, 255, .18);
}
.msg-body a { color: #9cc2ff; text-decoration: underline; }
.msg-row.user .msg-body a { color: #eef5ff; }
.msg-body code {
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: .92em;
  background: rgba(0, 0, 0, .26);
  padding: 1px 5px;
  border-radius: 6px;
}
.msg-row.user .msg-body code { background: rgba(0, 0, 0, .22); }
.msg-body pre {
  margin: 6px 0;
  padding: 10px 11px;
  border-radius: 10px;
  background: rgba(4, 7, 12, .72);
  border: 1px solid rgba(255, 255, 255, .07);
  overflow-x: auto;
  max-width: 100%;
  white-space: pre;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.msg-body pre code {
  display: block;
  padding: 0;
  background: transparent;
  white-space: pre;
  font-size: 12.5px;
  line-height: 1.55;
}
.code-wrap { position: relative; margin: 6px 0; max-width: 100%; }
.code-copy {
  position: absolute;
  top: 5px;
  right: 5px;
  z-index: 1;
  padding: 2px 8px;
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: 7px;
  background: rgba(30, 39, 58, .9);
  color: var(--muted);
  font-size: 11px;
}
.code-copy:active { background: rgba(79, 140, 255, .3); color: #fff; }

/* ------------------------------------------------------------ 语音输入 / 设置 */
.mic {
  flex: none;
  width: 40px;
  height: 40px;
  margin-bottom: 2px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--panel);
  font-size: 18px;
  line-height: 1;
}
.mic.recording {
  border-color: rgba(255, 95, 109, .6);
  background: rgba(255, 95, 109, .18);
  box-shadow: 0 0 0 4px rgba(255, 95, 109, .12);
  animation: micpulse 1.2s infinite ease-in-out;
}
@keyframes micpulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .55; }
}
.bg-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; margin-bottom: 8px; }
.bg-choice {
  position: relative;
  aspect-ratio: 16 / 9;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 12px;
  overflow: hidden;
  background: var(--panel-2);
}
.bg-choice img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bg-choice.active { border-color: var(--accent); box-shadow: 0 0 0 1px rgba(79, 140, 255, .35) inset; }
.bg-choice .bg-label {
  position: absolute;
  left: 6px;
  bottom: 6px;
  max-width: calc(100% - 12px);
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(4, 7, 12, .6);
  color: #fff;
  font-size: 10.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.bg-choice.add {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 3px;
  border: 1px dashed var(--line);
  color: var(--muted);
  font-size: 12px;
  background: rgba(255, 255, 255, .03);
}
.bg-choice.add span:first-child { font-size: 20px; }
.setting-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 0;
  font-size: 14px;
}
.setting-row input[type="checkbox"] {
  flex: none;
  width: 44px;
  height: 26px;
  margin: 0;
  border-radius: 999px;
  border: 0;
  appearance: none;
  -webkit-appearance: none;
  background-color: rgba(255, 255, 255, .16);
  background-image: radial-gradient(circle at 13px 50%, #fff 0 9px, transparent 10px);
  background-repeat: no-repeat;
  transition: background-color .15s;
}
.setting-row input[type="checkbox"]:checked {
  background-color: var(--accent);
  background-image: radial-gradient(circle at 31px 50%, #fff 0 9px, transparent 10px);
}
.field-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 0;
  font-size: 14px;
}
.field-row select {
  flex: 1;
  min-width: 0;
  max-width: 62%;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-soft);
  outline: none;
}
.slider-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  color: var(--muted);
  font-size: 13px;
}
.slider-row input[type="range"] { flex: 1; min-width: 0; accent-color: var(--accent); }
.slider-row b { flex: none; width: 44px; text-align: right; color: var(--text); font-weight: 600; }
.avatar-setting { display: flex; align-items: center; gap: 13px; }
.avatar-preview {
  flex: none;
  width: 64px;
  height: 64px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  overflow: hidden;
  background: linear-gradient(135deg, #26334f, #171f30);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.avatar-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.avatar-preview .avatar-letter { font-size: 26px; }
.avatar-setting-body { flex: 1; min-width: 0; }
.btn-row { display: flex; flex-wrap: wrap; gap: 8px; }
.subhead { margin: 14px 0 8px; color: var(--muted); font-size: 12.5px; font-weight: 500; }
.gallery-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; }
.gallery-item {
  position: relative;
  aspect-ratio: 1 / 1;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 10px;
  overflow: hidden;
  background: var(--panel-2);
}
.gallery-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gallery-item.active { border-color: var(--accent); }

/* ------------------------------------------------------------ 大图 / 长按菜单 */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(0, 0, 0, .97);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
}
.lightbox img {
  max-width: 96vw;
  max-height: 78vh;
  border-radius: 12px;
  box-shadow: var(--shadow);
  object-fit: contain;
}
.lightbox-close {
  position: absolute;
  top: max(14px, env(safe-area-inset-top));
  right: 16px;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 50%;
  background: rgba(20, 26, 40, .86);
  color: #fff;
  font-size: 24px;
  line-height: 1;
}
.lightbox-save {
  position: absolute;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 26px);
  transform: translateX(-50%);
  padding: 10px 24px;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, .24);
  background: rgba(32, 40, 58, .94);
  color: #fff;
  font-size: 14px;
  font-weight: 600;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .45);
}
.lightbox-save:active { transform: translateX(-50%) scale(.95); }
.lightbox-tip {
  position: absolute;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 78px);
  transform: translateX(-50%);
  color: rgba(233, 237, 246, .5);
  font-size: 11px;
  pointer-events: none;
}
.sheet-mask { position: fixed; inset: 0; z-index: 80; background: rgba(0, 0, 0, .46); }
.sheet {
  position: fixed;
  left: 50%;
  bottom: calc(var(--tabh) + env(safe-area-inset-bottom) + 12px);
  transform: translateX(-50%);
  z-index: 90;
  width: min(88vw, 360px);
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: rgba(20, 26, 40, .98);
  box-shadow: var(--shadow);
}
.sheet button {
  padding: 12px;
  border: 0;
  border-radius: 11px;
  background: rgba(255, 255, 255, .05);
  font-size: 14.5px;
}
.sheet button.cancel { color: var(--muted); }


/* ------------------------------------------------------------ 分作用域对话（聊天 / 酒馆 / 世界）
   三个 Tab 各有各的 .messages 容器，切 Tab 只切显示、不重建 DOM，
   所以消息和滚动位置都留在各自那一栏。 */
.view.chat-mode { padding: 0; overflow: hidden; }
.chat-pane {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  width: 100%;
}
.rp-head { flex: none; margin: 10px 14px 0; }
.rp-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 14.5px;
  color: var(--text);
}
.world-conv {
  margin-top: 16px;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, .07);
}
.conv-head { margin-bottom: 6px; color: var(--faint); font-size: 12px; }
/* 世界会话现在跟正文一起在 #worldScroll 里滚：
   不再套一层 max-height 小滚动框，所以不会再有「第一条气泡卡在上沿」
   的问题；padding-top 仍然留着，段落之间不贴边。 */
.world-messages {
  flex: none;
  max-height: none;
  padding: 10px 0 6px;
  overflow: visible;
  -webkit-mask-image: none;
  mask-image: none;
}

/* ------------------------------------------------------------ 世界：正文翻页 */
#worldReader .story { margin-top: 4px; gap: 0; }
#worldReader .world-section-body { font-size: 15.5px; line-height: 1.9; }
.world-page-card { margin: 0; }

.world-pager {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 8px 0 4px;
  border-top: 1px solid rgba(255, 255, 255, .06);
}
.world-page-btn { flex: none; padding: 5px 9px; font-size: 12px; }
.world-page-btn:disabled { opacity: .38; }
.world-page-label {
  flex: 1;
  min-width: 0;
  text-align: center;
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.world-page-note {
  flex: 0 0 100%;
  text-align: center;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--warn);
}

.world-choices-wrap { flex: none; padding-top: 8px; }
.world-choices-fixed { margin-top: 0; gap: 8px; }
.world-pick-note { padding: 2px 2px 6px; font-size: 12px; color: var(--ok); }

/* 选项只保留底部这一处：会话区不再渲染带选项的正文卡片 */
#worldScrollBottom { display: none; }

/* 键盘弹出（可视高度 ~500px）时先把翻页条 / 选项让出来，保证输入框不被顶出屏幕；
   键盘收起后自动回来。 */
@media (max-height: 560px) {
  #worldReader .world-pager,
  #worldChoicesWrap { display: none; }
}

/* ------------------------------------------------------------ 世界：正文 / 选项分开 */
/* 正文：占满宽度的独立卡片，没有气泡尾巴，衬线字体 + 更暗的底色 */
.world-section {
  display: block;
  width: 100%;
  margin: 10px 0;
}
.world-section-card {
  width: 100%;
  padding: 14px 14px 12px;
  border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, .075);
  background: linear-gradient(170deg, rgba(12, 16, 26, .97), rgba(8, 11, 18, .97));
  box-shadow: 0 8px 24px rgba(0, 0, 0, .28);
}
.world-section-label {
  margin: 0 0 9px;
  color: var(--muted);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .06em;
}
.world-section-body {
  color: var(--text);
  font-family: Georgia, "Songti SC", "Noto Serif SC", "Source Han Serif SC", serif;
  font-size: 15px;
  line-height: 1.85;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
/* 选项：正文下方三条横向按钮（描边 + 左侧序号圆点） */
.world-section-choices {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 14px;
}
.world-choice {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 10px 12px;
  border-radius: 12px;
  border: 1px solid rgba(139, 92, 246, .38);
  background: rgba(139, 92, 246, .08);
  color: var(--text);
  font-size: 13px;
  line-height: 1.5;
  text-align: left;
}
.world-choice:active { transform: scale(.985); }
.world-choice:disabled { opacity: .5; }
.world-choice-num {
  flex: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(139, 92, 246, .28);
  color: #fff;
  font-size: 11.5px;
  font-style: normal;
  font-weight: 700;
}
.world-choice span { flex: 1; min-width: 0; }
.world-picked {
  margin-top: 10px;
  color: var(--muted);
  font-size: 12px;
}
.world-picked.hidden { display: none; }
/* 世界里的其它内容（系统提示 / 报错 / 非叙事回复）：小一号的灰气泡 */
.msg-row.small .msg-bubble { font-size: 12.5px; opacity: .86; }
.msg-row.system.small .system-bubble { font-size: 11.5px; opacity: .8; }
/* 阅读区的正文卡片沿用同一套视觉 */
.story .world-story-card {
  padding: 14px;
  border: 1px solid rgba(255, 255, 255, .075);
  background: linear-gradient(170deg, rgba(12, 16, 26, .97), rgba(8, 11, 18, .97));
}

/* ------------------------------------------------------------ 世界设定抽屉 */
.world-set-drawer { width: 86%; max-width: 340px; }
.world-set-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 0 14px 8px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.world-set-title { margin: 0 0 2px; }
.world-set-field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  color: var(--muted);
  font-size: 12px;
}
.world-set-field input,
.world-set-field textarea {
  width: 100%;
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-soft);
  color: var(--text);
  font-size: 13px;
  line-height: 1.5;
  outline: none;
  resize: vertical;
}
.world-set-field input:focus,
.world-set-field textarea:focus { border-color: rgba(139, 92, 246, .55); }
.world-set-write { align-self: flex-start; margin: -2px 0 2px; }
.world-set-actions { display: flex; gap: 10px; margin-top: 4px; }
.world-set-actions .btn { flex: 1; }

/* ------------------------------------------------------------ 角色卡编辑（全屏） */
.card-edit-page {
  position: fixed;
  inset: 0;
  z-index: 95;
  display: flex;
  flex-direction: column;
  background: var(--bg);
}
.card-edit-page.hidden { display: none; }
.card-edit-head {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: calc(env(safe-area-inset-top, 0px) + 12px) 14px 10px;
  border-bottom: 1px solid var(--line);
  background: rgba(13, 17, 26, .96);
}
.card-edit-head b { font-size: 15px; }
.card-edit-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.card-edit-badge {
  padding: 8px 10px;
  border-radius: 10px;
  border: 1px solid rgba(255, 176, 32, .35);
  background: rgba(255, 176, 32, .12);
  color: #ffe4b3;
  font-size: 12px;
}
.card-edit-badge.hidden { display: none; }
.card-edit-details { color: var(--muted); font-size: 12px; }
.card-edit-details summary { cursor: pointer; margin-bottom: 6px; }
.card-edit-details textarea {
  width: 100%;
  margin-top: 4px;
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-soft);
  color: var(--text);
  font-size: 13px;
  line-height: 1.5;
  outline: none;
  resize: vertical;
}

/* 卡池上的「聊过 / 正在演」小标 */
.role-badges .tag.soft { background: rgba(255, 255, 255, .06); color: var(--muted); }

/* ------------------------------------------------------------ 新版提示条
   壳版本比 dist/version.json 旧时才出现；点整条 = 去下载，✕ = 关掉这次提示。 */
.update-bar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 8px 12px 0;
  padding: 9px 12px;
  border-radius: 12px;
  background: rgba(79, 140, 255, .16);
  border: 1px solid rgba(79, 140, 255, .38);
  color: #dbe6ff;
  font-size: 13px;
  line-height: 1.45;
  cursor: pointer;
  user-select: none;
}
.update-bar.urgent {
  background: rgba(255, 176, 32, .14);
  border-color: rgba(255, 176, 32, .42);
  color: #ffe4b3;
}
.update-bar:active { filter: brightness(1.12); }
.update-bar-go {
  flex: 1;
  min-width: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.update-bar-text { display: block; }
.update-bar-close {
  flex: none;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 0;
  border-radius: 8px;
  background: rgba(255, 255, 255, .08);
  color: inherit;
  font-size: 12px;
  line-height: 1;
}
.update-bar-close:active { background: rgba(255, 255, 255, .16); }

/* ------------------------------------------------------------ 服务页 */
.svc-list { display: flex; flex-direction: column; gap: 12px; }
.svc-card { margin: 0; }
.svc-card .card-head { gap: 8px; }
.svc-title { display: flex; align-items: center; gap: 8px; min-width: 0; }
.svc-dot {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--faint);
  box-shadow: 0 0 0 4px rgba(255, 255, 255, .05);
}
.svc-dot.on { background: var(--ok); box-shadow: 0 0 0 4px rgba(61, 220, 151, .14); }
.svc-dot.warn { background: var(--warn); box-shadow: 0 0 0 4px rgba(255, 176, 32, .14); }
.svc-dot.off { background: var(--danger); box-shadow: 0 0 0 4px rgba(255, 95, 109, .12); }
.svc-state { font-size: 12.5px; }
.svc-busy { color: var(--warn); }
.svc-actions { margin-top: 10px; }
.svc-actions .btn { padding: 8px 12px; font-size: 13px; }
.svc-actions .btn:disabled { cursor: default; }

/* 版本卡片里的下载地址：允许长按选中 / 复制 */
.selectable { user-select: text; -webkit-user-select: text; overflow-wrap: anywhere; }
.page-head #svcRefresh { flex: none; white-space: nowrap; }
.kv .btn-row { margin-top: 10px; }
.chip.off {
  background: rgba(255, 95, 109, .14);
  border-color: rgba(255, 95, 109, .34);
  color: #ffd7da;
}

/* ============================================================ 第五阶段：新建 / 搜索 / 精简输入框
   1) 聊天输入框左侧只留一个「＋」，点开底部 sheet（发图 / 生图 / 生视频 / 读链接 / 语音）
   2) 卡池 / 世界：sticky 搜索 + 排序 + 「⋯」菜单
   3) 语音输入按住说话：整块 composer 不可选中，消息气泡仍可复制
   4) 开发模式：聊天页顶部黄色小条 */

/* ------------------------------------------------------------ 输入框 */
.composer,
.composer-plus,
.composer .send {
  user-select: none;
  -webkit-user-select: none;
}
.composer textarea,
.composer input[type="text"] {
  user-select: text;
  -webkit-user-select: text;
  touch-action: manipulation;
}
.composer-plus {
  flex: none;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--panel);
  color: var(--text);
  font-size: 22px;
  font-weight: 400;
  line-height: 1;
}
.composer-plus:active { background: rgba(255, 255, 255, .08); transform: scale(.96); }
.composer-plus[aria-expanded="true"] { border-color: rgba(79, 140, 255, .6); color: #cfe0ff; }

/* 酒馆 / 世界：命令入口（☰）放在输入框左边，和聊天「＋」同一位置。
   40px 圆形：390 宽下 40 + 8 + 输入框 flex + 8 + 44 的发送仍不挤。
   抽屉打开时输入框和发送禁用，但 ☰ 保持可点，再点一下就能收回去。 */
.composer-cmd {
  flex: none;
  width: 40px;
  height: 40px;
  align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--panel);
  color: var(--text);
  font-size: 18px;
  font-weight: 400;
  line-height: 1;
  user-select: none;
  -webkit-user-select: none;
}
.composer-cmd:active { background: rgba(255, 255, 255, .08); transform: scale(.96); }
.composer-cmd[aria-expanded="true"] {
  border-color: rgba(79, 140, 255, .6);
  color: #cfe0ff;
}
/* 酒馆会话是 chat-mode（外层 padding 0），左右各留 14px 和 rp-head 对齐；
   世界聊天本身在 14px 的 view padding 里，不用再补。 */
#rpComposer { padding-left: 14px; padding-right: 14px; }

/* 输入框左侧常驻麦克风：按住说话 */
.composer-mic {
  flex: none;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--panel);
  color: var(--muted);
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
.composer-mic:active { background: rgba(255, 255, 255, .08); transform: scale(.96); }
.composer-mic.recording {
  border-color: rgba(255, 95, 109, .55);
  background: rgba(255, 95, 109, .18);
  color: #ffd7da;
  animation: micring 1.1s infinite ease-in-out;
}

/* 麦克风旁边的「语音条」开关：开 = 下一次录音直接发原声（需要 App 壳的原生录音） */
.composer-clip {
  flex: none;
  height: 32px;
  padding: 0 8px;
  align-self: center;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--panel);
  color: var(--muted);
  font-size: 11px;
  line-height: 1;
  white-space: nowrap;
  touch-action: manipulation;
}
.composer-clip.on {
  border-color: rgba(79, 140, 255, .62);
  background: rgba(79, 140, 255, .18);
  color: #cfe0ff;
}
.composer-clip:active { transform: scale(.96); }
@keyframes micring {
  0%, 100% { box-shadow: 0 0 0 0 rgba(255, 95, 109, .35); }
  50% { box-shadow: 0 0 0 7px rgba(255, 95, 109, 0); }
}

/* 语音录音条（红点 + 波形）
   录音时它「原地」盖在输入框那一行上：同宽、同圆角(20px)、固定 44px 高，
   不额外占高度、不压消息列表、不弹居中 toast。
   输入框仍留在 DOM 里并保持焦点（内容和光标位置都不丢），
   状态条整体 pointer-events: none，只有「取消/停止」按钮可点。 */
.composer-field {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
}
.composer-field textarea { flex: 1; width: 100%; }
.voice-bar {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  z-index: 2;
  height: 44px;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 10px 0 14px;
  border-radius: 20px;
  border: 1px solid rgba(255, 95, 109, .42);
  background:
    linear-gradient(180deg, rgba(255, 95, 109, .17), rgba(255, 95, 109, .09)),
    var(--panel);
  color: #ffe3e5;
  font-size: 12.5px;
  line-height: 1.2;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .26);
  pointer-events: none;
}
/* 录音期间输入框还在原位，只是文字让位给状态条；value 保留，不 style.height 抽动 */
.composer.voice-live #chatInput {
  height: 44px !important;
  min-height: 44px;
  color: transparent;
  caret-color: transparent;
}
.composer.voice-live #chatInput::placeholder { color: transparent; }
.composer.voice-live #chatInput:focus { box-shadow: none; }
/* 状态条占满整行，先把三个圆按钮收起来（不会多占高度，收手就回来） */
.composer.voice-live .composer-plus,
.composer.voice-live .composer-mic,
.composer.voice-live .composer-clip,
.composer.voice-live .send { display: none; }
/* 上滑超过阈值：整条变红 */
.voice-bar.cancel {
  background:
    linear-gradient(180deg, rgba(255, 59, 48, .42), rgba(255, 59, 48, .26)),
    var(--panel);
  border-color: rgba(255, 69, 58, .92);
  color: #ffd9d7;
  box-shadow: 0 6px 22px rgba(255, 59, 48, .32);
}
.voice-bar.cancel .voice-dot { background: #ff453a; animation: none; }
.voice-bar.cancel .voice-wave { opacity: .5; animation: none; }
.voice-dot {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--danger);
  animation: micpulse 1s infinite ease-in-out;
}
.voice-wave {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  height: 16px;
}
.voice-wave i {
  width: 3px;
  height: 7px;
  border-radius: 2px;
  background: currentColor;
  animation: voicewave 0.9s infinite ease-in-out;
}
.voice-wave i:nth-child(2) { animation-delay: .1s; }
.voice-wave i:nth-child(3) { animation-delay: .2s; }
.voice-wave i:nth-child(4) { animation-delay: .3s; }
.voice-wave i:nth-child(5) { animation-delay: .4s; }
@keyframes voicewave {
  0%, 100% { transform: scaleY(.55); }
  50% { transform: scaleY(1.7); }
}
.voice-bar #voiceBarText {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.voice-bar button {
  flex: none;
  pointer-events: auto;
  min-height: 30px;
  padding: 4px 12px;
  border-radius: 999px;
  border: 1px solid rgba(255, 95, 109, .5);
  background: rgba(255, 95, 109, .2);
  color: #ffe3e5;
  font-size: 12px;
}
.voice-bar.cancel button {
  border-color: rgba(255, 159, 154, .55);
  background: rgba(255, 59, 48, .22);
  color: #ffd9d7;
}
@media (prefers-reduced-motion: reduce) {
  .voice-dot, .voice-wave i { animation: none; }
  .voice-wave i { transform: scaleY(1); }
}

/* 开发模式小条 */
.devmode-bar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 10px 14px 0;
  padding: 8px 12px;
  border-radius: 12px;
  background: rgba(255, 176, 32, .16);
  border: 1px solid rgba(255, 176, 32, .4);
  color: #ffe4b3;
  font-size: 12.5px;
  line-height: 1.45;
}
.devmode-bar span { flex: 1; min-width: 0; }
/* 设置页那行删掉后，转交 / 待回复统计改在这里显示（紧凑一行） */
.devmode-bar .devmode-bar-stats {
  flex: none;
  margin-left: 6px;
  font-style: normal;
  opacity: .82;
  white-space: nowrap;
}
.devmode-bar button {
  flex: none;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid rgba(255, 176, 32, .45);
  background: rgba(255, 176, 32, .12);
  color: inherit;
  font-size: 12px;
}
/* 转交 / 待回复数字变化时轻脉冲一下 */
.devmode-bar .devmode-bar-stats.pulse {
  display: inline-block;
  animation: devstatpulse 700ms ease-out;
}
@keyframes devstatpulse {
  0% { transform: scale(1); color: #ffe4b3; }
  30% { transform: scale(1.14); color: #ffd27a;
        text-shadow: 0 0 8px rgba(255, 176, 32, .55); }
  100% { transform: scale(1); color: #ffe4b3; }
}
@media (prefers-reduced-motion: reduce) {
  .devmode-bar .devmode-bar-stats.pulse { animation: none; }
}

/* ------------------------------------------------------------ 底部 sheet 通用 */
.sheet-title {
  padding: 4px 10px 2px;
  color: var(--muted);
  font-size: 12.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sheet button.danger {
  color: #ffd7da;
  background: rgba(255, 95, 109, .12);
}

/* 「＋」：QQ 风格图标网格（图标大、文字小，无取消行） */
.tools-sheet {
  left: 0;
  right: 0;
  bottom: 0;
  transform: none;
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  gap: 0;
  padding: 7px 14px calc(16px + env(safe-area-inset-bottom));
  border: 1px solid rgba(255, 255, 255, .1);
  border-bottom: 0;
  border-radius: 24px 24px 0 0;
  background: rgba(20, 24, 36, .72);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  backdrop-filter: blur(20px) saturate(150%);
  box-shadow: 0 -18px 48px rgba(0, 0, 0, .5);
  animation: tools-up .22s cubic-bezier(.22, .9, .28, 1);
  touch-action: pan-y;
}
.tools-sheet.closing {
  animation: tools-down .18s ease-in forwards;
  pointer-events: none;
}
@keyframes tools-up {
  from { transform: translateY(104%); opacity: .55; }
  to { transform: translateY(0); opacity: 1; }
}
@keyframes tools-down {
  from { transform: translateY(0); opacity: 1; }
  to { transform: translateY(104%); opacity: .4; }
}
.tools-mask { animation: tools-mask-in .2s ease-out; }
.tools-mask.closing { animation: tools-mask-out .18s ease-in forwards; }
@keyframes tools-mask-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes tools-mask-out {
  from { opacity: 1; }
  to { opacity: 0; }
}
.sheet-grip {
  flex: none;
  width: 44px;
  height: 4px;
  margin: 1px auto 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .26);
}
.tools-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px 8px;
  padding: 12px 2px 8px;
}
.tools-sheet .tool-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 1px 0 3px;
  border: 0;
  border-radius: 18px;
  background: transparent;
  text-align: center;
}
.tool-icon {
  width: 76px;
  height: 76px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 18px;
  border: 1px solid rgba(255, 255, 255, .13);
  background: linear-gradient(160deg, rgba(255, 255, 255, .13),
              rgba(255, 255, 255, .045));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .09),
              0 6px 18px rgba(0, 0, 0, .2);
  font-size: 28px;
  line-height: 1;
  transition: transform .12s ease, background .12s ease;
}
.tool-label {
  max-width: 84px;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color .12s ease;
}
.tools-sheet .tool-tile:active { background: rgba(255, 255, 255, .035); }
.tool-tile:active .tool-icon {
  transform: scale(.93);
  background: linear-gradient(160deg, rgba(79, 140, 255, .28),
              rgba(79, 140, 255, .12));
}
.tool-tile:active .tool-label { color: var(--text); }
.tools-sheet.dragging { animation: none; }
/* 表单 / 确认 / loading：底部整宽滑出 */
.sheet.form-sheet {
  left: 0;
  right: 0;
  bottom: 0;
  transform: none;
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  gap: 10px;
  max-height: 88vh;
  overflow-y: auto;
  border-radius: 20px 20px 0 0;
  padding: 16px 16px calc(16px + env(safe-area-inset-bottom));
  animation: sheet-up .18s ease-out;
}
@keyframes sheet-up {
  from { transform: translateY(20px); opacity: .55; }
  to { transform: none; opacity: 1; }
}
.form-field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  color: var(--muted);
  font-size: 12.5px;
}
.form-field input,
.form-field textarea {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-soft);
  color: var(--text);
  font-size: 14.5px;
  outline: none;
  resize: none;
}
.form-field input:focus,
.form-field textarea:focus { border-color: rgba(79, 140, 255, .6); }
.form-sheet h3 { font-size: 15.5px; }
.form-sheet .btn-row { margin-top: 2px; }
.form-sheet .btn { flex: 1; }
.loading-sheet { text-align: center; gap: 7px; }
.loading-sheet h3 { font-size: 15px; }
.spinner {
  width: 30px;
  height: 30px;
  margin: 2px auto;
  border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .16);
  border-top-color: var(--accent);
  animation: spin .9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.loading-sheet .ghost { width: 100%; margin-top: 2px; }

/* ------------------------------------------------------------ 列表：搜索 / 排序 */
.page-head > div:first-child { min-width: 0; }
.head-actions {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
}
.head-btn { padding: 7px 11px; border-radius: 10px; font-size: 12.5px; white-space: nowrap; }
/* 卡池 / 世界：sticky 毛玻璃搜索条（不再是黑砖）
   - sticky 时离顶部 8px，左右与卡片对齐
   - 输入框本体透明，聚焦才描边 accent
   - 排序下拉同一视觉 */
.list-search {
  position: sticky;
  top: 8px;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 12px;
  padding: 8px;
  border-radius: 16px;
  background: rgba(20, 24, 36, .55);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  backdrop-filter: blur(18px) saturate(140%);
  border: 1px solid rgba(255, 255, 255, .08);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .25);
}
.list-search input[type="search"] {
  flex: 1;
  min-width: 0;
  padding: 9px 13px;
  border: 1px solid rgba(255, 255, 255, .10);
  border-radius: 12px;
  background: transparent;
  color: var(--text);
  font-size: 14px;
  outline: none;
  transition: border-color .15s, box-shadow .15s, background .15s;
}
.list-search input[type="search"]::placeholder { color: var(--faint); }
.list-search input[type="search"]:focus {
  border-color: rgba(79, 140, 255, .72);
  background: rgba(79, 140, 255, .08);
  box-shadow: 0 0 0 3px rgba(79, 140, 255, .16);
}
.search-count { flex: none; color: var(--faint); font-size: 11.5px; }
.list-search select {
  flex: none;
  max-width: 104px;
  padding: 8px 8px;
  border: 1px solid rgba(255, 255, 255, .10);
  border-radius: 12px;
  background: rgba(255, 255, 255, .06);
  color: var(--text);
  font-size: 12.5px;
  outline: none;
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.list-search select:focus { border-color: rgba(79, 140, 255, .6); }
.world-actions { margin: -2px 0 10px; }
.world-actions .btn { flex: 1; padding: 9px 8px; font-size: 13px; white-space: nowrap; }
.empty-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
}

/* 卡片 / 世界的「⋯」 */
.role-card { cursor: pointer; }
.world-item { position: relative; cursor: pointer; }
/* 给右上角「⋯」留出位置，长标题不会压到按钮下面 */
.world-item h3 { padding-right: 30px; }
.role-more,
.world-more {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 2;
  width: 28px;
  height: 28px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 50%;
  background: rgba(8, 12, 20, .7);
  color: var(--muted);
  font-size: 15px;
  line-height: 1;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.role-more:active,
.world-more:active { background: rgba(79, 140, 255, .3); color: #fff; }

/* 消息气泡里仍然可以选中复制 */
.msg-bubble,
.msg-body,
.system-bubble,
.section .body { user-select: text; -webkit-user-select: text; }

/* ------------------------------------------------------------ 开发模式回程 */
/* 开发消息：灰蓝虚线 + 「🛠 开发」角标，和她的正常气泡一眼区分 */
.msg-row.dev .msg-bubble {
  background: rgba(44, 56, 76, .74);
  border: 1px dashed rgba(150, 175, 210, .5);
  color: #e6edf8;
  box-shadow: 0 4px 16px rgba(0, 0, 0, .16);
}
.msg-row.dev.user .msg-bubble {
  background: rgba(56, 70, 92, .8);
  border-color: rgba(160, 185, 220, .52);
}
/* 开发者回复：浅青底 + 「开发者回复」角标 */
.msg-row.dev.assistant.dev-reply .msg-bubble {
  background: rgba(22, 62, 58, .76);
  border: 1px solid rgba(96, 214, 186, .42);
  color: #dff7f0;
}
.msg-row.dev.user .msg-bubble::after { border-left-color: rgba(56, 70, 92, .8); }
.msg-row.dev.assistant .msg-bubble::after { border-right-color: rgba(44, 56, 76, .74); }
.msg-row.dev.assistant.dev-reply .msg-bubble::after { border-right-color: rgba(22, 62, 58, .76); }
.dev-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 5px;
  padding: 1px 7px;
  border-radius: 999px;
  border: 1px solid rgba(160, 185, 220, .35);
  background: rgba(140, 165, 200, .16);
  color: #c8d7ea;
  font-size: 10.5px;
  line-height: 1.6;
  font-weight: 600;
  letter-spacing: .02em;
}
.dev-badge.reply {
  border-color: rgba(110, 220, 190, .4);
  background: rgba(80, 210, 180, .14);
  color: #bff0e2;
}
.time-divider.dev span {
  color: #b7c9de;
  border-color: rgba(150, 180, 220, .28);
}
.dev-wait-tag {
  align-self: flex-end;
  margin-top: 4px;
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px dashed rgba(150, 165, 190, .4);
  background: rgba(120, 135, 160, .14);
  color: #9da9bb;
  font-size: 11px;
  line-height: 1.6;
}

/* 筛选只影响显示，不删 DOM */
.msg-row.filtered-out,
.time-divider.filtered-out { display: none !important; }

/* 设置页内容不能被 flex 压缩：否则下面的卡片会被挤没、页面也不产生滚动 */
#view-settings > * { flex-shrink: 0; }

/* 顶栏漏斗筛选菜单（JS 按按钮位置定位） */
.filter-menu {
  position: fixed;
  z-index: 70;
  width: 174px;
  padding: 6px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: rgba(18, 24, 36, .97);
  box-shadow: 0 16px 40px rgba(0, 0, 0, .48);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
}
.filter-menu button {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 11px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--text);
  font-size: 13.5px;
  text-align: left;
}
.filter-menu button b {
  flex: none;
  color: var(--muted);
  font-size: 11.5px;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .07);
}
.filter-menu button.active {
  background: rgba(79, 140, 255, .18);
  color: #fff;
}
.filter-menu button.active b {
  color: #dbe8ff;
  background: rgba(79, 140, 255, .26);
}

/* ------------------------------------------------------------ 设置页 */
.settings-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 2px 2px 6px;
}
.settings-head h2 { margin: 0; font-size: 20px; }
.settings-instant { color: var(--muted); font-size: 11.5px; }
.settings-group {
  margin: 17px 4px 7px;
  color: var(--muted);
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .08em;
}
.settings-card {
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--panel);
  overflow: hidden;
  margin-bottom: 14px;
}
.settings-card-first { margin-top: 2px; }
.settings-card > * + * { border-top: 1px solid rgba(255, 255, 255, .055); }
.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: 56px;
  padding: 12px 14px;
  font-size: 14px;
  flex-wrap: nowrap;
}
.settings-row-top { align-items: flex-start; }
.settings-label {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.settings-label > span {
  display: flex;
  align-items: center;
  gap: 7px;
  color: var(--text);
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.settings-label small {
  color: var(--muted);
  font-size: 12px;
  line-height: 1.45;
  white-space: normal;
  overflow-wrap: anywhere;
}
.settings-control {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  max-width: 45%;
}
.settings-mini-btn {
  flex: none;
  padding: 6px 10px;
  border-radius: 9px;
  font-size: 12.5px;
  white-space: nowrap;
}
.settings-note {
  padding: 0 14px 11px;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.5;
}
.settings-note.kv { padding-top: 10px; }
.settings-note.kv .row { min-height: 0; padding: 2px 0; }
.settings-block { padding: 12px 14px 14px; }
.settings-block .settings-label { margin-bottom: 9px; }
.settings-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 8px 0 2px;
}
.settings-pin-form { margin: 0; }
.settings-check-label {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--muted);
  font-size: 12.5px;
}
.settings-row input[type="checkbox"],
.settings-check-label input[type="checkbox"] {
  flex: none;
  width: 44px;
  height: 26px;
  margin: 0;
  border-radius: 999px;
  border: 0;
  appearance: none;
  -webkit-appearance: none;
  background-color: rgba(255, 255, 255, .16);
  background-image: radial-gradient(circle at 13px 50%, #fff 0 9px, transparent 10px);
  background-repeat: no-repeat;
  transition: background-color .15s;
}
.settings-row input[type="checkbox"]:checked,
.settings-check-label input[type="checkbox"]:checked {
  background-color: var(--accent);
  background-image: radial-gradient(circle at 31px 50%, #fff 0 9px, transparent 10px);
}
.settings-select {
  flex: 1;
  min-width: 0;
  max-width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-soft);
  color: var(--text);
  font-size: 13px;
  outline: none;
}
.settings-slider {
  flex: 1;
  max-width: 45%;
  display: flex;
  align-items: center;
  gap: 10px;
}
.settings-slider input[type="range"] {
  flex: 1;
  min-width: 0;
  accent-color: var(--accent);
}
.settings-slider b {
  flex: none;
  width: 44px;
  text-align: right;
  color: var(--text);
  font-size: 12.5px;
  font-weight: 600;
}
.settings-slider-wide {
  max-width: none;
  width: 100%;
  margin-top: 8px;
  color: var(--muted);
  font-size: 12px;
}
.settings-avatar { gap: 10px; }
.settings-avatar .avatar-preview { width: 44px; height: 44px; }
.settings-avatar .avatar-preview .avatar-letter { font-size: 18px; }
.settings-avatar-btns { display: flex; flex-direction: column; gap: 5px; }
.settings-voice { flex-wrap: nowrap; justify-content: flex-end; }
/* 模型名比较长：比音色下拉宽一点，放不下就省略号 */
.settings-model { max-width: 58%; }
.settings-model .settings-select { text-overflow: ellipsis; }
/* 「未授权（点这里去系统设置）」：看起来可以点 */
.settings-status-link {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.settings-status-link[data-state="granted"] {
  color: var(--muted);
  text-decoration: none;
  cursor: default;
}
.settings-status-link[data-state="none"] {
  color: var(--muted);
  text-decoration: none;
  cursor: default;
}
/* DeepSeek 余额：整行可点，数字等宽 */
.settings-row-balance { cursor: pointer; }
.balance-value {
  font-size: 15px;
  font-weight: 650;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.balance-value.low { color: #ff5c6c; }
.balance-value.is-loading {
  display: inline-block;
  min-width: 56px;
  height: 15px;
  color: transparent;
  border-radius: 6px;
  background: linear-gradient(90deg, rgba(255, 255, 255, .06),
              rgba(255, 255, 255, .18), rgba(255, 255, 255, .06));
  background-size: 200% 100%;
  animation: balanceshine 1.1s linear infinite;
}
@keyframes balanceshine {
  from { background-position: 200% 0; }
  to { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .balance-value.is-loading { animation: none; }
}
.settings-svc-list { display: flex; flex-direction: column; gap: 6px; }
.svc-dot-item {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  width: 100%;
  min-width: 0;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--bg-soft);
  color: var(--muted);
  font-size: 12px;
  text-align: left;
}
.svc-dot-item span {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.svc-state-text {
  flex: none;
  max-width: 48%;
  color: var(--muted);
  font-size: 11px;
  font-style: normal;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.svc-dot-item.on { color: var(--text); border-color: rgba(61, 220, 151, .28); }
.svc-dot-item.on .svc-state-text { color: var(--ok); }
.settings-row .btn.danger {
  background: transparent;
  border: 1px solid rgba(255, 95, 109, .55);
  color: #ffd7da;
}
.pin-fields {
  flex: 0 1 auto;
  max-width: 68%;
  min-width: 0;
  display: flex;
  flex-wrap: nowrap;
  justify-content: flex-end;
  gap: 5px;
}
.pin-fields input {
  flex: 1 1 0;
  width: auto;
  min-width: 0;
  padding: 7px 6px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--bg-soft);
  color: var(--text);
  font-size: 12px;
  text-align: center;
  outline: none;
}
.pin-fields .settings-mini-btn { padding: 7px 8px; }
@media (max-width: 430px) {
  .settings-row-top { flex-direction: row; align-items: center; gap: 10px; }
  .settings-row-top .settings-label small { white-space: normal; }
  .pin-fields { max-width: 68%; }
  .settings-slider { max-width: 45%; }
}

/* ------------------------------------------------------------ 聊天记录搜索 */
.head-icon-btn {
  flex: none;
  padding: 5px 9px;
  font-size: 15px;
  line-height: 1.1;
}
.load-older {
  flex: none;
  display: block;
  margin: 8px auto 0;
  padding: 3px 12px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(8, 12, 20, .45);
  color: var(--muted);
  font-size: 11.5px;
  line-height: 1.6;
}
.load-older:active { background: rgba(79, 140, 255, .16); color: var(--text); }
.search-panel {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  padding: calc(env(safe-area-inset-top, 0px) + 12px) 14px 14px;
}
.search-panel-head {
  flex: none;
  display: flex;
  align-items: center;
  gap: 9px;
}
.search-panel-head input {
  flex: 1;
  min-width: 0;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-soft);
  color: var(--text);
  font-size: 14px;
  outline: none;
}
.search-panel-head input:focus { border-color: rgba(79, 140, 255, .55); }
.search-panel-head button { flex: none; }
.search-meta { flex: none; padding: 8px 2px 6px; min-height: 26px; }
.search-results {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
.search-result {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 10px 4px;
  border: 0;
  border-bottom: 1px solid rgba(255, 255, 255, .06);
  background: transparent;
  color: var(--text);
  text-align: left;
}
.search-result:active { background: rgba(79, 140, 255, .1); }
.search-result .sr-top {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  color: var(--muted);
  font-size: 11.5px;
}
.search-result .sr-text {
  font-size: 13.5px;
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.search-result mark {
  padding: 0 1px;
  border-radius: 3px;
  background: rgba(79, 140, 255, .34);
  color: #fff;
}
.search-result .sr-where { color: var(--faint); }
.search-history { flex: none; max-height: 34%; overflow-y: auto; padding-top: 8px; }
.search-history-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 2px 7px;
  color: var(--muted);
  font-size: 11.5px;
}
.search-history-head button { padding: 2px 8px; font-size: 11.5px; }
.search-history-list { display: flex; flex-wrap: wrap; gap: 7px; }
.search-history-list button {
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(255, 255, 255, .04);
  color: var(--muted);
  font-size: 12px;
}
.search-hit .msg-bubble,
.search-hit .system-bubble {
  animation: searchHitPulse 1.4s ease;
  outline: 2px solid rgba(79, 140, 255, .75);
  outline-offset: 2px;
}
@keyframes searchHitPulse {
  0% { box-shadow: 0 0 0 0 rgba(79, 140, 255, .55); }
  100% { box-shadow: 0 0 0 12px rgba(79, 140, 255, 0); }
}

/* ------------------------------------------------------------ 命令抽屉 */
.cmd-mask {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: rgba(0, 0, 0, .46);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}
.cmd-drawer {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  z-index: 81;
  width: 78%;
  max-width: 320px;
  display: flex;
  flex-direction: column;
  padding: calc(env(safe-area-inset-top, 0px) + 12px) 0 12px;
  background: var(--panel);
  border-right: 1px solid var(--line);
  box-shadow: 18px 0 50px rgba(0, 0, 0, .5);
  transform: translateX(-102%);
  visibility: hidden;
  pointer-events: none;
  transition: transform .22s ease, visibility .22s;
}
.cmd-drawer.open {
  transform: translateX(0);
  visibility: visible;
  pointer-events: auto;
}
.cmd-drawer-head {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 2px 14px 12px;
  color: var(--text);
  font-size: 15px;
  font-weight: 650;
}
.cmd-drawer-head button {
  flex: none;
  padding: 4px 8px;
  font-size: 13px;
}
.cmd-list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 0 10px 8px;
}
.cmd-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 56px;
  padding: 9px 10px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--text);
  text-align: left;
}
.cmd-item + .cmd-item { border-top: 1px solid rgba(255, 255, 255, .055); }
.cmd-item:active { background: rgba(79, 140, 255, .12); }
.cmd-icon { flex: none; width: 24px; text-align: center; font-size: 16px; }
.cmd-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.cmd-text b {
  font-size: 13.5px;
  font-weight: 550;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cmd-text small {
  color: var(--muted);
  font-size: 11.5px;
  line-height: 1.35;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cmd-key {
  flex: none;
  max-width: 42%;
  color: var(--faint);
  font-size: 10.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* 开发者回复很长：字号小一号、行距收一点，避免一条占满整屏 */
.msg-row.dev-reply .msg-body { font-size: 13px; line-height: 1.62; }
.msg-row.dev-reply .msg-body p { margin: 0 0 5px; }
/* ------------------------------------------------------------ 引用消息 */
/* 预览条：在 composer 内部单独占一整行（不压输入框宽度），
   放在按钮那一行之上；隐藏时不占高度。 */
.composer.has-quote {
  flex-wrap: wrap;
  row-gap: 6px;
}
.quote-bar {
  order: -1;
  flex: 0 0 100%;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 8px 5px 10px;
  border-radius: 10px;
  border-left: 3px solid rgba(79, 140, 255, .85);
  background: rgba(79, 140, 255, .13);
  color: rgba(226, 232, 244, .86);
  font-size: 12px;
  line-height: 1.35;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
.quote-bar.hidden { display: none; }
.quote-bar-label {
  flex: none;
  color: rgba(170, 198, 255, .96);
  font-weight: 600;
}
.quote-bar-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.quote-bar-close {
  flex: none;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .10);
  color: var(--muted);
  font-size: 12px;
  line-height: 1;
}
.quote-bar-close:active { background: rgba(255, 255, 255, .18); }

/* 气泡上方的引用块：12px 灰字、左侧 2px 竖线、最多 2 行省略。
   普通 div（没有 tabindex），点它只跳转，不抢输入框焦点。 */
.msg-quote {
  max-width: 100%;
  margin: 0 0 4px;
  padding: 4px 8px 4px 7px;
  border-left: 2px solid rgba(158, 174, 200, .62);
  border-radius: 8px;
  background: rgba(255, 255, 255, .06);
  color: rgba(196, 206, 224, .8);
  font-size: 12px;
  line-height: 1.5;
  text-align: left;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
  word-break: break-word;
}
.msg-row.user .msg-quote {
  background: rgba(255, 255, 255, .16);
  border-left-color: rgba(255, 255, 255, .62);
  color: rgba(255, 255, 255, .88);
}
.msg-quote:active { opacity: .72; }
.msg-quote-label { font-weight: 600; }
.msg-quote-text { white-space: normal; }

/* 点引用块跳过去：高亮 1.5 秒（JS 到点移除 .quote-hit） */
.msg-row.quote-hit .msg-bubble,
.msg-row.quote-hit .system-bubble,
.msg-row.quote-hit .msg-quote {
  outline: 2px solid rgba(255, 196, 84, .85);
  outline-offset: 2px;
  animation: quoteHitPulse 1.5s ease;
}
@keyframes quoteHitPulse {
  0% { box-shadow: 0 0 0 0 rgba(255, 196, 84, .55); }
  100% { box-shadow: 0 0 0 12px rgba(255, 196, 84, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .msg-row.quote-hit .msg-bubble,
  .msg-row.quote-hit .system-bubble,
  .msg-row.quote-hit .msg-quote { animation: none; }
}

/* 空白的叙述/动作块不占高度（避免聊天气泡之间出现诡异空档和竖线） */
.msg-narration:empty, .msg-action:empty { display: none; }
.msg-narration .msg-body:empty, .msg-action .msg-body:empty { display: none; }
