/* 语音消息 + 语音/视频通话（第 139 章）
 * 与 app.css 里的聊天样式配套；单独成文件是为了不把 3800 行的 app.css 再撑大。
 * 命名前缀：.wx-* 输入栏、.voice-* 语音消息、.rtc-* 通话界面。
 */

/* ================= 输入栏：语音 / 键盘切换 ================= */
.wx-inputbar { position: relative; }
.wx-vsw { flex: none; width: 38px; height: 42px; border: 0; background: transparent; font-size: 21px;
  line-height: 1; color: #5b5b66; border-radius: 10px; display: flex; align-items: center; justify-content: center;
  -webkit-tap-highlight-color: transparent; }
.wx-vsw:active { background: rgba(0,0,0,.06); }
.wx-vsw svg { width: 24px; height: 24px; color: #55555f; }
/* touch-action:none 是「按住说话」的命门：不加的话手指一按，
 * 浏览器就按滚动页面处理并甩一个 pointercancel 过来，录音当场作废 */
.wx-hold { flex: 1; height: 44px; border: 0; border-radius: 10px; background: #fff;
  font-size: 15.5px; color: #333; font-weight: 600; letter-spacing: 1px;
  touch-action: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent; }
.wx-hold.rec { background: #e9e9ee; color: #6a6a75; transform: scale(.995); }
.wx-field.hide, .wx-hold.hide, .wx-vsw.hide { display: none; }

/* 录音浮层 */
.rec-hud { position: fixed; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 9800;
  width: 168px; padding: 18px 14px 14px; border-radius: 18px; background: rgba(28,26,36,.9);
  color: #fff; text-align: center; backdrop-filter: blur(6px); pointer-events: none; }
.rec-hud .m { font-size: 30px; line-height: 1; }
.rec-hud .t { margin-top: 8px; font-size: 13px; letter-spacing: .5px; }
.rec-hud .s { margin-top: 6px; font-size: 11.5px; opacity: .72; }
.rec-hud .bars { display: flex; gap: 3px; align-items: flex-end; justify-content: center; height: 26px; margin: 10px 0 2px; }
.rec-hud .bars i { width: 3px; border-radius: 2px; background: #ff8fa8; animation: rec-bar .9s ease-in-out infinite; }
.rec-hud .bars i:nth-child(1) { height: 8px; animation-delay: 0s; }
.rec-hud .bars i:nth-child(2) { height: 16px; animation-delay: .1s; }
.rec-hud .bars i:nth-child(3) { height: 24px; animation-delay: .2s; }
.rec-hud .bars i:nth-child(4) { height: 14px; animation-delay: .3s; }
.rec-hud .bars i:nth-child(5) { height: 20px; animation-delay: .4s; }
@keyframes rec-bar { 0%, 100% { transform: scaleY(.4); } 50% { transform: scaleY(1); } }
/* 真机有麦克风电平时，条子高度由 JS 按实时音量写，关掉假动画 */
.rec-hud.live .bars i { animation: none; transition: height .09s linear; }
.rec-hud.cancel { background: rgba(168,32,52,.94); }

/* ================= 语音消息气泡 ================= */
.bubble.voice { padding: 8px 12px; position: relative; white-space: normal; }
.voice-b { display: flex; align-items: center; gap: 8px; min-height: 22px; }
.voice-b .vb { display: inline-flex; align-items: flex-end; gap: 3px; height: 18px; }
.voice-b .vb i { width: 3px; border-radius: 2px; background: currentColor; opacity: .9; }
.voice-b .vb i:nth-child(1) { height: 8px; }
.voice-b .vb i:nth-child(2) { height: 14px; }
.voice-b .vb i:nth-child(3) { height: 18px; }
.voice-b .dur { font-size: 12.5px; opacity: .85; min-width: 22px; text-align: right; }
.bubble-row.mine .voice-b { flex-direction: row-reverse; }
.bubble.voice.playing .vb i { animation: vb .8s ease-in-out infinite; }
.bubble.voice.playing .vb i:nth-child(2) { animation-delay: .15s; }
.bubble.voice.playing .vb i:nth-child(3) { animation-delay: .3s; }
@keyframes vb { 0%, 100% { transform: scaleY(.45); } 50% { transform: scaleY(1.15); } }
/* 未听过的语音：红点 + 播放进度条（底部一条细线，跟着 currentTime 走） */
.bubble.voice .v-dot { position: absolute; right: 3px; top: 3px; width: 8px; height: 8px; border-radius: 50%;
  background: #ff4d6d; box-shadow: 0 0 0 1.5px rgba(255,255,255,.9); }
.bubble.voice .voice-p { position: absolute; left: 8px; right: 8px; bottom: 3px; height: 2px;
  background: rgba(0,0,0,.08); border-radius: 2px; overflow: hidden; }
.bubble.voice .voice-p i { display: block; height: 100%; width: 0; background: currentColor; opacity: .45; border-radius: 2px; }
.bubble-row.mine .bubble.voice .voice-p { background: rgba(255,255,255,.22); }
/* 上传中的语音：气泡淡一点 + 右下角小转圈，一眼能看出「还在发」 */
.bubble.voice.sending { opacity: .6; }
.bubble.voice.sending::after { content: ''; position: absolute; right: 4px; bottom: 4px; width: 8px; height: 8px;
  border-radius: 50%; border: 1.5px solid currentColor; border-top-color: transparent;
  animation: vspin .8s linear infinite; opacity: .75; }
@keyframes vspin { to { transform: rotate(360deg); } }

/* 通话记录气泡（微信风格：一行小字 + 图标） */
.bubble.call-b { display: flex; align-items: center; gap: 7px; font-size: 13.5px; cursor: pointer; }
.bubble.call-b .ci { font-size: 16px; }
.bubble.call-b .miss { color: #e2556b; }
.bubble-row.mine .bubble.call-b .miss { color: #fff; opacity: .92; }

/* ================= 通话界面 ================= */
.rtc-layer { position: fixed; inset: 0; z-index: 9700; display: flex; flex-direction: column;
  align-items: center; justify-content: center; color: #fff; overflow: hidden;
  background: radial-gradient(circle at 50% 30%, #3a3550 0%, #201d2e 55%, #14121d 100%);
  animation: rtc-in .22s ease; }
@keyframes rtc-in { from { opacity: 0; transform: scale(.98); } to { opacity: 1; transform: none; } }
.rtc-layer.video { background: #0b0b10; }

.rtc-bg { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 0 30px; text-align: center; }
.rtc-bg.hide { display: none; }
.rtc-av { width: 96px; height: 96px; border-radius: 28px; background: #4a4560 center/cover no-repeat;
  display: flex; align-items: center; justify-content: center; font-size: 34px; color: rgba(255,255,255,.9);
  box-shadow: 0 10px 30px rgba(0,0,0,.35); }
.rtc-nm { font-size: 20px; font-weight: 700; letter-spacing: .5px; }
.rtc-st { font-size: 13px; opacity: .72; letter-spacing: .5px; }

/* 语音通话的呼吸波纹 */
.rtc-wave { display: flex; gap: 4px; align-items: flex-end; height: 26px; margin-top: 4px; }
.rtc-wave i { width: 4px; border-radius: 2px; background: #ff8fa8; opacity: .85; animation: rtc-w 1.1s ease-in-out infinite; }
.rtc-wave i:nth-child(1) { height: 10px; animation-delay: 0s; }
.rtc-wave i:nth-child(2) { height: 18px; animation-delay: .12s; }
.rtc-wave i:nth-child(3) { height: 26px; animation-delay: .24s; }
.rtc-wave i:nth-child(4) { height: 16px; animation-delay: .36s; }
.rtc-wave i:nth-child(5) { height: 12px; animation-delay: .48s; }
@keyframes rtc-w { 0%, 100% { transform: scaleY(.4); } 50% { transform: scaleY(1); } }

/* 视频画面 */
.rtc-remote { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; background: #000; }
.rtc-local { position: absolute; right: 14px; top: 70px; width: 96px; height: 130px; border-radius: 12px;
  object-fit: cover; background: #1c1a26; box-shadow: 0 6px 18px rgba(0,0,0,.4); z-index: 2;
  border: 1px solid rgba(255,255,255,.14); }
.rtc-layer.video .rtc-bar { position: absolute; left: 0; right: 0; bottom: 34px; z-index: 3; }
.rtc-layer.video .rtc-timer { position: absolute; left: 50%; top: 26px; transform: translateX(-50%);
  padding: 4px 12px; border-radius: 20px; background: rgba(0,0,0,.42); font-size: 13px; letter-spacing: 1px; z-index: 3; }

.rtc-timer { margin-top: 14px; font-size: 15px; letter-spacing: 1px; opacity: .85; font-variant-numeric: tabular-nums; }
/* 还没接通时显示「接通中」，不要跟真正的计时抢注意力 */
.rtc-timer.dim { opacity: .5; font-size: 13px; letter-spacing: .5px; }
/* 来电倒计时（服务端到点判 missed，先告诉用户还剩几秒） */
.rtc-ring-left { margin-top: 2px; font-size: 12px; opacity: .55; letter-spacing: .4px; }

.rtc-bar { position: absolute; left: 0; right: 0; bottom: 46px; display: flex; justify-content: center; gap: 34px; }
.rtc-act { width: 66px; height: 66px; border-radius: 50%; border: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px; font-size: 11.5px; letter-spacing: .5px;
  background: rgba(255,255,255,.16); color: #fff; -webkit-tap-highlight-color: transparent; }
.rtc-act::before { font-size: 22px; line-height: 1; }
.rtc-act:active { transform: scale(.95); }
#rtc-mute::before { content: '🎤'; }
#rtc-mute.on { background: rgba(255,255,255,.34); }
#rtc-mute.on::before { content: '🔇'; }
#rtc-cam::before { content: '🔄'; }
#rtc-camoff::before { content: '📷'; }
#rtc-camoff.on { background: rgba(255,255,255,.34); }
#rtc-camoff.on::before { content: '🚫'; }
.rtc-local.off { opacity: .25; }
#rtc-end { background: #e5455f; }
#rtc-end::before { content: '📵'; }
#rtc-accept { background: #2fbf6a; }
#rtc-accept::before { content: '📞'; }
#rtc-reject { background: #e5455f; }
#rtc-reject::before { content: '📵'; }
.rtc-layer.incoming .rtc-bar { gap: 60px; }

/* 视频通话顶部：对方昵称（整屏画面时也要知道在跟谁聊） */
.rtc-head { position: absolute; left: 0; right: 0; top: 22px; z-index: 3; text-align: center; pointer-events: none; }
.rtc-head-nm { font-size: 17px; font-weight: 700; text-shadow: 0 2px 12px rgba(0,0,0,.6); }
.rtc-head-st { margin-top: 4px; font-size: 12px; opacity: .78; text-shadow: 0 2px 12px rgba(0,0,0,.6); }
.rtc-layer.video .rtc-timer { top: 66px; }
.rtc-timer.low { color: #ffb3c0; }

.rtc-mini { position: absolute; left: 14px; top: 22px; z-index: 4; height: 30px; padding: 0 12px;
  border-radius: 16px; border: 0; background: rgba(255,255,255,.16); color: #fff; font-size: 12px; }

/* 最小化：缩成右上角浮窗，通话不中断 */
.rtc-layer.min { inset: 76px 12px auto auto; width: 132px; height: 176px; border-radius: 18px;
  background: radial-gradient(circle at 50% 26%, #3a3550 0%, #1d1a29 70%); box-shadow: 0 10px 28px rgba(0,0,0,.4); }
.rtc-layer.min .rtc-bg { gap: 6px; padding: 0 10px; }
.rtc-layer.min .rtc-av { width: 54px; height: 54px; border-radius: 16px; font-size: 20px; }
.rtc-layer.min .rtc-nm { font-size: 13px; }
.rtc-layer.min .rtc-st, .rtc-layer.min .rtc-wave, .rtc-layer.min .rtc-timer { display: none; }
.rtc-layer.min .rtc-bar { position: absolute; bottom: 12px; gap: 14px; }
.rtc-layer.min .rtc-act { width: 44px; height: 44px; font-size: 10px; }
.rtc-layer.min .rtc-act:not(#rtc-end) { display: none; }
.rtc-layer.min .rtc-mini { left: auto; right: 10px; top: 8px; height: 24px; padding: 0 9px; font-size: 11px; }
.rtc-layer.min .rtc-remote, .rtc-layer.min .rtc-local { display: none; }

@media (max-height: 620px) {
  .rtc-av { width: 78px; height: 78px; }
  .rtc-bar { bottom: 26px; }
}

/* 计费提示（第 146 章）：免费额度用完后按分钟扣费，面板上先把标准说清楚 */
.rtc-fee { margin-top: 6px; font-size: 12px; letter-spacing: .3px; opacity: .62; font-variant-numeric: tabular-nums; }
.rtc-layer.video .rtc-fee { position: absolute; left: 50%; top: 52px; transform: translateX(-50%);
  padding: 3px 10px; border-radius: 14px; background: rgba(0,0,0,.42); z-index: 3; opacity: .8; }
/* 进入计费后计时器换成暖色，提醒正在扣余额 */
.rtc-timer.bill { color: #ffd28a; opacity: 1; }
