/* 通话页：桌面＝居中玻璃浮窗 + 遮罩，手机＝全屏；--call-bg-* 三个变量由 js/call.js 写 */

:root {
  /* 声波线：雾蓝要"雾而不灰"（与背景同亮度）；金粉借用标题底线暖色，5 根蓝金交替 */
  --call-wave-c1: #7C8DD6;
  --call-wave-c2: var(--color-chat-title-line-warm);
  --call-wave-lines: 5;
  /* 气泡纸面上的细噪点浓度；深色主题白颗粒显脏，themes.css 里压到一半 */
  --call-bubble-grain: 0.12;
  /* 挂断键那行花体字的白色镶边：贴上背景图后字还抓得住；深色套在 themes.css 里压淡 */
  --call-script-glow: rgba(255, 255, 255, 0.92);
  /* 挂断键两行字底下的白光分三档（花体外层 / 花体里层 / 中文那行）：深色套里白光最刺眼，
     themes.css 里整套压到五分之一 */
  --call-glow-en-1: rgba(255, 255, 255, 0.26);
  --call-glow-en-2: rgba(255, 255, 255, 0.12);
  --call-glow-cn: rgba(255, 255, 255, 0.65);
  /* hover 必须换更浅的一支——opacity 只会压深，永远调不出"更浅"；五套主题各配一支 */
  --call-send: #8795b4;
  --call-send-hover: #bcc8e8;
}

.call-overlay {
  position: fixed;
  inset: 0;
  z-index: 820;
  display: none;
  /* 退场：整层淡出；时长与 call.js 的 CALL_CLOSE_MS 对齐 */
  transition: opacity 0.32s ease;
}

/* 入场：整层淡入（照永恒之书的底图淡入），桌面浮卡在下方媒体块里另做轻升 */
.call-overlay.show {
  display: block;
  animation: callLayerIn 0.8s ease-out;
}

.call-overlay.closing {
  opacity: 0;
  pointer-events: none;
  /* 入场没演完就关：先掐掉入场，免得卡面反而亮一下 */
  animation: none;
}

@keyframes callLayerIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes callPanelIn {
  from { transform: translateY(10px) scale(0.992); }
  to { transform: none; }
}

.call-panel {
  --call-pad: 24px;
  /* 消息区与输入栏共用的左右边：两处对齐全靠它 */
  --call-edge: calc(var(--call-pad) * 1.5);
  /* 消息区上缘渐隐的高度；滚动区的上留白用它同一个值（贴顶时第一条不许正好坐在渐隐里） */
  --call-fade-h: 28px;
  --font-home-text: 'Cormorant Garamond', 'Times New Roman', 'Songti SC', 'SimSun', serif;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  color: var(--color-home-ink);
  background:
    radial-gradient(ellipse at 18% 0%, var(--color-home-glow-a) 0%, transparent 42%),
    radial-gradient(ellipse at 96% 82%, var(--color-home-glow-c) 0%, transparent 44%),
    radial-gradient(ellipse at 0% 100%, var(--color-home-glow-b) 0%, transparent 38%),
    var(--color-home-bg);
}

/* 插图的米白薄纱：与晨窗 .home-bg-tint 同款同值，没它图会把纸底那层光盖平；.has-bg 由 js/call.js 打 */
.call-panel::after {
  content: '';
  display: none;
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(180deg,
    var(--color-home-image-tint) 0%,
    var(--color-home-image-tint) 44%,
    transparent 68%,
    transparent 88%,
    var(--color-home-image-tint) 100%);
}

.call-overlay.has-bg .call-panel::after { display: block; }

/* 与晨窗同一张噪点纹理：纸感全靠它 */
.call-panel::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.14;
  background-image: url("data:image/svg+xml,%3Csvg width='200' height='200' viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.78' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.32'/%3E%3C/svg%3E");
}

/* 插图：默认没有（none），传了图 call.js 换成 url(data:...) */
.call-bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.call-bg::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: var(--call-bg-image, none);
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  opacity: var(--call-bg-alpha, 0.28);
  filter: blur(var(--call-bg-blur, 0px));
  transform: scale(1.03);
}

/* —— 顶部：左边一句英文小语，右边「时段 + 英文日期」（抄晨窗 .home-topline）—— */
.call-topline {
  position: relative;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 14px;
  padding: calc(var(--call-pad) + env(safe-area-inset-top, 0px)) var(--call-pad) 0;
  font-family: var(--font-home-text);
  font-size: 0.58rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  color: var(--color-home-ink);
  opacity: 0.62;
}

/* 时段标签贴在日期左边：字色、字号、正体全都随顶部这行，不加任何自带的样式 */
.call-topline-right {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
}

/* —— 舞台：声波在中间那段，他的头像坐在正中，四周都让开 —— */
.call-stage {
  position: relative;
  /* 3：声波画布比舞台高，要压过上面的英文行和下面的中文行（不然穿过去就被盖住/裁掉） */
  z-index: 3;
  flex: 0 0 auto;
  height: clamp(120px, 17%, 150px);
  display: flex;
  align-items: center;
  justify-content: center;
  /* 上留白把头像往下送（居中的内容只吃到它的一半）；整块也长高了些，声波上下都留出位置、不再贴住顶上那行英文 */
  padding: 22px 13% 0;
}

/* 声波两端渐隐，不许贴卡片边、也不许横成实线；★ width 必须写死，只给 left/right 会退回固有宽度 */
.call-wave {
  position: absolute;
  left: 12%;
  width: 76%;
  top: calc(50% + 11px);       /* 跟头像同下移（舞台 padding-top 的一半）；别写回 50%，否则声波贴到顶部那行英文 */
  /* 高度只是余量：振幅不按这个盒子算，见 js 的 CALL_WAVE_REACH */
  height: 220px;
  transform: translateY(-50%);
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to right, transparent 0, black 14%, black 86%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, black 14%, black 86%, transparent 100%);
}

/* 圆头像：光从上面来——上半的框线淡、下半深，投影只压在下沿，球才"坐"在纸上。
   别再加一圈均匀的白 rim / 均匀外环：那是"画了个框"，不是立体 */
.call-avatar {
  position: relative;
  z-index: 1;
  width: min(11vh, 80px);
  height: min(11vh, 80px);
  object-fit: cover;
  border-radius: 50%;
  border: 1.5px solid var(--color-home-faint);
  /* 四边分浓淡（上 45% / 侧 72% / 下原浓度）：旧壳不认 color-mix 就退回上面那条均匀框 */
  border-color:
    color-mix(in srgb, var(--color-home-faint) 45%, transparent)
    color-mix(in srgb, var(--color-home-faint) 72%, transparent)
    var(--color-home-faint)
    color-mix(in srgb, var(--color-home-faint) 72%, transparent);
  background: var(--color-home-accent-soft);
  box-shadow:
    0 -1px 3px rgba(255, 255, 255, 0.60),
    0 12px 26px -8px rgba(34, 47, 96, 0.51),
    0 5px 11px -3px rgba(34, 47, 96, 0.36);
  animation: callBreathe 7s ease-in-out infinite;
}

.call-avatar[data-no-shadow="true"] {
  box-shadow: none;
  border-radius: 0;
  border: none;
  background: none;
  object-fit: contain;
}

@keyframes callBreathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.014); }
}

/* —— 头像下方那句轻声呢喃：中文衬线主句 → Kapakana 花体英文 → 括号斜体中文（译）—— */
.call-murmur {
  /* 中文→英文的间距要看着和「头像→中文」同宽：花体字面扁、墨压在行盒下半 */
  --call-murmur-gap: 9px;
  display: flex;
  position: relative;
  z-index: 2;
  flex: none;
  flex-direction: column;
  align-items: center;
  /* 上边距把它和头像拉开，下边距把消息区让开 */
  padding: 12px calc(var(--call-pad) * 1.4) 18px;
  text-align: center;
  pointer-events: none;
}

.call-murmur-cn {
  /* 这行永远以全角「。」「？」收尾：字占满一个字宽、墨却挤在左下，
     按字盒居中时正文看着偏左。右移半个字宽把正文按回视觉正中（要更右就调大这一行） */
  --call-murmur-nudge: 0.7rem;
  font-family: var(--font-home-text);
  font-size: 0.92rem;
  font-weight: 400;
  line-height: 1.45;
  letter-spacing: 0.12em;
  text-indent: 0.12em;
  color: var(--color-home-ink);
  opacity: 0.82;
  transform: translateX(var(--call-murmur-nudge));
}

/* Kapakana 是家里自托管的花体，没有斜体版——别拧 italic，会变脏 */
.call-murmur-en {
  margin-top: var(--call-murmur-gap);
  font-family: 'Kapakana', 'Cormorant Garamond', serif;
  font-style: normal;
  font-size: 1.35rem;
  line-height: 1.05;
  letter-spacing: 0.04em;
  color: var(--color-home-ink);
  opacity: 0.58;
}

.call-murmur-tr {
  margin-top: 3px;
  font-family: var(--font-home-text);
  font-style: italic;
  font-size: 0.61rem;
  line-height: 1.4;
  letter-spacing: 0.1em;
  color: var(--color-home-ink);
  opacity: 0.4;
}

.call-murmur.is-in { animation: callMurmurIn 0.7s var(--ease-out-expo) both; }

@keyframes callMurmurIn {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

/* —— 消息区：玻璃气泡（抄 .home-glass），他左她右 —— */
/* 滚动区子节点 = 一条消息（callApplyWindow 数 children）；★ 渐隐必须挂 mask，别叠一层实色——那样一插背景图就一道白截断 */
.call-log {
  position: relative;
  z-index: 2;
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* 上下留白都等于渐隐高度：贴顶/贴底时第一条与最后一条都正好落在渐隐之外 */
  padding: var(--call-fade-h, 28px) var(--call-edge);
  display: flex;
  flex-direction: column;
  gap: 16px;
  scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to bottom,
    transparent 0, black var(--call-fade-h, 28px),
    black calc(100% - var(--call-fade-h, 28px)), transparent 100%);
  mask-image: linear-gradient(to bottom,
    transparent 0, black var(--call-fade-h, 28px),
    black calc(100% - var(--call-fade-h, 28px)), transparent 100%);
}

.call-log::-webkit-scrollbar { display: none; }

/* 一条消息 = 一个 .call-msg（动作小字 + 若干气泡按序排在里面）。
   max-width 挂在消息上、气泡自己撑满：两层各 92% 会缩成 85% */
.call-msg {
  display: flex;
  flex-direction: column;
  gap: 3px;
  max-width: 92%;
}

.call-msg.his { align-self: flex-start; align-items: flex-start; }
.call-msg.mine { align-self: flex-end; align-items: flex-end; }

.call-bubble {
  position: relative;
  /* 颗粒是 z-index:-1 的伪元素：必须让气泡自己成为层叠上下文（否则它会掉到纸底下面、完全看不见） */
  isolation: isolate;
  max-width: 100%;
  padding: 8px 13px;
  border: 0.5px solid var(--color-home-card-rim);
  /* ★ 别改 --color-home-card-bg：晨窗卡也在用它；气泡靠这层不透光纸底，mask 已废掉磨砂 */
  background-color: var(--color-home-bubble-bg);
  background-image: linear-gradient(158deg, var(--color-home-card-rim) 0%, transparent 44%);
  box-shadow:
    0 10px 26px -18px var(--color-home-card-shadow),
    inset 0 0 14px -2px var(--color-home-card-rim);
  font-family: var(--font-home-text);
  font-size: 0.82rem;
  font-weight: 400;
  line-height: 1.8;
  white-space: pre-wrap;
  word-break: break-word;
}

/* 纸面噪点与卡片纸纹同一张 SVG；气泡质感全靠它（磨砂已下线） */
.call-bubble::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background-image: url("data:image/svg+xml,%3Csvg width='200' height='200' viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='grain'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.78' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23grain)'/%3E%3C/svg%3E");
  opacity: var(--call-bubble-grain, 0.12);
  pointer-events: none;
}

/* transform-origin 必须钉在尾巴尖角上，弹出动画才从那儿长开 */
.call-bubble.his {
  border-radius: 18px 18px 18px 6px;
  transform-origin: 6px 100%;
}

.call-bubble.mine {
  border-radius: 18px 18px 6px 18px;
  transform-origin: calc(100% - 6px) 100%;
  opacity: 0.9;
}

/* 动作描写（括号里的）：气泡上方一行斜体衬线小字，来源与呢喃那句译文同一套 */
.call-act {
  --call-act-op: 0.48;
  padding: 0 6px;
  font-family: var(--font-home-text);
  font-style: italic;
  font-size: 0.66rem;
  line-height: 1.5;
  letter-spacing: 0.06em;
  color: var(--color-home-ink);
  opacity: var(--call-act-op);
}

/* 台词之后再来一段动作：拉开一档，别跟上一句黏成一坨 */
.call-bubble + .call-act { margin-top: 5px; }

/* ★ 别加透明度淡入：opacity<1 的祖先会成为 Backdrop Root，动画全程气泡底透明 */
@keyframes callBubblePop {
  from { transform: translateY(7px) scale(0.7); }
  to { transform: none; }
}

.call-bubble.pop {
  animation: callBubblePop 0.6s cubic-bezier(0.22, 0.7, 0.3, 1) both;
}

/* 动作小字：淡入 + 轻轻上浮（终点 opacity 用变量取，别写 1——收尾会跳到静息值） */
@keyframes callActIn {
  from { opacity: 0; transform: translateY(3px); }
  to { opacity: var(--call-act-op); transform: none; }
}

.call-act.is-in { animation: callActIn 0.5s var(--ease-out-expo) both; }

@media (prefers-reduced-motion: reduce) {
  .call-overlay.show,
  .call-bubble.pop,
  .call-act.is-in,
  .call-murmur.is-in { animation: none; }
}

/* —— 挂断键：整张卡唯一的出口（没有 ×，点外面也关不掉）——
   无边框无底色，一枚细线话筒剪影 + 下方一行「英文 · 中文」；放在输入栏上方 */
.call-hangup {
  position: relative;        /* 上方那枚气泡提示挂在这上头 */
  z-index: 3;                /* 消息区是 z-index:2，气泡要压在它上面才浮得出来 */
  align-self: center;
  flex: none;
  /* 下边距给挂在花体下面那行中文留位置（它不占布局，靠这段空白吃饭） */
  margin: 0 0 12px;
  padding: 4px 10px;
  border: none;
  background: none;
  box-shadow: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  /* 砖红火苗要从莫兰迪灰里提亮一档：是"烧着的砖"，不是"旧的砖" */
  color: #b25a3d;
  cursor: var(--pl-cursor-pointer, pointer);
  transition: color 0.25s, opacity 0.25s;
  opacity: 0.9;
}

/* 话筒 fill 走 currentColor；这张图本身朝右上，顺时针 225° 才是挂断 */
.call-hangup svg {
  display: block;
  width: 30px;
  height: 30px;
  transform: rotate(225deg);
  opacity: 0.92;
}

/* ★ 中文必须绝对定位到英文正下方、不占布局：放回行内整块会被顶上去；Kapakana 字面只有一半高，1rem 看着才像 0.5rem */
.call-hangup-line {
  position: relative;
  isolation: isolate;        /* 白光要压在字后面（::before 的 z-index:-1） */
  display: inline-flex;
  align-items: baseline;
  white-space: nowrap;
}

/* 这一行字底下单独垫的一层薄白光：只给两档很低的浓度、衰减快，别再往中间堆高浓度——
   堆高就是"拿白刷子抹了一道" */
.call-hangup-line::before {
  content: '';
  position: absolute;
  inset: -4px -18px;
  z-index: -1;
  border-radius: 999px;
  background:
    radial-gradient(ellipse 56% 100% at 50% 55%, var(--call-glow-en-1) 0%, rgba(255, 255, 255, 0) 62%),
    radial-gradient(ellipse at 50% 50%, var(--call-glow-en-2) 0%, rgba(255, 255, 255, 0) 92%);
  filter: blur(8px);
  pointer-events: none;
}

.call-hangup-en {
  font-family: 'Kapakana', 'Cormorant Garamond', serif;
  font-style: normal;               /* 它没有斜体版，硬拧会变脏 */
  font-size: 1.2rem;
  line-height: 1.05;
  letter-spacing: 0.04em;
  opacity: 0.9;
  /* 白色镶边：贴上背景图后花体还抓得住（深色套的浓度在 themes.css 里） */
  text-shadow: 0 0 14px var(--call-script-glow), 0 0 3px var(--call-script-glow);
}

.call-hangup-tr {
  position: absolute;
  top: calc(100% + 2px);
  left: 50%;
  transform: translateX(-50%);
  /* 单独成层：底下那圈白光要压在字后面（z-index:-1 只在本层内生效） */
  isolation: isolate;
  white-space: nowrap;
  font-family: var(--font-home-text);
  font-style: italic;
  font-size: 0.62rem;
  line-height: 1.3;
  letter-spacing: 0.06em;
  opacity: 0.58;
  text-shadow: 0 0 10px var(--call-script-glow);
  pointer-events: none;             /* 挂在按钮外面：点它不该等于挂断 */
}

/* ★ 这行 opacity 0.58，白光浓度必须按 1/(0.58×0.9) 折回来，别照抄上面那组数字 */
.call-hangup-tr::before {
  content: '';
  position: absolute;
  inset: -4px -16px;
  z-index: -1;
  border-radius: 999px;
  background: radial-gradient(ellipse at 50% 50%, var(--call-glow-cn) 0%, rgba(255, 255, 255, 0) 88%);
  filter: blur(7px);
  pointer-events: none;
}

/* 悬停要变淡变亮（原来是往深里走 #8e4a44，越 hover 越闷，看着奇怪） */
.call-hangup:hover { color: #d4735b; opacity: 1; }

/* ── 挂断键上方的气泡提示：贴按钮绝对定位（不占高度），两句话叠同一格，短提示出现时状态让位 ── */
.call-hint {
  position: absolute;
  left: 50%;
  bottom: 100%;   /* 贴着挂断键上沿：再往上就擦到最底下那条消息气泡了（她量出来的） */
  transform: translateX(-50%);
  display: grid;
  padding: 4px 13px;
  border: 0.5px solid var(--color-home-card-rim);
  border-radius: 999px;
  background-color: var(--color-home-bubble-bg);
  box-shadow: 0 8px 20px -16px var(--color-home-card-shadow);
  font-size: 0.62rem;
  line-height: 1.3;
  letter-spacing: 0.06em;
  color: var(--color-home-ink);
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.25s var(--ease-out-expo);
  pointer-events: none;
}

.call-hint.show { opacity: 1; }

.call-hint-status,
.call-hint-note {
  grid-area: 1 / 1;
  text-align: center;
  font-family: var(--font-home-text);
  font-style: italic;
  transition: opacity 0.2s var(--ease-out-expo);
}

.call-hint-status { opacity: 0.55; }
.call-hint-note { opacity: 0; }
.call-hint-note.show { opacity: 0.85; }
.call-hint.has-note .call-hint-status { opacity: 0; }

/* 虚线是输入栏自己的底线，不是横贯卡片的分割线；底边距别再缩回去 */
.call-bar {
  position: relative;
  z-index: 2;
  flex: none;
  display: flex;
  align-items: flex-end;
  gap: 14px;
  padding: 3px var(--call-edge) calc(48px + env(safe-area-inset-bottom, 0px));
}

.call-input {
  flex: 1 1 auto;
  min-width: 0;
  border: none;
  border-bottom: 0.5px dashed var(--color-home-faint);
  background: none;
  outline: none;
  padding: 7px 0;
  font-family: var(--font-home-text);
  font-size: 0.86rem;
  font-weight: 400;
  letter-spacing: 0.02em;
  color: var(--color-home-ink);
  caret-color: var(--color-home-ink);
}

.call-input::placeholder {
  color: var(--color-home-ink);
  opacity: 0.38;
}

/* 结构对标晨窗导航那颗按钮；别用 opacity 调浓淡，它只会压深 */
.call-send {
  /* ★ 必须用负下距、不能用 position:top：按钮比输入行高，撑高底栏会把上面整块顶上去 */
  margin-bottom: -23px;
  flex: none;
  border: none;
  background: none;
  padding: 2px 0 2px 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  /* 静息色随主题（--call-send，五套各一支） */
  color: var(--call-send);
  cursor: var(--pl-cursor-pointer, pointer);
  transition: color 0.2s var(--ease-out-expo), transform 0.2s var(--ease-out-expo);
}

.call-send svg {
  display: block;
  width: 28px;
  height: 28px;
}

/* 花体与挂断键那行英文同字号同字体（Kapakana 字面小，1.2rem 才和普通小字一档） */
.call-send span {
  font-family: 'Kapakana', 'Cormorant Garamond', serif;
  font-size: 1.2rem;
  line-height: 1;
  letter-spacing: 0.04em;
}

/* hover 比静息亮一档（--call-send-hover），同时微微放大 */
.call-send:hover {
  color: var(--call-send-hover);
  transform: scale(1.07);
}

.call-send:active {
  transform: scale(0.96);
}

/* —— 桌面：压暗压糊一层遮罩，中间浮起 520 宽的玻璃卡（尺寸与圆角照晨窗）—— */
@media (min-width: 801px) {
  .call-overlay {
    background: var(--color-home-veil);
    -webkit-backdrop-filter: blur(9px);
    backdrop-filter: blur(9px);
  }

  .call-overlay.show {
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .call-panel {
    position: relative;
    --call-pad: 30px;
    --call-edge: 64px;      /* 桌面：输入栏与消息区共用这一条边，一起收在 64px */
    width: min(520px, calc(100vw - 48px));
    height: min(720px, calc(100vh - 64px));
    border: 0.5px solid var(--color-home-card-rim);
    border-radius: 36px;
    box-shadow: 0 24px 70px var(--color-home-card-shadow);
    transition: transform 0.32s var(--ease-out-expo);
  }

  /* 桌面浮窗入场：从退场那一档原地轻升回来 */
  .call-overlay.show .call-panel {
    animation: callPanelIn 1s cubic-bezier(0.22, 1, 0.36, 1);
  }

  .call-overlay.closing .call-panel {
    transform: translateY(10px) scale(0.992);
    animation: none;
  }

  /* 桌面版式：输入行离底边再让开一档，挂断键的点击区按字面放宽 */
  .call-bar {
    padding: 3px var(--call-edge) 80px;
  }

  .call-hangup {
    padding: 4px 20px;
  }
}

/* —— 手机：整屏（版式尺寸跟桌面同一套，手机专属的那点差异只留在这几条）—— */
@media (max-width: 800px) {
  .call-panel {
    position: absolute;
    inset: 0;
    --call-pad: 20px;
    /* 手机端中文一律非衬线（OPPO WebView 取不到中文衬线） */
    --font-home-text: 'Cormorant Garamond', -apple-system, 'PingFang SC', 'Microsoft YaHei', sans-serif;
  }

  /* 照晨窗贴顶：4px 是唯一能调的，env() 是安全区不许删；字号/字距按 354 屏收成一行
     （照抄晨窗的 0.66rem/2.2px 会折两行） */
  .call-topline {
    padding-top: calc(4px + env(safe-area-inset-top, 0px));
    font-size: 0.62rem;
    font-style: italic;
    letter-spacing: 1.2px;
    color: var(--color-home-faint);
    opacity: 1;
    white-space: nowrap;
  }

  .call-topline-right { margin-left: auto; }

  /* 中文时段不跟着斜 */
  .call-daypart { font-style: normal; }

  /* 手机端整页统一 300 字重：400 的中文在安卓上发粗 */
  .call-panel,
  .call-panel * { font-weight: 300; }

  /* 手机端气泡单独收一档字号、放宽字距（桌面仍是 0.82rem、无字距） */
  .call-bubble {
    font-size: 0.78rem;
    letter-spacing: 0.08em;
  }

  /* 手机端输入栏与占位字跟气泡同字号 */
  .call-input { font-size: 0.78rem; }

  /* 手机端挂断键整组：金描边 + 字脚暗影把红字从白光里托出来；描边别低于 0.3px，安卓不渲染 */
  .call-hangup svg path {
    stroke: var(--color-home-warm);
    stroke-width: 0.6px;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
  }

  .call-hangup-en {
    -webkit-text-stroke: 0.3px var(--color-home-warm);
    text-shadow:
      0 0 14px var(--call-script-glow),
      0 0 3px var(--call-script-glow),
      0 1px 2px rgba(30, 12, 8, 0.45);
  }

  .call-hangup-tr {
    -webkit-text-stroke: 0.3px var(--color-home-warm);
    text-shadow:
      0 0 10px var(--call-script-glow),
      0 1px 2px rgba(30, 12, 8, 0.45);
  }

  /* 全屏时舞台更高、头像下面那圈空白也更大：中文→英文跟着放大，仍与「头像→中文」齐平 */
  .call-murmur {
    --call-murmur-gap: 18px;
  }
}

/* —— 消息头那枚话筒：不碰它时什么都不显示（桌面 hover / 触屏点名字才淡入 0.3s） —— */
.msg-call-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  margin-left: 2px;
  border: none;
  background: none;
  padding: 0;
  cursor: var(--pl-cursor-pointer, pointer);
  color: var(--color-msg-action);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease, color 0.25s ease, filter 0.25s ease;
}

/* 图标定死尺寸：<svg> 有 viewBox 没 width/height 时会退回 300×150 的默认值 */
.msg-call-btn svg {
  display: block;
  width: 16px;
  height: 16px;
}

.msg-call-btn:hover {
  color: var(--color-msg-action-hover);
  filter: drop-shadow(0 0 4px var(--color-msg-action-hover-glow));
}

/* ★ 露出必须分两条路（桌面 :hover / 触屏 .call-on），别写成"普适 hover + 后面再按回去"：手机会黏住 */
@media (hover: hover) {
  .msg-avatar-row:hover .msg-call-btn {
    opacity: 1;
    pointer-events: auto;
  }
}

/* 触屏：只认点到名字后挂上的 .call-on（淡入 0.3s 由 .msg-call-btn 自己的 transition 负责） */
.msg-avatar-row.call-on .msg-call-btn {
  opacity: 1;
  pointer-events: auto;
}

/* 桌面浮窗的入场动画在 801px 块里，压降必须写在它之后 */
@media (prefers-reduced-motion: reduce) {
  .call-overlay.show .call-panel { animation: none; }
}
