:root {
  color-scheme: light;
  --bg: #f5f5f5;
  --bar: #f5f5f5;
  /* 仅会话列表标题栏 + 聊天标题栏（见 header.top.top-list / .top-chat） */
  --header-title-bg: #e0e0e0;
  /* 介于 #e5e5e5 与过重灰线之间，浅色下能分清又不抢眼 */
  --border: #dadada;
  --text: #191919;
  --muted: #888;
  --bubble-self: #95ec69;
  --bubble-text: #191919;
  --bubble-card: #fff;
  /* 对方气泡（.msg-row-other）专用文字色。要跟 --bubble-card 保持对比，
     不能直接复用 --bubble-text——那是给自己那只绿色气泡准备的，
     深色模式下 --bubble-text 会变成近黑，压在深灰气泡上就完全读不出来。 */
  --bubble-other-text: #191919;
  --accent: #07c160;
  --accent-rgb: 7, 193, 96;
  --danger: #fa5151;
  --shadow: none;
  --scroll-track: rgba(0, 0, 0, 0.05);
  --scroll-thumb: rgba(0, 0, 0, 0.22);
  --scroll-thumb-hover: rgba(0, 0, 0, 0.35);
  --surface: #fff;
  --input-bg: #fff;
  --menu-bg: #fff;
  --menu-hover: #f5f5f5;
  --sheet-bg: #fff;
  --btn-secondary-bg: #f2f2f2;
  --link: #576b95;
  --bubble-link: #576b95;
  --time-pill-bg: rgba(0, 0, 0, 0.25);
  --bubble-border: rgba(0, 0, 0, 0.065);
  --panel-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
  --header-more-hover: rgba(0, 0, 0, 0.06);
  --header-more-active: rgba(0, 0, 0, 0.08);
  --multiselect-ring: #b0b0b0;
  /* 交互动效：统一曲线与时长，抽屉 / 面板 / Sheet 叠在一起时节奏一致、更干净 */
  --motion-ease: cubic-bezier(0.4, 0, 0.2, 1);
  --motion-ease-emphasized: cubic-bezier(0.2, 0, 0, 1);
  --motion-duration: 0.26s;
  --motion-duration-short: 0.18s;
}

[data-theme="dark"] {
  color-scheme: dark;
  /* 深色：底与灰阶略提亮；气泡/强调色恢复微信标准绿 #07c160（--accent-rgb 继承 :root） */
  --bg: #1a1a1a;
  --bar: #252525;
  --header-title-bg: #252525;
  --border: #404040;
  --text: #e6e6e6;
  --muted: #8b8b8b;
  --bubble-self: #07c160;
  --bubble-text: #111111;
  --bubble-card: #323232;
  --bubble-other-text: #e6e6e6;
  --accent: #07c160;
  --danger: #fa5151;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
  --scroll-track: rgba(255, 255, 255, 0.06);
  --scroll-thumb: rgba(255, 255, 255, 0.28);
  --scroll-thumb-hover: rgba(255, 255, 255, 0.42);
  --surface: #2f2f2f;
  --input-bg: #333333;
  --menu-bg: #333333;
  --menu-hover: #3d3d3d;
  --sheet-bg: #333333;
  --btn-secondary-bg: #424242;
  --link: #6b8cce;
  /* 绿色气泡上的链接：偏蓝、可读 */
  --bubble-link: #0d47a1;
  --time-pill-bg: rgba(255, 255, 255, 0.15);
  --bubble-border: rgba(0, 0, 0, 0.12);
  --panel-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
  --header-more-hover: rgba(255, 255, 255, 0.08);
  --header-more-active: rgba(255, 255, 255, 0.12);
  --multiselect-ring: #5c5c5c;
}

* {
  box-sizing: border-box;
}

/* 所有可编辑控件的光标：微信绿（与 --accent 一致），避免深色模式下仍为浅色竖线。 */
input,
textarea,
select,
[contenteditable="true"] {
  caret-color: var(--accent);
}

/* HTML 的 hidden 属性靠 UA 样式表 [hidden]{display:none} 实现，特异度只有 (0,1,0)，
   任何作者样式里像 .share-expired{display:grid} / .app{display:flex} 这类规则
   都会同级胜出，把 hidden 压掉。统一用 !important 作者规则锚住语义，
   以后新加 display:xxx 的浮层也不用再记得补一条 [hidden] 兜底。 */
[hidden] {
  display: none !important;
}

html,
body {
  height: 100%;
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial,
    "PingFang SC", "Microsoft YaHei", sans-serif;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  overscroll-behavior-y: none;
  touch-action: manipulation;
}

.app {
  position: relative;
  max-width: 520px;
  height: 100%;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  box-shadow: 0 0 0 1px var(--border);
  min-height: 0;
  overflow: hidden;
}

/* 验证通过后首次进入主界面：自下而上轻量入场 */
.app.app--enter {
  opacity: 0;
  transform: translate3d(0, 16px, 0);
}
.app.app--enter.app--enter-active {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  transition: opacity 0.45s var(--motion-ease), transform 0.52s var(--motion-ease-emphasized);
}

.chat-layer {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  background: var(--bg);
  /* 窄屏下会话抽屉盖住全屏但关闭时应让聊天层（含右上角 ⋯）处于上层可点 */
  position: relative;
  z-index: 2;
}

.session-drawer {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: flex;
  flex-direction: row;
  align-items: stretch;
  pointer-events: none;
  visibility: hidden;
  transition: visibility 0s linear;
}

.session-drawer.open {
  z-index: 80;
  visibility: visible;
  pointer-events: auto;
  transition-delay: 0s;
}

.session-drawer-panel {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  height: 100%;
  width: min(62vw, 340px);
  max-width: 90%;
  background: var(--bg);
  border-right: 1px solid var(--border);
  box-shadow: 8px 0 28px rgba(0, 0, 0, 0.1);
  transform: translateX(-100%);
  transition: transform var(--motion-duration) var(--motion-ease-emphasized);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

[data-theme="dark"] .session-drawer-panel {
  box-shadow: 8px 0 36px rgba(0, 0, 0, 0.45);
}

.session-drawer.open .session-drawer-panel {
  transform: translateX(0);
  will-change: transform;
}

.session-drawer:not(.open) .session-drawer-panel {
  will-change: auto;
}

.session-drawer-scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  margin: 0;
  padding: 0;
  border: none;
  cursor: pointer;
  background: rgba(0, 0, 0, 0.32);
  opacity: 0;
  transition: opacity var(--motion-duration) var(--motion-ease);
  -webkit-tap-highlight-color: transparent;
  pointer-events: none;
}

.session-drawer.open .session-drawer-scrim {
  opacity: 1;
  pointer-events: auto;
  will-change: opacity;
}

.session-drawer:not(.open) .session-drawer-scrim {
  will-change: auto;
}

[data-theme="dark"] .session-drawer-scrim {
  background: rgba(0, 0, 0, 0.45);
}

.top-list {
  padding-right: 48px;
  padding-left: 16px;
}

.top-list h1 {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}

.top-list .sub {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.header-new-session {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 40px;
  height: 36px;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--accent);
  font-size: 22px;
  line-height: 1;
  font-weight: 300;
  cursor: pointer;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.header-new-session:hover,
.header-new-session:focus {
  background: var(--header-more-hover);
  outline: none;
}

.session-list-scroll {
  flex: 1;
  overflow-y: overlay;
  overflow-x: hidden;
  min-height: 0;
}

.session-list {
  padding: 0 0 24px;
}

.session-row-wrap {
  position: relative;
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--border);
  transition: background-color 0.15s ease;
}

.session-row-wrap:hover {
  background: var(--header-more-hover);
}

.session-row-wrap:active {
  background: var(--header-more-active);
}

.session-row-wrap:has(.session-row-active) {
  background: var(--header-more-active);
}

/* 浅色：选中条再淡一点，避免与列表白底对比过重 */
[data-theme="light"] .session-row-wrap:has(.session-row-active) {
  background: rgba(0, 0, 0, 0.05);
}

.session-row {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  text-align: left;
  padding: 14px 4px 14px 12px;
  gap: 10px;
  font-family: inherit;
  color: inherit;
}

.session-row:hover,
.session-row:focus {
  outline: none;
}

.session-row-avatar-wrap {
  position: relative;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
}

/* 访客未读：头像右上角红点（与列表底色用 ring 分隔） */
.session-row-avatar-wrap.has-unread::after {
  content: "";
  position: absolute;
  top: 1px;
  right: 1px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--danger);
  box-shadow: 0 0 0 2px var(--bg);
  pointer-events: none;
}

.session-row-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  -webkit-font-smoothing: antialiased;
}

/* 浅色页：略压阴影，字偏暖白，避免在亮底上发飘 */
[data-theme="light"] .session-row-avatar {
  color: rgba(255, 255, 255, 0.97);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.24);
}

/* 深色页：纯白 + 稍强阴影，压住彩色底 */
[data-theme="dark"] .session-row-avatar {
  color: #ffffff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
}

.session-row-body {
  flex: 1;
  min-width: 0;
}

.session-row-summary {
  font-size: 16px;
  font-weight: 500;
  line-height: 1.35;
  margin-bottom: 4px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.session-row-preview {
  font-size: 13px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 最后一条为图片：显示小缩略图，避免 data:image/... 撑爆预览行 */
.session-row-preview.session-row-preview--has-thumb {
  display: flex;
  align-items: center;
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  min-height: 24px;
}

.session-row-preview-thumb {
  width: 24px;
  height: 24px;
  border-radius: 6px;
  object-fit: cover;
  flex-shrink: 0;
  border: 1px solid var(--border);
  background: var(--menu-hover);
  vertical-align: top;
}

.session-row-actions {
  position: relative;
  z-index: 4;
  display: flex;
  flex-direction: row;
  align-items: center;
  flex-shrink: 0;
  align-self: stretch;
  gap: 4px;
  padding: 0 12px 0 8px;
  background: transparent;
}

.session-row-wrap:has(.session-row-active) .session-row-actions {
  background: transparent;
}

.session-row-edit,
.session-row-del,
.session-row-share {
  flex-shrink: 0;
  align-self: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  border-radius: 6px;
  font-size: 15px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.2s ease, background-color 0.2s ease, color 0.2s ease;
}

.session-row-edit:hover,
.session-row-edit:focus {
  background: var(--header-more-hover);
  color: var(--text);
  outline: none;
  transform: scale(1.05);
}

.session-row-del:hover,
.session-row-del:focus {
  background: rgba(250, 81, 81, 0.12);
  color: var(--danger);
  outline: none;
  transform: scale(1.05);
}

.session-row-share:hover,
.session-row-share:focus {
  background: var(--header-more-hover);
  color: var(--accent);
  outline: none;
  transform: scale(1.05);
}

/* 已开启分享的会话：分享按钮默认就带强调色，提示状态 */
.session-row-share.session-row-share-on {
  color: var(--accent);
}

.sub-list-hint {
  display: block;
  margin: 2px auto 0;
  padding: 4px 8px;
  max-width: 100%;
}

.sub--editable {
  display: block;
  width: calc(100% - 88px);
  margin: 2px auto 0;
  border: none;
  background: transparent;
  font-family: inherit;
  font-size: 12px;
  color: var(--muted);
  cursor: pointer;
  text-align: center;
  padding: 4px 8px;
  border-radius: 4px;
  line-height: 1.35;
}

.sub--editable:hover,
.sub--editable:focus {
  background: var(--header-more-hover);
  color: var(--text);
  outline: none;
}

.sub--editable.sub--inactive,
.sub--editable:disabled {
  cursor: default;
  opacity: 0.55;
  pointer-events: none;
}

.sub--editable.sub--inactive:hover,
.sub--editable.sub--inactive:focus,
.sub--editable:disabled:hover,
.sub--editable:disabled:focus {
  background: transparent;
  color: var(--muted);
}

header.top {
  flex-shrink: 0;
  background: var(--bar);
  border-bottom: 1px solid var(--border);
  padding: 10px 44px 8px;
  text-align: center;
  position: relative;
  /* 窄屏软键盘时减少与下方主区域同步重排导致的标题条闪动 */
  backface-visibility: hidden;
}

/* 只统一「会话列表」与「聊天」两处标题条背景；不改整栏 --surface / --bg */
header.top.top-list,
header.top.top-chat {
  background: var(--header-title-bg);
}

/*
 * 整块聊天/分享顶栏叠在 .stream 之上（含伸出的「更多」下拉）。
 * 须高于 .stream 内 sticky 日期条等（仅用个位数 z-index，见 .chat-ts），避免日期盖住顶栏/面板。
 */
header.top.top-chat,
header.top.top-share {
  z-index: 50;
}

.header-back {
  position: absolute;
  left: 4px;
  top: 50%;
  transform: translateY(-50%);
  /* 高于关闭态面板与全宽 h1/.sub；低于 open 面板时由 .header-more 仍保持可点（见 .header-more-panel.open z-index） */
  z-index: 60;
  width: 40px;
  height: 36px;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--text);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.header-back:hover {
  background: var(--header-more-hover);
}

.header-back:focus {
  outline: none;
}

.header-back:focus-visible {
  background: var(--header-more-hover);
}

/* 按下瞬间高亮：触屏松手即消失，与右侧 ⋯ 一致 */
.header-back:active {
  background: var(--header-more-active);
}

header.top h1 {
  margin: 0;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.25;
}

header.top .sub {
  margin-top: 2px;
  font-size: 12px;
  color: var(--muted);
  line-height: 1.35;
}

.header-more {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 60;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  width: 40px;
  height: 36px;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--text);
  font-size: 18px;
  line-height: 1;
  letter-spacing: 0.12em;
  cursor: pointer;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.header-more:focus {
  outline: none;
}

/* 仅键盘聚焦时高亮 */
.header-more:focus-visible {
  background: var(--header-more-hover);
}

/* 打开态由下拉面板体现 */
.header-more[aria-expanded="true"] {
  background: transparent;
}

.header-more[aria-expanded="true"]:focus-visible {
  background: var(--header-more-hover);
}

/*
 * 触屏点击后浏览器常把 :hover「粘」在按钮上，看起来像一直选中。
 * 仅在能真正悬停的设备上应用 hover 底色。
 */
@media (hover: hover) and (pointer: fine) {
  .header-more:hover {
    background: var(--header-more-hover);
  }

  .header-more[aria-expanded="true"]:hover {
    background: var(--header-more-hover);
  }
}

/* 与 .header-back:active 相同：触屏有点击感，且不依赖会粘住的 :hover */
.header-more:active {
  background: var(--header-more-active);
}

.header-more.has-filter::after {
  content: "";
  position: absolute;
  top: 8px;
  right: 8px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
}

.header-more-panel {
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  /* 关闭时必须在 ⋯ 按钮之下，避免部分引擎仍命中透明层导致点不开 */
  z-index: 0;
  background: var(--bar);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--panel-shadow);
  padding: 12px;
  opacity: 0;
  transform: translate3d(0, -6px, 0);
  pointer-events: none;
  visibility: hidden;
  /* 顶栏下拉：略快于全局面板，收起时更跟手 */
  transition: opacity var(--motion-duration-short) var(--motion-ease),
    transform var(--motion-duration-short) var(--motion-ease),
    visibility var(--motion-duration-short);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.header-more-panel.open {
  z-index: 50;
  opacity: 1;
  transform: translate3d(0, 0, 0);
  pointer-events: auto;
  visibility: visible;
  will-change: transform, opacity;
}

.header-more-panel:not(.open) {
  z-index: 0;
  will-change: auto;
}

.panel-divider {
  border: none;
  border-top: 1px solid var(--border);
  margin: 12px 0 10px;
}

/* ========== 当前会话搜索框（三点面板顶部） ========== */
.panel-search {
  display: flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--input-bg);
  padding: 0 10px;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}

.panel-search:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.22);
}

.panel-search-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  flex-shrink: 0;
}

.panel-search input[type="search"] {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  padding: 10px 0;
  font: inherit;
  font-size: 14px;
  color: var(--text);
  caret-color: var(--accent);
  -webkit-appearance: none;
  appearance: none;
}

.panel-search input[type="search"]::-webkit-search-decoration,
.panel-search input[type="search"]::-webkit-search-cancel-button,
.panel-search input[type="search"]::-webkit-search-results-button,
.panel-search input[type="search"]::-webkit-search-results-decoration {
  display: none;
}

.panel-search input[type="search"]::placeholder {
  color: var(--muted);
  opacity: 0.9;
}

.panel-search-clear {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  font-size: 18px;
  line-height: 1;
  padding: 0;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.panel-search-clear:hover {
  background: var(--menu-hover);
  color: var(--text);
}

.panel-search-hint {
  margin: 8px 2px 0;
  font-size: 12px;
  color: var(--muted);
  line-height: 1.5;
}

.panel-search-hint.empty {
  color: var(--danger);
}

/* 深色模式下 --input-bg / --border 与面板底色 --bar 容易融在一起，
   单独给搜索框一档更暗的底 + 更浅的边框，维持与其它 sheet 输入一致的视觉。 */
[data-theme="dark"] .panel-search {
  background: #262626;
  border-color: #454545;
}

/* 气泡里命中的关键词高亮。背景用柔和的黄，在浅色/深色、以及绿色气泡上都清晰可读。 */
mark.search-hl {
  background: #ffe082;
  color: #111;
  border-radius: 3px;
  padding: 0 2px;
  font-weight: 600;
}

[data-theme="dark"] mark.search-hl {
  background: #ffd54f;
  color: #111;
}

.panel-section-title {
  display: block;
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 8px;
  text-align: left;
}

.theme-seg {
  display: flex;
  gap: 0;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid var(--border);
}

.theme-seg button {
  flex: 1;
  padding: 10px 12px;
  border: none;
  background: var(--surface);
  color: var(--muted);
  font-size: 14px;
  font-family: inherit;
  cursor: pointer;
}

.theme-seg button + button {
  border-left: 1px solid var(--border);
}

.theme-seg button:hover {
  background: var(--menu-hover);
  color: var(--text);
}

.theme-seg button.active {
  background: var(--accent);
  color: #fff;
}

.theme-seg button.active:hover {
  color: #fff;
  filter: brightness(1.05);
}

.panel-notify-block {
  margin: 0;
}

.panel-notify-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
}

.panel-notify-row .panel-section-title {
  margin-bottom: 0;
  flex: 1;
}

.panel-notify-toggle {
  flex-shrink: 0;
  padding: 6px 12px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--btn-secondary-bg);
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
  white-space: nowrap;
}

.panel-notify-toggle.is-on {
  background: var(--accent);
  color: #fff;
  border-color: transparent;
}

.panel-notify-toggle:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.panel-notify-hint {
  margin: 0;
  font-size: 11px;
  line-height: 1.45;
  color: var(--muted);
}

.timeline-range {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  font-size: 13px;
  color: var(--text);
}

.timeline-range label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
}

.date-picker {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 13px;
  background: var(--input-bg);
  color: var(--muted);
  cursor: pointer;
  min-width: 110px;
  transition: border-color 0.2s, color 0.2s;
}

.date-picker:hover {
  border-color: var(--accent);
}

.date-picker.has-value {
  color: var(--text);
}

.timeline-range .range-clear {
  margin-left: auto;
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: 14px;
  padding: 4px 12px;
  font-size: 12px;
  cursor: pointer;
  color: var(--muted);
}

.timeline-range .range-clear:hover {
  color: var(--text);
  border-color: var(--accent);
}

.timeline-range-hint {
  width: 100%;
  margin: 0 0 4px;
  font-size: 12px;
  color: var(--muted);
  text-align: left;
}

.panel-logout {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--danger);
  font-size: 14px;
  font-family: inherit;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease;
}

.panel-logout:hover,
.panel-logout:focus {
  background: rgba(250, 81, 81, 0.08);
  outline: none;
}

/* ========== 已登录设备区块 ========== */
.panel-devices {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.panel-devices-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.panel-devices-label {
  margin-bottom: 0;
}

.panel-device-count {
  font-size: 13px;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--input-bg);
  border: 1px solid var(--border);
  min-width: 36px;
  text-align: center;
}

.panel-revoke-others {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  font-size: 14px;
  font-family: inherit;
  cursor: pointer;
  transition: background-color 0.2s ease, color 0.2s ease,
    border-color 0.2s ease, opacity 0.2s ease;
}

.panel-revoke-others:hover:not(:disabled),
.panel-revoke-others:focus:not(:disabled) {
  background: rgba(250, 81, 81, 0.08);
  color: var(--danger);
  border-color: var(--danger);
  outline: none;
}

.panel-revoke-others:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

.multiselect-toolbar {
  display: none;
  flex-shrink: 0;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 12px;
  background: var(--bar);
  border-bottom: 1px solid var(--border);
}

.app--multiselect .multiselect-toolbar {
  display: flex;
}

.app--multiselect .composer {
  display: none;
}

.multi-tool-cancel {
  padding: 8px 12px;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--accent);
  font-size: 16px;
  font-family: inherit;
  cursor: pointer;
}

.multi-tool-cancel:hover,
.multi-tool-cancel:focus {
  background: var(--header-more-hover);
  outline: none;
}

.multi-tool-actions {
  display: flex;
  align-items: center;
  gap: 16px;
}

.multi-tool-btn {
  padding: 8px 4px;
  border: none;
  background: none;
  color: var(--accent);
  font-size: 16px;
  font-family: inherit;
  cursor: pointer;
}

.multi-tool-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.multi-tool-btn.multi-tool-del:not(:disabled) {
  color: var(--danger);
}

.multi-tool-btn:not(:disabled):hover,
.multi-tool-btn:not(:disabled):focus {
  text-decoration: underline;
  outline: none;
}

.stream {
  flex: 1;
  position: relative;
  z-index: 0;
  isolation: isolate;
  overflow-x: hidden;
  /*
   * scroll 而非 auto：始终占用纵向滚动条槽位宽度，避免「是否需要滚动」切换时
   * 内容区宽度突变；scrollbar-gutter 在 overlay 滚动条系统上可能不预留，双保险。
   */
  overflow-y: scroll;
  scrollbar-gutter: stable;
  padding: 8px 12px 96px;
  /* 程序里改 scrollTop 时不要浏览器再插一层 smooth 动画，
     否则切会话 / 发消息后整列表会“慢慢拖到底”，又慢又容易和气泡入场叠在一起显卡。 */
  scroll-behavior: auto;
}

.stream::-webkit-scrollbar,
.session-list-scroll::-webkit-scrollbar {
  width: 10px;
  height: 10px;
  background-color: transparent;
}

.stream::-webkit-scrollbar-track,
.session-list-scroll::-webkit-scrollbar-track {
  background: transparent;
}

.stream::-webkit-scrollbar-thumb,
.session-list-scroll::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb);
  border-radius: 100px;
}

.stream::-webkit-scrollbar-thumb:hover,
.session-list-scroll::-webkit-scrollbar-thumb:hover {
  background: var(--scroll-thumb-hover);
}

.stream::-webkit-scrollbar-button,
.session-list-scroll::-webkit-scrollbar-button {
  display: none !important;
  width: 0 !important;
  height: 0 !important;
}

.stream::-webkit-scrollbar-corner,
.session-list-scroll::-webkit-scrollbar-corner {
  display: none !important;
  background: transparent !important;
}

.chat-ts {
  text-align: center;
  margin: 18px auto 14px;
  font-size: 12px;
  line-height: 1.4;
  color: #fff;
  padding: 4px 10px;
  background: var(--time-pill-bg);
  border-radius: 6px;
  width: fit-content;
  position: sticky;
  top: 12px;
  /* 仅在消息流内部叠在气泡之上；勿用过大值，否则会与顶栏 z-index 竞争 */
  z-index: 2;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  box-shadow: 0 1px 3px rgba(0,0,0,0.02);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
}

[data-theme="dark"] .chat-ts {
  color: #e6e6e6;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}

.chat-group {
  display: flex;
  flex-direction: column;
}

.chat-group:first-child .chat-ts {
  margin-top: 10px;
}

@keyframes msg-enter {
  from {
    opacity: 0;
    transform: translate3d(0, 4px, 0);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

.msg-row {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  width: 100%;
  margin-bottom: 10px;
  gap: 10px;
}

/* 入场动画只加在"第一次见到"的消息上：
   - 切会话、编辑、删除、轮询刷新都会触发 renderStream 把整个流重建，
     如果每次都让所有气泡重跑动画，100 条的会话就会整屏闪一遍，非常卡。
   - JS 侧维护一个 seenItemIds 集合，已见过的气泡不加这个类，保持静止；
     只有真正新出现的消息会拿到 .msg-row-enter，触发入场动画。
   时长与曲线与 :root 里 --motion-* 对齐，整 app 动效节奏一致。 */
.msg-row-enter {
  animation: msg-enter var(--motion-duration) var(--motion-ease) both;
  will-change: transform, opacity;
}

.msg-row:last-child {
  margin-bottom: 4px;
}

.msg-row-trail {
  flex: 1;
  min-width: 0;
  display: flex;
  justify-content: flex-end;
}

.msg-check {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  margin-top: 8px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  display: none;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
}

.app--multiselect .msg-check {
  display: flex;
}

.msg-check:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.msg-check-inner {
  position: relative;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2px solid var(--multiselect-ring);
  box-sizing: border-box;
  background: transparent;
}

.msg-check[aria-checked="true"] .msg-check-inner {
  background: var(--accent);
  border-color: var(--accent);
}

.msg-check[aria-checked="true"] .msg-check-inner::after {
  content: "";
  position: absolute;
  left: 6px;
  top: 2px;
  width: 5px;
  height: 10px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
  box-sizing: border-box;
}

.app--multiselect .bubble .body a,
.app--multiselect .bubble a.bubble-link {
  pointer-events: none;
}

.app--multiselect .bubble-wrap {
  max-width: min(82%, calc(100% - 40px));
}

.bubble-wrap {
  max-width: min(82%, 100%);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: pan-y;
  cursor: context-menu;
}

/* 关键：iOS Safari 对外层 user-select:none 在"长按+微滑"时不完全传导，
   文字一旦被选中，系统的"拷贝/查询/翻译"菜单就会抢在我们的长按菜单前弹出。
   这里用 !important 把禁选和禁 callout 强制加到气泡里所有后代元素上。 */
.bubble-wrap,
.bubble-wrap * {
  -webkit-touch-callout: none !important;
  -webkit-user-select: none !important;
  user-select: none !important;
}

@media (hover: hover) and (pointer: fine) {
  /* 桌面端：主卡片内除表单外默认不可选中，避免误选标题栏/侧栏/时间戳等；
     气泡内仅 .title / .body 可划词（与 iOS 全禁选策略区分）。 */
  .app {
    -webkit-user-select: none;
    user-select: none;
  }

  .app input,
  .app textarea,
  .app select {
    -webkit-user-select: text;
    user-select: text;
  }

  .bubble-wrap {
    cursor: context-menu;
  }

  /* 盖过上方 .bubble-wrap * { user-select:none !important }，仅正文区可选 */
  .bubble .title,
  .bubble .title *,
  .bubble .body,
  .bubble .body * {
    -webkit-user-select: text !important;
    user-select: text !important;
  }

  .bubble-wrap--image-standalone .msg-img-standalone-title,
  .bubble-wrap--image-standalone .msg-img-standalone-title * {
    -webkit-user-select: text !important;
    user-select: text !important;
  }
}

/* 分享页无多选长按菜单：触屏上亦允许在气泡内划词复制。
   （主应用在触屏上仍全禁选，避免与长按上下文菜单冲突。） */
.share-app .bubble .title,
.share-app .bubble .title *,
.share-app .bubble .body,
.share-app .bubble .body * {
  -webkit-touch-callout: default !important;
  -webkit-user-select: text !important;
  user-select: text !important;
}

.share-app .bubble .body a {
  -webkit-user-drag: none;
}

.share-app .msg-img-standalone-title,
.share-app .msg-img-standalone-title * {
  -webkit-touch-callout: default !important;
  -webkit-user-select: text !important;
  user-select: text !important;
}

.bubble {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  background: var(--bubble-self);
  color: var(--bubble-text);
  border-radius: 8px;
  padding: 10px 14px;
  font-size: 16px;
  line-height: 1.6;
  word-break: break-word;
  white-space: pre-wrap;
  box-shadow: var(--shadow);
  border: 1px solid var(--bubble-border);
  transition: filter 0.15s ease;
}

.bubble-wrap:active .bubble,
.bubble-wrap:active .bubble::after {
  filter: brightness(0.92);
}

.bubble::after {
  content: "";
  position: absolute;
  width: 6px;
  height: 12px;
  top: 14px;
  right: -5px;
  background: var(--bubble-self);
  clip-path: polygon(0 0, 100% 50%, 0 100%);
  transition: filter 0.15s ease;
}

.bubble-stack {
  min-width: 0;
}

.bubble .body a,
.bubble a.bubble-link {
  color: var(--bubble-link);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.bubble .body a:hover,
.bubble a.bubble-link:hover {
  filter: brightness(1.08);
}

.bubble .title {
  font-weight: 600;
  margin-bottom: 4px;
  font-size: 14px;
  color: var(--bubble-text);
}

/* ============================================================
   对方（非自己）气泡：用于分享功能中区分访客 vs 管理者的消息。
   .msg-row-other 加在 .msg-row 上，代表该消息是"对方发来的"。
   管理者主应用里访客（guest）消息是对方；分享页访客视角里，
   管理者（owner）消息是对方。两端 CSS 类相同，靠 JS 决定归属。
   ============================================================ */
.msg-row-other .msg-row-trail {
  justify-content: flex-start;
}

.msg-row-other .bubble-wrap {
  align-items: flex-start;
}

.msg-row-other .bubble {
  background: var(--bubble-card);
  color: var(--bubble-other-text);
}

/* .bubble .title 那里写死了 var(--bubble-text)，这里得跟着气泡底色翻一下 */
.msg-row-other .bubble .title {
  color: var(--bubble-other-text);
}

/* 气泡里链接默认用 --bubble-link（为亮绿色气泡调过的深蓝）；
   对方灰色气泡用标准 --link 色，深色模式下才不会变成黑底配深蓝看不清。 */
.msg-row-other .bubble .body a,
.msg-row-other .bubble a.bubble-link {
  color: var(--link);
}

.msg-row-other .bubble::after {
  left: -5px;
  right: auto;
  background: var(--bubble-card);
  clip-path: polygon(100% 0, 0 50%, 100% 100%);
}

/* 独立图片消息：无 .bubble 绿/灰底与尾翼，仅圆角图 + 可选标题（类原生 IM） */
.bubble-wrap--image-standalone {
  gap: 0;
}

.msg-img-standalone-title {
  font-weight: 600;
  font-size: 14px;
  line-height: 1.35;
  margin-bottom: 6px;
  color: var(--text);
  max-width: min(220px, 72vw);
  align-self: flex-end;
  text-align: right;
  word-break: break-word;
}

.msg-row-other .msg-img-standalone-title {
  align-self: flex-start;
  text-align: left;
}

.bubble-wrap--image-standalone .msg-img-figure {
  border-radius: 8px;
  box-shadow: var(--shadow);
  border: 1px solid var(--bubble-border);
}

.bubble-wrap:active.bubble-wrap--image-standalone .msg-img-figure {
  filter: brightness(0.92);
  transition: filter 0.15s ease;
}

/* 独立图片解码/加载失败：占位文案（仍占独立消息位，无气泡底） */
.msg-img-figure.msg-img-figure--invalid {
  display: block;
  margin: 0;
  line-height: 1.5;
  padding: 10px 14px;
  font-size: 15px;
  color: var(--muted);
  border-radius: 8px;
  box-shadow: var(--shadow);
  border: 1px solid var(--bubble-border);
  background: var(--bubble-card);
  max-width: min(220px, 72vw);
}

.msg-ctx-menu {
  position: fixed;
  z-index: 100;
  min-width: 132px;
  background: var(--menu-bg);
  border-radius: 8px;
  box-shadow: var(--panel-shadow);
  border: 1px solid var(--border);
  padding: 4px 0;
  opacity: 0;
  transform: scale(0.96);
  pointer-events: none;
  visibility: hidden;
  transition: opacity var(--motion-duration-short) var(--motion-ease),
    transform var(--motion-duration-short) var(--motion-ease),
    visibility var(--motion-duration-short);
  transform-origin: top left;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
  /* 长按菜单自身要完全屏蔽系统菜单：
     - touch-callout: none   禁掉 iOS 长按弹出的「拷贝/查询」浮层
     - user-select: none     禁掉文字选中
     - tap-highlight-color   禁掉安卓点击时的灰色高亮 */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.msg-ctx-menu,
.msg-ctx-menu * {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
}

.msg-ctx-menu.open {
  opacity: 1;
  transform: scale(1);
  pointer-events: auto;
  visibility: visible;
  will-change: transform, opacity;
}

.msg-ctx-menu:not(.open) {
  will-change: auto;
}

.msg-ctx-menu button {
  display: block;
  width: 100%;
  text-align: left;
  border: none;
  background: none;
  padding: 12px 18px;
  font-size: 15px;
  font-family: inherit;
  color: var(--text);
  cursor: pointer;
}

.msg-ctx-menu button:hover,
.msg-ctx-menu button:focus {
  background: var(--menu-hover);
  outline: none;
}

.msg-ctx-menu button.danger {
  color: var(--danger);
}

.composer {
  flex-shrink: 0;
  position: sticky;
  bottom: 0;
  background: var(--bar);
  border-top: 1px solid var(--border);
  padding: 8px 10px calc(8px + env(safe-area-inset-bottom));
  display: flex;
  gap: 8px;
  align-items: flex-end;
}

.composer textarea {
  flex: 1;
  min-width: 0;
  min-height: 40px;
  max-height: 120px;
  resize: none;
  border: none;
  border-radius: 6px;
  padding: 10px 12px;
  font-size: 15px;
  font-family: inherit;
  line-height: 21px;
  background: var(--input-bg);
  color: var(--text);
  overflow-x: hidden;
  /* 纵向：无 field-sizing 时由 resizeComposerInput 设 overflow-y */
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  touch-action: auto;
  /* auto 比 thin 更易点；WebKit 见下方显式 width */
  scrollbar-width: auto;
  scrollbar-color: var(--scroll-thumb) transparent;
  -ms-overflow-style: auto;
}

@supports (field-sizing: content) {
  .composer textarea {
    field-sizing: content;
  }
}

.composer textarea::-webkit-scrollbar {
  width: 10px;
}

.composer textarea::-webkit-scrollbar-track {
  background: transparent;
}

.composer textarea::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb);
  border-radius: 100px;
}

.composer textarea:focus {
  outline: none;
}

.composer textarea::placeholder,
.sheet textarea::placeholder {
  color: var(--muted);
  opacity: 0.9;
}

.composer .send {
  flex-shrink: 0;
  height: 40px;
  padding: 0 16px;
  border: none;
  border-radius: 6px;
  background: var(--accent);
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s, opacity 0.2s, transform 0.1s;
}

.composer .send:not(:disabled):active {
  transform: scale(0.95);
}

.composer .send:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.composer-input-wrap {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: flex-end;
}

.composer-input-wrap textarea {
  /* 为竖向滚动条槽位 + 与图标间距 + 32px 图标留足空间（与 scrollbar-gutter 叠加后不挤作一团） */
  /* 角标 position:absolute 叠在角上，勿加 padding-top，否则会把整框撑高 */
  padding-right: 3rem;
}

.composer-img-btn {
  position: absolute;
  /* 钉在输入区右下角，不随 textarea 变高而上下移动 */
  right: 18px;
  bottom: 5px;
  width: 32px;
  height: 32px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.2s;
}

.composer-img-btn:hover,
.composer-img-btn:focus {
  color: var(--text);
  outline: none;
}

.composer-img-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

/* 输入框右上：默认贴角；有竖向滚动条时由 JS 加 .input-expand-icon-btn--for-scrollbar 左移让轨 */
.input-expand-icon-btn {
  position: absolute;
  z-index: 1;
  top: 2px;
  right: 2px;
  width: 22px;
  height: 22px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: right 0.12s ease, color 0.2s, opacity 0.2s;
  box-shadow: none;
}

.input-expand-icon-btn--for-scrollbar {
  right: 12px;
}

.input-expand-icon-btn svg {
  display: block;
  width: 12px;
  height: 12px;
}

[data-theme="dark"] .input-expand-icon-btn {
  background: transparent;
  color: #c4c4c4;
  box-shadow: none;
}

.input-expand-icon-btn:hover,
.input-expand-icon-btn:focus {
  color: var(--text);
  outline: none;
  background: transparent;
}

.input-expand-icon-btn:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.sheet-edit-input-wrap {
  position: relative;
  margin-bottom: 12px;
}

/* 放大写作层：高于编辑弹层 .overlay(150)、低于确认框等；整层居中、卡片勿铺满视口 */
.text-expand-layer {
  position: fixed;
  inset: 0;
  z-index: 450;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: max(10px, env(safe-area-inset-top)) max(10px, env(safe-area-inset-right))
    max(10px, env(safe-area-inset-bottom)) max(10px, env(safe-area-inset-left));
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

.text-expand-layer[hidden] {
  display: none !important;
}

.text-expand-backdrop {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: rgba(0, 0, 0, 0.5);
  /* 可接到点击，用于点空白处缩小；编辑卡片叠在其上 */
  pointer-events: auto;
  cursor: default;
}

[data-theme="dark"] .text-expand-backdrop {
  background: rgba(0, 0, 0, 0.72);
}

.text-expand-inner {
  position: relative;
  z-index: 1;
  /* 勿对 inner 用 pointer-events:none，否则部分环境下列表/textarea 的竖向滚动条无法拖动 */
  width: 100%;
  max-width: min(56rem, 98vw);
  /* 不顶天立地：给四周留白 */
  max-height: min(99.2vh, 72rem);
  display: flex;
  flex-direction: column;
  min-height: 0;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* 与输入框同构：角标叠在框内右上；承接点击（父 .text-expand-inner 为 none 以让空白落到 backdrop） */
.text-expand-field-wrap {
  position: relative;
  z-index: 0;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  max-height: min(98.2vh, 68rem);
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  pointer-events: auto;
}

/* 与 .input-expand-icon-btn 组合；尺寸略大（right 同全局 10px，与竖滚动条错开） */
.text-expand-field-wrap .text-expand-shrink-btn {
  z-index: 2;
  width: 26px;
  height: 26px;
  top: 1px;
}

.text-expand-field-wrap .text-expand-shrink-btn svg {
  width: 14px;
  height: 14px;
}

@media (max-width: 959.98px) {
  .text-expand-inner {
    max-width: 100%;
    max-height: min(94vh, 52rem);
  }
  .text-expand-field-wrap {
    max-height: min(92vh, 50rem);
  }
  .text-expand-ta--open {
    min-height: 22rem;
  }
}

.text-expand-ta--open {
  flex: 1 1 auto;
  min-height: 30rem;
  width: 100%;
  max-width: none;
  max-height: 100%;
  box-sizing: border-box;
  margin: 0;
  border-radius: 8px;
  border: 1px solid var(--accent);
  /* 与框内缩小角标 + 竖滚动条同列：右侧多留、顶底正常 */
  padding: 10px 1.9rem 10px 12px;
  font-size: 16px;
  line-height: 1.5;
  font-family: inherit;
  background: var(--input-bg);
  color: var(--text);
  resize: none;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-gutter: stable;
  scrollbar-width: auto;
  scrollbar-color: var(--scroll-thumb) transparent;
}

@media (min-width: 960px) {
  .text-expand-ta--open {
    min-height: 36rem;
  }
}

.text-expand-ta--open::-webkit-scrollbar {
  width: 10px;
}

.text-expand-ta--open::-webkit-scrollbar-track {
  background: transparent;
}

.text-expand-ta--open::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb);
  border-radius: 100px;
}

.text-expand-ta--open:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.22);
  caret-color: var(--accent);
}

[data-theme="dark"] .text-expand-ta--open {
  background: #262626;
  border: 1px solid var(--accent);
}

[data-theme="dark"] .text-expand-ta--open:focus {
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.28);
}

html.text-expand-ui-open {
  overflow: hidden;
}

/* 聊天气泡内 / 独立图片：底衬透明；独立模式由 .bubble-wrap--image-standalone .msg-img-figure 加边与阴影 */
.msg-img-figure {
  margin: 0;
  line-height: 0;
  border-radius: 6px;
  overflow: hidden;
  max-width: min(220px, 72vw);
  background: transparent;
}

.msg-img-thumb {
  display: block;
  width: 100%;
  height: auto;
  min-height: 40px;
  max-height: 280px;
  object-fit: cover;
  cursor: zoom-in;
}

/* 多选：不放大预览，与点气泡勾选一致 */
.app--multiselect .msg-img-thumb {
  cursor: pointer;
}

/* 全屏预览 */
.img-lightbox {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: flex;
  align-items: center;
  justify-content: center;
}

.img-lightbox[hidden] {
  display: none !important;
}

.img-lightbox-backdrop {
  position: absolute;
  inset: 0;
  border: none;
  padding: 0;
  margin: 0;
  cursor: zoom-out;
  background: rgba(0, 0, 0, 0.88);
}

[data-theme="dark"] .img-lightbox-backdrop {
  background: rgba(0, 0, 0, 0.92);
}

.img-lightbox-inner {
  position: relative;
  z-index: 1;
  max-width: min(100vw - 24px, 960px);
  max-height: min(100vh - 48px, 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

.img-lightbox-inner > * {
  pointer-events: auto;
}

.img-lightbox-img {
  display: block;
  position: relative;
  z-index: 1;
  max-width: min(100vw - 24px, 960px);
  max-height: min(100vh - 80px, 90vh);
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: 4px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.45);
}

.img-lightbox-close {
  position: absolute;
  top: -40px;
  right: 0;
  z-index: 2;
  width: 36px;
  height: 36px;
  border: none;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.img-lightbox-close:hover,
.img-lightbox-close:focus {
  background: rgba(255, 255, 255, 0.22);
  outline: none;
}

@media (max-width: 520px) {
  /* 窄屏：关闭钮固定到视口右上角；须高于大图 z-index，否则大图会盖住按钮无法点 */
  .img-lightbox-inner {
    max-width: calc(100vw - 16px);
    max-height: calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
    max-height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
    padding-left: 8px;
    padding-right: 8px;
    box-sizing: border-box;
  }

  .img-lightbox-img {
    max-width: 100%;
    /* 预留顶部安全区 + 关闭按钮高度，避免竖图顶到状态栏/压住关闭 */
    max-height: calc(100vh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 52px);
    max-height: calc(100dvh - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px) - 52px);
  }

  .img-lightbox-close {
    position: fixed;
    top: calc(8px + env(safe-area-inset-top, 0px));
    right: calc(8px + env(safe-area-inset-right, 0px));
    z-index: 10;
    background: rgba(0, 0, 0, 0.45);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
  }

  .img-lightbox-close:hover,
  .img-lightbox-close:focus {
    background: rgba(0, 0, 0, 0.58);
  }
}

.empty {
  text-align: center;
  color: var(--muted);
  font-size: 14px;
  padding: 48px 24px;
}

.empty.empty--no-session {
  padding: 72px 28px;
  font-size: 15px;
  line-height: 1.55;
  max-width: 320px;
  margin: 0 auto;
}

.empty.empty--loading {
  animation: empty-loading-pulse 1.1s ease-in-out infinite;
}

@keyframes empty-loading-pulse {
  0%,
  100% {
    opacity: 0.55;
  }
  50% {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .empty.empty--loading {
    animation: none;
    opacity: 0.85;
  }
}

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  z-index: 150;
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: opacity var(--motion-duration) var(--motion-ease), visibility var(--motion-duration);
}

.overlay.open {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
}

.sheet {
  width: 100%;
  max-width: 520px;
  background: var(--sheet-bg);
  color: var(--text);
  border-radius: 12px 12px 0 0;
  padding: 16px 16px calc(16px + env(safe-area-inset-bottom));
  box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.12);
  transform: translate3d(0, 100%, 0);
  transition: transform var(--motion-duration) var(--motion-ease-emphasized);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.overlay.open .sheet {
  transform: translate3d(0, 0, 0);
  will-change: transform;
}

.overlay:not(.open) .sheet {
  will-change: auto;
}

[data-theme="dark"] .sheet {
  box-shadow: 0 -4px 32px rgba(0, 0, 0, 0.55);
}

/* 桌面：编辑消息 / 编辑概述 / 分享 —— 居中模态（与 app.js DESKTOP_SHELL_MQ 960px 一致） */
@media (min-width: 960px) {
  .overlay {
    align-items: center;
    justify-content: center;
    padding: 24px;
    box-sizing: border-box;
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
  }

  .overlay .sheet {
    width: min(520px, 100%);
    max-height: min(90dvh, 720px);
    overflow-y: auto;
    border-radius: 12px;
    padding: 18px 18px 18px;
    box-shadow: var(--panel-shadow);
    border: 1px solid var(--border);
    transform: scale(0.96);
    transition: transform var(--motion-duration) var(--motion-ease-emphasized);
  }

  .overlay.open .sheet {
    transform: scale(1);
  }

  [data-theme="dark"] .overlay .sheet {
    box-shadow: 0 16px 48px rgba(0, 0, 0, 0.5);
  }
}

.sheet h2 {
  margin: 0 0 12px;
  font-size: 17px;
  text-align: center;
}

.sheet label {
  display: block;
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 4px;
}

.sheet input,
.sheet textarea,
.sheet select {
  width: 100%;
  margin-bottom: 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 12px;
  font-size: 15px;
  font-family: inherit;
  background: var(--input-bg);
  color: var(--text);
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

/* 聚焦态：统一走品牌绿，不要浏览器默认的蓝色 outline */
.sheet input:focus,
.sheet textarea:focus,
.sheet select:focus,
.sheet input:focus-visible,
.sheet textarea:focus-visible,
.sheet select:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.22);
  caret-color: var(--accent);
}

/* 深色模式下 sheet 内输入比 --sheet-bg 略深一档，便于与卡片区分 */
[data-theme="dark"] .sheet input,
[data-theme="dark"] .sheet textarea,
[data-theme="dark"] .sheet select {
  background: #262626;
  border-color: #454545;
}

[data-theme="dark"] .sheet input:focus,
[data-theme="dark"] .sheet textarea:focus,
[data-theme="dark"] .sheet select:focus,
[data-theme="dark"] .sheet input:focus-visible,
[data-theme="dark"] .sheet textarea:focus-visible,
[data-theme="dark"] .sheet select:focus-visible {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.28);
}

.sheet textarea {
  /* 与底部 composer 一致：默认偏单行高度，可增高；禁用原生右下角拖动手柄 */
  min-height: 40px;
  max-height: 120px;
  resize: none;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: auto;
  scrollbar-color: var(--scroll-thumb) transparent;
}

.sheet textarea::-webkit-scrollbar {
  width: 10px;
}

.sheet textarea::-webkit-scrollbar-track {
  background: transparent;
}

.sheet textarea::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb);
  border-radius: 100px;
}

/* 须写在 .sheet textarea 规则之后；角标不占文档流，仅右侧多留几格避免与文字叠字 */
.sheet .sheet-edit-input-wrap textarea {
  margin-bottom: 0;
  padding: 10px 1.9rem 10px 12px;
  /* 编辑区默认高一些；手机用 vh 封顶避免占满半屏+ */
  min-height: 5.75rem;
  max-height: min(36vh, 200px);
}

@media (min-width: 960px) {
  .sheet .sheet-edit-input-wrap textarea {
    min-height: 8.75rem;
    max-height: min(50vh, 300px);
  }
}

.sheet .row-btns {
  display: flex;
  gap: 10px;
  margin-top: 8px;
}

.sheet .row-btns button {
  flex: 1;
  padding: 12px;
  border-radius: 8px;
  border: none;
  font-size: 16px;
  cursor: pointer;
}

.sheet .row-btns .cancel {
  background: var(--btn-secondary-bg);
  color: var(--text);
}

.sheet .row-btns .save {
  background: var(--accent);
  color: #fff;
}

/* ============================================================
   会话分享弹窗
   ============================================================ */
.share-hint {
  margin: 0 0 14px;
  font-size: 13px;
  color: var(--muted);
  line-height: 1.5;
  text-align: center;
}

.share-token-label {
  display: block;
  margin: 0 0 8px;
  font-size: 13px;
  color: var(--text);
  text-align: left;
}

.share-token-row {
  align-items: center;
  flex-wrap: wrap;
}

.share-origin-prefix {
  flex-shrink: 0;
  font-size: 12px;
  color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  max-width: 46%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.share-token-input-wrap {
  display: flex;
  flex: 1 1 12rem;
  min-width: 0;
  align-items: stretch;
  gap: 8px;
}

.share-token-input-wrap input {
  max-width: none;
  flex: 1 1 6rem;
  min-width: 0;
}

.share-random-token-btn {
  flex-shrink: 0;
  padding: 10px 12px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  border-radius: 6px;
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
  transition: filter 0.2s ease, border-color 0.2s ease;
}

.share-random-token-btn:hover:not(:disabled),
.share-random-token-btn:focus:not(:disabled) {
  border-color: var(--accent);
  outline: none;
}

.share-random-token-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.share-random-token-btn[hidden] {
  display: none !important;
}

.share-save-token-btn {
  padding: 10px 14px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text);
  border-radius: 6px;
  font-size: 14px;
  cursor: pointer;
  transition: filter 0.2s ease, border-color 0.2s ease;
}

/* 与下方「取消分享 / 完成」一致：两钮等宽 50% / 50%（share-actions-row 不依赖 :has，旧浏览器也可用） */
.share-actions-row .share-save-token-btn,
.share-actions-row .share-copy-btn {
  flex: 1 1 0;
  min-width: 0;
}

.share-save-token-btn:hover:not(:disabled),
.share-save-token-btn:focus:not(:disabled) {
  border-color: var(--accent);
  outline: none;
}

.share-save-token-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.share-link-row {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}

.share-link-row input {
  flex: 1;
  min-width: 0;
  margin-bottom: 0;
  font-size: 13px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--input-bg);
  color: var(--text);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

.share-link-row input:focus,
.share-link-row input:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.22);
}

.share-copy-btn {
  padding: 10px 14px;
  border: none;
  background: var(--accent);
  color: #fff;
  border-radius: 6px;
  font-size: 14px;
  cursor: pointer;
  transition: filter 0.2s ease;
}

.share-copy-btn:hover,
.share-copy-btn:focus {
  filter: brightness(1.05);
  outline: none;
}

.share-row-btns {
  justify-content: space-between;
}

.sheet .row-btns .share-revoke {
  background: transparent;
  color: var(--danger);
  border: 1px solid var(--border);
}

.sheet .row-btns .share-revoke:hover,
.sheet .row-btns .share-revoke:focus {
  background: rgba(250, 81, 81, 0.1);
  outline: none;
}

.sheet .row-btns .share-revoke:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ============================================================
   分享访客页专用
   ============================================================ */

/* 分享页 sub（会话概述）非可点击，纯显示 */
.sub-share {
  display: block;
  margin: 2px auto 0;
  padding: 4px 8px;
  max-width: 100%;
  text-align: center;
  color: var(--sub-color, var(--muted));
  font-size: 12px;
  line-height: 1.4;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 分享已结束全屏遮罩。隐藏逻辑由文件顶部的全局 [hidden] 规则兜底。 */
.share-expired {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 24px;
  background: var(--bg);
  z-index: 9999;
}

.share-expired-card {
  max-width: 360px;
  width: 100%;
  background: var(--sheet-bg, var(--bg));
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 28px 24px;
  text-align: center;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.14);
}

.share-expired-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: rgba(250, 81, 81, 0.12);
  color: var(--danger);
  margin-bottom: 14px;
}

.share-expired-card h2 {
  margin: 0 0 8px;
  font-size: 18px;
  color: var(--text);
}

.share-expired-card p {
  margin: 0;
  font-size: 14px;
  color: var(--muted);
  line-height: 1.6;
}

.toast {
  position: fixed;
  left: 50%;
  bottom: calc(108px + env(safe-area-inset-bottom));
  transform: translate3d(-50%, 8px, 0);
  z-index: 300;
  max-width: min(90vw, 320px);
  padding: 11px 24px;
  text-align: center;
  border-radius: 10px;
  background: rgba(58, 58, 58, 0.92);
  color: #fff;
  font-size: 15px;
  line-height: 1.4;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity var(--motion-duration-short) var(--motion-ease),
    transform var(--motion-duration-short) var(--motion-ease),
    visibility var(--motion-duration-short);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
}

.toast.toast--show {
  opacity: 1;
  visibility: visible;
  transform: translate3d(-50%, 0, 0);
  will-change: transform, opacity;
}

.toast:not(.toast--show) {
  will-change: auto;
}

[data-theme="light"] .toast {
  background: rgba(70, 70, 70, 0.92);
  color: #fff;
}

.confirm-overlay {
  position: fixed;
  inset: 0;
  z-index: 260;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(0, 0, 0, 0.48);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: opacity var(--motion-duration) var(--motion-ease), visibility var(--motion-duration);
}

.confirm-overlay.open {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
}

.confirm-card {
  width: 100%;
  max-width: 300px;
  background: var(--sheet-bg);
  color: var(--text);
  border-radius: 14px;
  padding: 22px 20px 18px;
  box-shadow: var(--panel-shadow);
  border: 1px solid var(--border);
  transform: scale(0.94);
  transition: transform var(--motion-duration) var(--motion-ease-emphasized);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.confirm-overlay.open .confirm-card {
  transform: scale(1);
  will-change: transform;
}

.confirm-overlay:not(.open) .confirm-card {
  will-change: auto;
}

.confirm-title {
  margin: 0 0 12px;
  font-size: 17px;
  font-weight: 600;
  text-align: center;
  letter-spacing: 0.02em;
}

.confirm-message {
  margin: 0 0 22px;
  font-size: 15px;
  line-height: 1.55;
  color: var(--muted);
  text-align: center;
}

.confirm-actions {
  display: flex;
  gap: 12px;
}

.confirm-btn {
  flex: 1;
  padding: 12px 14px;
  border: none;
  border-radius: 10px;
  font-size: 16px;
  font-family: inherit;
  font-weight: 500;
  cursor: pointer;
}

.confirm-btn-cancel {
  background: var(--btn-secondary-bg);
  color: var(--text);
}

.confirm-btn-cancel:hover,
.confirm-btn-cancel:focus {
  filter: brightness(0.97);
  outline: none;
}

.confirm-btn-ok {
  background: var(--danger);
  color: #fff;
}

.confirm-btn-ok:hover,
.confirm-btn-ok:focus {
  filter: brightness(1.05);
  outline: none;
}

.calendar-overlay {
  position: fixed;
  inset: 0;
  /* 须高于提醒弹窗（reminders.css 中 220–240），以便在「设置提醒时间」内点选日期；低于全局 .confirm-overlay(260) */
  z-index: 255;
  background: rgba(0, 0, 0, 0.32);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: opacity var(--motion-duration) var(--motion-ease), visibility var(--motion-duration);
}

.calendar-overlay.open {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
}

.calendar-widget {
  background: var(--sheet-bg);
  border-radius: 12px;
  box-shadow: var(--panel-shadow);
  padding: 16px;
  width: 280px;
  color: var(--text);
  transform: scale(0.96);
  transition: transform var(--motion-duration) var(--motion-ease-emphasized);
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.calendar-overlay.open .calendar-widget {
  transform: scale(1);
  will-change: transform;
}

.calendar-overlay:not(.open) .calendar-widget {
  will-change: auto;
}

.cal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  font-size: 16px;
  font-weight: 500;
}

.cal-header button {
  background: var(--btn-secondary-bg);
  border: none;
  color: var(--text);
  cursor: pointer;
  font-size: 20px;
  width: 32px;
  height: 32px;
  border-radius: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.2s;
  line-height: 1;
}

.cal-header button:hover {
  background: var(--border);
}

.cal-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  text-align: center;
  font-size: 13px;
  color: var(--muted);
  margin-bottom: 8px;
}

.cal-days {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}

.cal-day {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  cursor: pointer;
  border-radius: 6px;
  transition: background 0.2s, color 0.2s;
}

.cal-day:hover {
  background: var(--menu-hover);
}

.cal-day.other-month {
  color: var(--muted);
  opacity: 0.5;
}

.cal-day.selected {
  background: var(--accent);
  color: #fff;
  font-weight: 500;
}

.cal-day.selected:hover {
  background: var(--accent);
  filter: brightness(1.05);
}

/* ============================================================
   登录（Google Authenticator）弹窗
   风格与 .confirm-card / .sheet 保持一致
   ============================================================ */
.auth-overlay {
  position: fixed;
  inset: 0;
  z-index: 400;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(0, 0, 0, 0.55);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  opacity: 0;
  pointer-events: none;
  visibility: hidden;
  transition: opacity var(--motion-duration) var(--motion-ease), visibility var(--motion-duration);
}

.auth-overlay.open {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
}

.auth-card {
  position: relative;
  width: 100%;
  max-width: 340px;
  background: var(--sheet-bg);
  color: var(--text);
  border-radius: 16px;
  padding: 28px 24px 22px;
  box-shadow: var(--panel-shadow);
  border: 1px solid var(--border);
  transform: scale(0.94) translate3d(0, 6px, 0);
  transition: transform var(--motion-duration) var(--motion-ease-emphasized);
  text-align: center;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.auth-overlay.open .auth-card {
  transform: scale(1) translate3d(0, 0, 0);
  will-change: transform;
}

.auth-overlay:not(.open) .auth-card {
  will-change: auto;
}

/* 验证成功瞬间：卡片略放大 + 绿色描边，再随 .open 移除淡出 */
.auth-overlay.auth-overlay--success.open .auth-card {
  transform: scale(1.04);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.38), var(--panel-shadow);
  transition: transform 0.24s var(--motion-ease-emphasized), box-shadow 0.24s ease;
}

.auth-overlay.auth-overlay--exit {
  pointer-events: none;
}

[data-theme="dark"] .auth-card {
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.6);
}

.auth-icon {
  width: 52px;
  height: 52px;
  border-radius: 14px;
  margin: 0 auto 14px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(var(--accent-rgb), 0.12);
  color: var(--accent);
}

.auth-title {
  margin: 0 0 6px;
  font-size: 18px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.auth-message {
  margin: 0 0 18px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted);
}

/* 6 个格子的验证码显示 */
.auth-code {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 8px;
  margin-bottom: 10px;
  cursor: text;
}

.auth-code-cell {
  aspect-ratio: 1 / 1.25;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--input-bg);
  color: var(--text);
  transition: border-color 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
  user-select: none;
}

.auth-code-mask-svg {
  display: block;
  flex-shrink: 0;
}

.auth-code-cell.filled {
  background: var(--surface);
}

/* 深色模式：验证码格子略深于卡片，避免与底色融在一起 */
[data-theme="dark"] .auth-code-cell {
  background: #262626;
  border-color: #454545;
}

[data-theme="dark"] .auth-code-cell.filled {
  background: #2e2e2e;
  border-color: #505050;
}

.auth-code.focused .auth-code-cell.caret {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.18);
}

.auth-code.error .auth-code-cell {
  border-color: var(--danger);
  animation: auth-shake 0.35s ease;
}

@keyframes auth-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}

/* 真正的输入框：透明但依旧可聚焦、接受键盘与粘贴 */
.auth-code-input {
  position: absolute;
  left: -9999px;
  top: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.auth-error {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--danger);
  min-height: 18px;
}

.auth-submit {
  width: 100%;
  margin-top: 16px;
  padding: 12px;
  border: none;
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  font-size: 16px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  transition: filter 0.15s ease, opacity 0.2s ease, transform 0.1s ease;
}

.auth-submit:not(:disabled):hover {
  filter: brightness(1.05);
}

.auth-submit:not(:disabled):active {
  transform: scale(0.98);
}

.auth-submit:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.auth-submit.loading {
  opacity: 0.85;
  cursor: progress;
}

.auth-hint {
  margin: 14px 0 0;
  font-size: 12px;
  color: var(--muted);
}

/* --------------------------------------------------------------------------
 * 移动 / 窄视口：同步 visualViewport 高度（viewport.js 写 --visual-vh），
 * 软键盘弹起时压缩 #app，避免底部输入区被遮挡。与 app.js / share.js 中 focus 时
 * scrollIntoView 配合。
 * -------------------------------------------------------------------------- */
@media (max-width: 959.98px) {
  html {
    --visual-vh: 100dvh;
  }

  html,
  body {
    height: var(--visual-vh, 100dvh);
    max-height: var(--visual-vh, 100dvh);
    overflow: hidden;
  }

  .app {
    height: var(--visual-vh, 100dvh);
    max-height: var(--visual-vh, 100dvh);
  }

  /* iOS / 部分 WebView：input 字级 <16px 时聚焦会整页放大，影响输入与键盘区定位 */
  .composer textarea,
  .sheet textarea {
    font-size: 16px;
    line-height: 1.4;
  }

  header.top {
    transform: translateZ(0);
    isolation: isolate;
  }

  /* 标题 h1 全宽与两侧绝对定位按钮重叠：勿让 h1 抢走触摸/点击命中 */
  header.top.top-chat > h1,
  header.top.top-share > h1 {
    pointer-events: none;
    position: relative;
    z-index: 0;
  }

  /* 副标题可点，收窄宽度避免与右上角 ⋯ 重叠 */
  header.top.top-chat .sub--editable {
    max-width: calc(100% - 120px);
    width: 100%;
    box-sizing: border-box;
  }
}

/* --------------------------------------------------------------------------
 * 桌面宽屏：类似电脑版微信 —— 中间主卡片「宽:高 = 4:3」落在视口留白内；
 * 左侧会话列表固定宽度，右侧为聊天区。
 * 主页与分享页共用 #app；分享页无 session-drawer，仅中间单栏卡片。
 * 断点与 app.js 中 DESKTOP_SHELL_MQ 一致。
 * -------------------------------------------------------------------------- */
@media (min-width: 960px) {
  html {
    --app-shell-pad: clamp(14px, 2.2vmin, 32px);
    --app-inner-w: calc(100vw - 2 * var(--app-shell-pad));
    --app-inner-h: calc(100dvh - 2 * var(--app-shell-pad));
  }

  body {
    padding: var(--app-shell-pad);
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 100dvh;
    box-sizing: border-box;
  }

  /* 中间整体：宽 / 高 = 4 / 3，且完整落在内框 (--app-inner-*) 内 */
  .app {
    width: min(var(--app-inner-w), calc(var(--app-inner-h) * 4 / 3));
    aspect-ratio: 4 / 3;
    height: auto;
    max-width: var(--app-inner-w);
    max-height: var(--app-inner-h);
    margin: 0;
    flex: none;
    flex-direction: row;
    align-items: stretch;
    align-self: center;
    min-height: 0;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: var(--panel-shadow);
    border: 1px solid var(--border);
  }

  .session-drawer {
    order: 1;
    position: relative;
    inset: auto;
    z-index: 1;
    /* 固定左栏宽度（随卡片变窄时可略缩），与中间 4:3 外框无关 */
    flex: 0 0 min(300px, 42%);
    min-width: 0;
    height: auto;
    align-self: stretch;
    display: flex;
    flex-direction: row;
    align-items: stretch;
    pointer-events: auto;
    visibility: visible;
    transition: none;
  }

  .session-drawer-panel {
    flex: 1 1 auto;
    width: 100%;
    min-width: 0;
    max-width: none;
    height: 100%;
    transform: none !important;
    box-shadow: none;
    border-right: 1px solid var(--border);
    background: var(--surface);
    will-change: auto;
  }

  /* 深色全局规则特异度更高，否则会盖掉上面的 box-shadow: none */
  [data-theme="dark"] .session-drawer-panel {
    box-shadow: none;
  }

  .session-drawer.open .session-drawer-panel,
  .session-drawer:not(.open) .session-drawer-panel {
    transform: none !important;
    will-change: auto;
  }

  .session-drawer-scrim {
    display: none !important;
  }

  /* 桌面左栏底色为 --surface，红点描边与列表底一致 */
  .session-row-avatar-wrap.has-unread::after {
    box-shadow: 0 0 0 2px var(--surface);
  }

  .chat-layer {
    order: 2;
    flex: 1 1 0;
    min-width: 0;
    min-height: 0;
    border-left: none;
    background: var(--bg);
  }

  /* 分享页：单栏铺满 4:3 卡片 */
  .app.share-app .chat-layer {
    flex: 1 1 auto;
    width: 100%;
    min-width: 0;
  }

  .header-back {
    display: none !important;
  }

  /* 无「返回」槽位后，概述条略加宽 */
  .sub--editable {
    width: calc(100% - 52px);
  }

  /* 左侧列表顶栏：与右侧标题区视觉对齐 */
  .top-list {
    padding-left: 14px;
  }
}

/* 全屏加载占位（进入应用前的短暂加载） */
.app-loading {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
  color: var(--muted);
  font-size: 14px;
  gap: 10px;
}

.app-loading .spinner {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  animation: app-spin 0.8s linear infinite;
}

@keyframes app-spin {
  to { transform: rotate(360deg); }
}

/* 系统开启「减少动态效果」时：浮层 / 抽屉 / 气泡入场几乎瞬时完成，避免眩晕也减轻低端机 GPU 压力 */
@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-duration: 0.01ms;
    --motion-duration-short: 0.01ms;
  }

  .msg-row-enter {
    animation: none;
  }

  .app-loading .spinner {
    animation: none;
    border-color: var(--border);
    border-top-color: var(--accent);
  }

  .confirm-overlay,
  .auth-overlay {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }

  .app.app--enter,
  .app.app--enter.app--enter-active {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  .auth-overlay.auth-overlay--success.open .auth-card {
    transform: none !important;
    box-shadow: var(--panel-shadow) !important;
  }
}

@media (prefers-reduced-motion: reduce) and (min-width: 960px) {
  .overlay .sheet,
  .overlay.open .sheet {
    transform: none;
    transition: none;
  }
}
