/* ===========================================================================
 * kefu.css —— 自绘智能客服聊天窗（2026-10-23 第二版：全自绘）
 * ---------------------------------------------------------------------------
 * 第一版是「列表 → 对话(iframe) → 留言(form)」三级跳，问题有两个：
 *   ① 点客服后整屏变成三方的 H5（它自己的头、推荐问题、输入区全冒出来）；
 *   ② 留言表单是个死胡同，提交完还得等人工，访客体验断裂。
 * 现在合成一个视图：客服介绍 ＋ 聊天记录 ＋ 人工服务按钮 ＋ 输入框 ＋ 发送键。
 *
 * ★消息收发是自己实现的（WS + HTTP，见 assets/js/embed.js 顶部说明），
 *   不再有 iframe，所以「界面全是我们的」这句话这次是真的。
 *
 * ★类名统一 kf- 前缀；不许出现 body / html 级选择器（全站共用这张表）。
 * =========================================================================== */

/* ---------- 模态遮罩（2026-10-26 傍晚）----------
   用户要求：点开客服后「不关闭聊天窗口，其他点不了」。
   层级必须严格是 遮罩 9997 < 悬浮球 9998 < 窗口 9999：
     遮罩压到球上 → 球（打开时就是关闭键）点不动；
     遮罩压到窗口上 → 整块聊天区没反应（表现是「窗口显示着却打不了字」）。
   ★遮罩本身**不绑**点击关闭：误触会连正在输入的内容一起丢掉。
   ★用 top/right/bottom/left 而不用 inset：微信内置浏览器版本参差大，
     inset 在 iOS 14.1 之前不认，而这一条失效就是——遮罩没了。 */
.kf-mask{
  position:fixed; top:0; right:0; bottom:0; left:0; z-index:9997;
  background:rgba(9,22,38,.42);
  opacity:0; visibility:hidden;
  transition:opacity .2s ease, visibility .2s;
  -webkit-tap-highlight-color:transparent;
}
.kf-mask.is-open{opacity:1; visibility:visible}

/* ---------- 悬浮球 ---------- */
.kf-ball{
  position:fixed; right:24px; bottom:24px; width:56px; height:56px; border:0; padding:0;
  border-radius:50%; background:linear-gradient(145deg,var(--navy-600,#123A63),var(--navy-800,#0B2A4A));
  box-shadow:0 10px 26px rgba(11,42,74,.32); cursor:pointer; z-index:9998;
  display:flex; align-items:center; justify-content:center;
  transition:transform .18s ease, box-shadow .18s ease;
}
.kf-ball:hover{transform:translateY(-2px); box-shadow:0 14px 32px rgba(11,42,74,.4)}
.kf-ball:focus-visible{outline:3px solid #D8B24A; outline-offset:2px}
.kf-ball svg{width:26px; height:26px; stroke:#fff; fill:none; stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round}
.kf-ball .kf-dot{position:absolute; top:7px; right:7px; width:9px; height:9px; border-radius:50%;
  background:#D8B24A; border:2px solid #fff; box-sizing:content-box}
.kf-ball.is-open .kf-ico-chat, .kf-ball:not(.is-open) .kf-ico-close{display:none}

/* ---------- 窗口 ---------- */
.kf-panel{
  position:fixed; right:24px; bottom:96px;
  /* ★2026-10-26 傍晚：尺寸由写死改为随视口伸缩（原来 376×572）。
     用户要求「适配网页尺寸」：
       · 1280×600 / 1366×768 这类小笔记本不再被压扁（原来高度写死 572，
         视口只剩 600 时顶部会顶到屏幕外）；
       · 1920 以上也不至于只剩右下角一小块（宽上限 440）。
     宽 30vw：1280→384、1440→432、1800→440（上限）；
     高 clamp(420, 100vh-132, 720)：保证最少 420 有一屏消息，
     小视口靠 max-height 再压一道，不会溢出屏幕。 */
  width:clamp(376px, 30vw, 440px);
  height:clamp(420px, calc(100vh - 132px), 720px);
  max-height:calc(100vh - 132px);
  background:#F5F8FB; border-radius:16px;
  box-shadow:0 18px 48px rgba(9,28,52,.22), 0 2px 8px rgba(9,28,52,.08);
  z-index:9999; display:flex; flex-direction:column; overflow:hidden;
  opacity:0; visibility:hidden; transform:translateY(12px) scale(.985); transform-origin:100% 100%;
  transition:opacity .2s ease, transform .2s ease, visibility .2s;
}
.kf-panel.is-open{opacity:1; visibility:visible; transform:none}

/* ---------- 头部：客服介绍 ---------- */
.kf-head{
  background:linear-gradient(135deg,#0B2A4A 0%,#1B4C7C 100%);
  color:#fff; padding:14px 15px 13px; display:flex; align-items:center; gap:11px;
  flex:0 0 auto; border-bottom:2px solid #B8912F;
}
.kf-ava{width:42px; height:42px; border-radius:50%; object-fit:cover; flex:0 0 auto;
  background:#DCE8F4; border:1.5px solid rgba(255,255,255,.55)}
.kf-head-txt{min-width:0; flex:1 1 auto}
.kf-title{font-size:15.5px; font-weight:700; letter-spacing:.01em; line-height:1.3;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.kf-sub{font-size:12px; color:#B9CEE2; margin-top:3px; line-height:1.3;
  display:flex; align-items:center; gap:5px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
.kf-live{width:6px; height:6px; border-radius:50%; background:#5BD38A; flex:0 0 auto;
  box-shadow:0 0 0 2px rgba(91,211,138,.24)}
.kf-live.is-off{background:#8FA3B6; box-shadow:0 0 0 2px rgba(143,163,182,.22)}
.kf-close{border:0; background:transparent; color:#CFE0EE; font-size:23px; line-height:1;
  cursor:pointer; padding:2px 4px; flex:0 0 auto; border-radius:6px}
.kf-close:hover{color:#fff; background:rgba(255,255,255,.12)}
.kf-close:focus-visible{outline:2px solid #D8B24A; outline-offset:1px}

/* ---------- 消息区 ---------- */
.kf-log{
  flex:1 1 auto; overflow-y:auto; overflow-x:hidden; padding:16px 14px 8px;
  display:flex; flex-direction:column; gap:12px; min-height:0;
  scroll-behavior:smooth; overscroll-behavior:contain;
}
.kf-log::-webkit-scrollbar{width:6px}
.kf-log::-webkit-scrollbar-thumb{background:#CBD8E4; border-radius:3px}

/* 气泡行 */
.kf-row{display:flex; align-items:flex-end; gap:8px; max-width:100%}
.kf-row.kf-in{justify-content:flex-start}
.kf-row.kf-out{justify-content:flex-end}
/* 不再给每条消息挂头像：头部已经有完整的客服介绍（头像＋姓名＋职位＋在线状态），
   28px 的小头像上那个横版 LOGO 只会糊成一团，信息没有增加，视觉反而更碎。 */

.kf-bub{
  max-width:84%; padding:10px 13px; border-radius:13px;
  font-size:14px; line-height:1.66; white-space:pre-wrap; word-break:break-word;
  overflow-wrap:anywhere;
}
.kf-row.kf-in .kf-bub{background:#fff; color:#16202C; border:1px solid #E4EBF2;
  border-bottom-left-radius:5px; box-shadow:0 1px 2px rgba(11,42,74,.04)}
.kf-row.kf-out .kf-bub{background:linear-gradient(140deg,#1B4C7C,#0B2A4A); color:#fff;
  border-bottom-right-radius:5px}

/* AI 回复气泡尾部的免责声明（2026-10-26）。
   ★它原来是窗口底部那行灰字；那条改成营业时间与电话后，这里必须接住
     「不构成诊疗建议」这句话，否则 AI 答错内容时没有免责留痕。
   ★为什么不做回 footer：footer 只有一行，营业时间和免责声明抢同一行会两败俱伤。
   ★为什么在气泡**外面**：塞进气泡时只有 264px 内容宽，26 字必折两行、占掉气泡
     高度的 29%，正文一短小字反倒比正文抢眼。放外面这一行是独立 flex item，
     能用满 352px，单行 286px 就够 —— 而且正文的折行完全不受影响。
   ★字号 11px 是下限 —— 再小在高分屏上会糊成一片灰。
   ★padding-left 与气泡内文字左沿对齐（气泡 1px 边框 + 13px 内边距 = 14px），
     不加分隔线：气泡有自己的边框，再拉一条横贯整行的线反而割裂。 */
.kf-row.kf-in.has-note{flex-wrap:wrap}
.kf-bub-note{
  flex:1 1 100%; min-width:0;
  margin-top:-4px; padding-left:14px;
  font-size:11px; line-height:1.5; color:#96A5B4; letter-spacing:0;
  font-weight:400; white-space:normal;
  /* 极窄屏下仍可能折行，那时让两行长度接近，避免末行只剩一两个字 */
  text-wrap:balance;
}

/* ---------- 图片气泡 ----------
   图片消息走 type=image（type_id 2），收发两端都按图片渲染，不再折成「[图片]」两个字。
   ★min-width/min-height：访客可能发一张 1×1 的图（或者服务端给的缩略图失败），
     没有下限的话气泡会缩成一个小点，看起来像发了一条空白消息。 */
.kf-photo{
  position:relative; max-width:72%; line-height:0; cursor:zoom-in;
  border-radius:12px; overflow:hidden; background:#fff; border:1px solid #E4EBF2;
  box-shadow:0 1px 2px rgba(11,42,74,.06);
}
.kf-row.kf-out .kf-photo{border-color:rgba(27,76,124,.28); border-bottom-right-radius:5px}
.kf-row.kf-in .kf-photo{border-bottom-left-radius:5px}
.kf-photo img{display:block; max-width:100%; max-height:220px; width:auto; height:auto;
  min-width:56px; min-height:44px; object-fit:cover}
.kf-photo.is-loading{cursor:default}
.kf-photo.is-loading img{filter:saturate(.85) brightness(.96)}
.kf-photo-mask{
  position:absolute; top:0; right:0; bottom:0; left:0;
  display:flex; align-items:center; justify-content:center;
  gap:6px; background:rgba(11,42,74,.42); color:#fff;
  font-size:12px; font-weight:600; line-height:1; letter-spacing:.02em;
}
.kf-photo.is-err .kf-photo-mask{background:rgba(160,43,34,.68)}
.kf-photo.is-err{cursor:pointer}
.kf-spin{width:12px; height:12px; border-radius:50%; display:block;
  border:2px solid rgba(255,255,255,.42); border-top-color:#fff;
  animation:kfspin .75s linear infinite}
@keyframes kfspin{to{transform:rotate(360deg)}}

/* 系统提示（转人工、加载失败等）：居中细条，不是气泡 */
.kf-sys{align-self:center; max-width:88%; text-align:center; font-size:12.2px;
  color:#6B7A89; background:rgba(11,42,74,.055); border-radius:8px; padding:6px 12px;
  line-height:1.55}
.kf-sys.is-err{color:#A02B22; background:#FDEDEC}
.kf-time{align-self:center; font-size:11.4px; color:#9AA9B8; margin:2px 0 -2px}

/* 「正在输入」三点 */
.kf-typing{align-self:flex-start; display:flex; align-items:center; gap:4px;
  padding:11px 14px; background:#fff; border:1px solid #E4EBF2; border-radius:13px;
  border-bottom-left-radius:5px}
.kf-typing i{width:6px; height:6px; border-radius:50%; background:#A9BCCD; display:block;
  animation:kfdot 1.15s infinite ease-in-out}
.kf-typing i:nth-child(2){animation-delay:.16s}
.kf-typing i:nth-child(3){animation-delay:.32s}
@keyframes kfdot{0%,60%,100%{opacity:.32; transform:translateY(0)} 30%{opacity:1; transform:translateY(-3px)}}

/* 首屏骨架 */
.kf-skel{padding:6px 0; display:flex; flex-direction:column; gap:12px}
.kf-skel i{display:block; height:46px; width:66%; border-radius:13px;
  background:linear-gradient(90deg,#E8EFF6 25%,#F4F8FC 37%,#E8EFF6 63%);
  background-size:400% 100%; animation:kfsh 1.3s ease infinite}
.kf-skel i:nth-child(2){align-self:flex-end; width:52%}
.kf-skel i:nth-child(3){width:58%}
@keyframes kfsh{0%{background-position:100% 50%} 100%{background-position:0 50%}}

/* ---------- 工具行：图片 ＋ 人工服务 ----------
   图片按钮放在人工服务**前面**（2026-10-23 用户要求）。
   ★为什么是图标按钮而不是「图片」两个字：这一行还要放「人工服务」和右侧状态文字，
     376px 宽的窗口里三个中文词并排会挤到换行。图标 15px ＋ 28px 方形热区足够点。 */
.kf-tools{flex:0 0 auto; display:flex; align-items:center; gap:7px;
  padding:9px 14px 0; background:#fff; border-top:1px solid #E4EBF2}
.kf-img{
  flex:0 0 auto; display:inline-flex; align-items:center; justify-content:center;
  width:30px; height:28px; padding:0;
  border:1px solid #D3DFEA; border-radius:14px; background:#fff; color:#1B4C7C;
  cursor:pointer; transition:background .15s, border-color .15s, color .15s;
}
.kf-img svg{width:15px; height:15px; stroke:currentColor; fill:none; stroke-width:1.8;
  stroke-linecap:round; stroke-linejoin:round}
.kf-img:hover:not(:disabled){border-color:#A8C2D8; background:#F4F8FC}
.kf-img:focus-visible{outline:2px solid #9FC0DC; outline-offset:1px}
.kf-img:disabled{opacity:.45; cursor:not-allowed}
.kf-human{
  display:inline-flex; align-items:center; gap:6px; height:28px; padding:0 12px;
  border:1px solid #D3DFEA; border-radius:14px; background:#fff; color:#1B4C7C;
  font:inherit; font-size:12.4px; font-weight:600; cursor:pointer;
  transition:background .15s, border-color .15s, color .15s;
}
.kf-human svg{width:13px; height:13px; stroke:currentColor; fill:none; stroke-width:1.9;
  stroke-linecap:round; stroke-linejoin:round}
.kf-human:hover{border-color:#A8C2D8; background:#F4F8FC}
.kf-human[aria-pressed="true"]{background:#0B2A4A; border-color:#0B2A4A; color:#fff}
.kf-human:disabled{opacity:.5; cursor:not-allowed}
.kf-hint{margin-left:auto; font-size:11.4px; color:#93A2B1}

/* ---------- 输入区 ----------
   ★高度必须对齐：输入框外框（含 1px 边框）与发送键同为 44px。
     第一版把它们分别写成 42 / 40，底边对齐后顶边差 2px，
     截图里看就是「输入框比发送键高出一截」，很难看。 */
.kf-bar{flex:0 0 auto; display:flex; align-items:flex-end; gap:9px;
  padding:9px 14px 10px; background:#fff}
.kf-inputwrap{flex:1 1 auto; min-width:0; display:flex; align-items:center;
  background:#F3F7FB; border:1px solid #E1E9F1; border-radius:11px;
  padding:0 4px 0 12px; transition:border-color .15s, box-shadow .15s, background .15s}
.kf-inputwrap.is-focus{background:#fff; border-color:#9FC0DC;
  box-shadow:0 0 0 3px rgba(20,112,172,.09)}
.kf-input{
  flex:1 1 auto; min-width:0; border:0; outline:0; background:transparent; resize:none;
  font:inherit; font-size:14px; line-height:22px; color:#16202C;
  /* border-box：height 含 padding，autosize 直接用 scrollHeight 就对得上 */
  box-sizing:border-box; height:42px; padding:10px 0; max-height:88px;
  overflow-y:auto; scrollbar-width:thin;
}
.kf-input::placeholder{color:#9AA9B8}
.kf-send{
  flex:0 0 auto; height:44px; min-width:62px; padding:0 15px; margin-right:2px;
  border:0; border-radius:9px; background:#0B2A4A; color:#fff;
  font:inherit; font-size:13.6px; font-weight:600; cursor:pointer;
  transition:background .15s, opacity .15s;
}
.kf-send:hover:not(:disabled){background:#15406B}
.kf-send:disabled{background:#C3D0DC; cursor:not-allowed}
.kf-send:focus-visible{outline:3px solid #D8B24A; outline-offset:1px}

/* 底部声明：这是「不做线上问诊」的界线，视觉上要轻但不能没有 */
.kf-foot{flex:0 0 auto; padding:0 14px 9px; background:#fff; font-size:11px;
  color:#A2AFBB; line-height:1.5; text-align:center}

/* ★.kf-skel 自带 display:flex，会压过 UA 的 [hidden] ——
   不加这条就会出现「数据回来了、骨架还挂着」，且完全不报错。 */
.kf-panel [hidden]{display:none !important}

/* ---------- 移动端 ---------- */
@media (max-width:520px){
  /* ★2026-10-26 傍晚：手机端窗口由「78vh、最高 600」改为**几乎占满**。
     原来 390×844 的机上窗口只到 76% 高，下面留 84 加上上面一大截空白，
     既不像模态、也浪费可见区（对话框越高，能看到的历史越多）。
     上留 8px、下留 84px（悬浮球与关闭键所在），高度 = 100dvh - 92。
     ★dvh 优先、vh 兜底：地址栏收起/展开时 dvh 跟着变，
       不会把底部输入框顶到屏幕外；不认 dvh 的旧版本退回 vh。 */
  .kf-panel{right:8px; left:8px; bottom:84px; width:auto;
    height:calc(100vh - 92px);
    height:calc(100dvh - 92px);
    max-height:none; border-radius:14px}
  .kf-ball{right:16px; bottom:16px; width:52px; height:52px}
  .kf-log{padding:13px 12px 6px}
  .kf-bar{padding:8px 12px 9px; gap:8px}
  .kf-foot{padding:0 12px 8px}
  .kf-bub{font-size:14.2px}
}
/* 打印时三件套一起藏：只藏窗口不藏遮罩，PDF 会整页变成一层灰。 */
@media print{ .kf-ball,.kf-panel,.kf-mask{display:none !important} }

/* 尊重系统的「减少动效」偏好 */
@media (prefers-reduced-motion:reduce){
  .kf-panel,.kf-ball,.kf-mask,.kf-human,.kf-send{transition:none}
  .kf-log{scroll-behavior:auto}
  .kf-typing i,.kf-skel i{animation:none}
}
