:root {
  --green: #18b27e;
  --green-d: #0e8f63;
  --bg: #eef3f4;
  --panel: #ffffff;
  --ink: #1f2a37;
  --ink-soft: #5b6b7b;
  --line: #e6edf0;
  --bubble-user: #18b27e;
  --bubble-ai: #f1f5f7;
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif;
  background: linear-gradient(180deg, #e8f3ef 0%, #eef3f4 38%, #eef3f4 100%);
  color: var(--ink);
}

/* 顶部栏 */
.topbar {
  height: 60px;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 26px;
  background: rgba(255,255,255,.82);
  backdrop-filter: saturate(160%) blur(8px);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 10;
}
.brand { display: flex; align-items: baseline; gap: 10px; }
.brand .logo {
  font-weight: 800; font-size: 20px; letter-spacing: .5px;
  background: linear-gradient(90deg, var(--green), #34c79a);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.brand .divider { color: #b9c6cd; }
.brand .subtitle { color: var(--ink-soft); font-size: 14px; }
.brand .subtitle em { font-style: normal; color: var(--green-d); font-weight: 700; }
.status { font-size: 13px; color: var(--ink-soft); }

/* 布局
   高度锁死在视口内，页面整体永不滚动，两栏各自内部滚。
   否则左栏内容约 930px，加顶栏和外边距共 1034px，在 900 屏的笔记本上溢出 234px，
   一滚数字人和问诊摘要就整个被刷走——评审会上看到的就是这个。
   注：这里不能用 position:sticky。左栏是 grid item，容器就是它自己的 grid area，
   而行高恰恰由左栏内容撑起，item 高度 == 容器高度，没有可滑动的余量，sticky 是死的。 */
.layout {
  max-width: 1180px; margin: 22px auto; padding: 0 18px;
  display: grid; grid-template-columns: 420px 1fr; gap: 18px;
  align-items: stretch;
  height: calc(100vh - 104px);   /* 60 顶栏 + 22×2 外边距 */
  transition: margin .26s cubic-bezier(.4,0,.2,1), grid-template-columns .26s cubic-bezier(.4,0,.2,1);
}
/* 侧栏弹出时主区让位而不是被盖住：整体右边界让出 380px，左栏人像同时收窄。
   宽度不够时（<1100px）没有让位的余地，退回覆盖式。 */
@media (min-width: 1100px) {
  body.tp-open .layout {
    margin-left: auto; margin-right: 396px;
    grid-template-columns: 340px 1fr;
  }
}
@media (max-width: 880px) {
  /* 单列时两栏上下堆叠，塞不进一个视口高度，退回自然流让页面正常滚。
     本 demo 定位是大屏演示，窄屏只求不崩，不做适配。 */
  .layout { grid-template-columns: 1fr; height: auto; }
  .avatar-panel { overflow-y: visible; }
  .chat-panel { min-height: 560px; }
}

/* 左：数字人 */
.avatar-panel {
  background: var(--panel); border: 1px solid var(--line); border-radius: 18px;
  padding: 18px; box-shadow: 0 8px 26px rgba(20,60,50,.06);
  display: flex; flex-direction: column;
  /* 视口不够高时（笔记本）左栏自己滚，而不是把整页顶出滚动条 */
  overflow-y: auto; overscroll-behavior: contain;
}
.avatar-stage {
  position: relative; border-radius: 14px; overflow: hidden;
  background: radial-gradient(120% 90% at 50% 0%, #dff3ec 0%, #eaf4f1 55%, #f4f8f7 100%);
  aspect-ratio: 3 / 4; display: flex; align-items: flex-end; justify-content: center;
  /* 左栏定高后，flex 默认会压缩子项来凑高度：实测 640 高的视口里立绘框被压成
     382×307，宽高比从 0.75 变 1.24，医生的脸直接变形。立绘不参与压缩，
     空间不够就让左栏自己滚（上面的 overflow-y:auto）。 */
  flex-shrink: 0;
}
.avatar-glow {
  position: absolute; inset: -20% 10% auto 10%; height: 60%;
  background: radial-gradient(60% 60% at 50% 40%, rgba(52,199,154,.28), transparent 70%);
  filter: blur(8px); pointer-events: none;
}
/* 微动头容器：缓慢呼吸 + 极轻的左右/俯仰摆动，制造"活着"的临场感（不夸张） */
.avatar-sway {
  position: absolute; inset: 0; transform-origin: 50% 78%;
  animation: sway 9s ease-in-out infinite, breathe 5.4s ease-in-out infinite;
  will-change: transform;
}
.avatar-sway.speaking { animation: sway 7s ease-in-out infinite, breathe-talk 3.1s ease-in-out infinite; }

/* 两层叠图做交叉淡入（cross-fade），消除硬切换、让口型"流动"过渡 */
.avatar-img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; object-position: center top;
  display: block;
  opacity: 1; transition: opacity 130ms ease-in-out;
  backface-visibility: hidden;
}
.avatar-img.layer-top { opacity: 0; }

@keyframes sway {
  0%   { transform: translateX(0)    rotate(0deg)    translateY(0); }
  25%  { transform: translateX(2px)  rotate(0.35deg) translateY(-1px); }
  50%  { transform: translateX(0)    rotate(0deg)    translateY(0.5px); }
  75%  { transform: translateX(-2px) rotate(-0.35deg) translateY(-1px); }
  100% { transform: translateX(0)    rotate(0deg)    translateY(0); }
}
@keyframes breathe {
  0%, 100% { scale: 1.000; }
  50%      { scale: 1.010; }
}
@keyframes breathe-talk {
  0%, 100% { scale: 1.004; }
  50%      { scale: 1.016; }
}

.speaking-badge {
  position: absolute; top: 12px; left: 12px;
  background: rgba(24,178,126,.92); color: #fff; font-size: 12px;
  padding: 5px 10px; border-radius: 999px; opacity: 0; transform: translateY(-6px);
  transition: .25s; display: flex; align-items: center; gap: 6px;
}
.speaking-badge::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; background: #fff;
  animation: pulse 1s infinite;
}
.speaking-badge.show { opacity: 1; transform: translateY(0); }
@keyframes pulse { 0%,100%{opacity:.35} 50%{opacity:1} }

/* 医生信息叠在立绘底部，不再单独占一块。左栏是定高的，省下的 ~90px 归了问诊摘要。
   遮罩用渐变而不是实色：立绘下半身是白大褂，纯白底上压白字会糊。 */
.doctor-meta {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 3;
  padding: 26px 14px 12px;
  background: linear-gradient(180deg, transparent, rgba(11, 38, 30, .66));
  pointer-events: none;   /* 别挡住立绘（虽然现在也没有交互）*/
}
.doctor-name { font-size: 19px; font-weight: 700; color: #fff; letter-spacing: .5px; }
.doctor-title { font-size: 12px; color: rgba(255, 255, 255, .85); margin-top: 2px; }

/* ---------- 开始卡（问诊入口：先确认患者信息） ---------- */
.start-card {
  align-self: center; width: 100%; max-width: 460px;
  background: #fff; border: 1px solid #cfe1da; border-radius: 16px;
  padding: 18px 20px; margin: 8px 0;
  box-shadow: 0 3px 14px rgba(21,60,48,.07);
  animation: chips-in .3s ease both;
}
.sc-title { font-size: 15.5px; font-weight: 800; color: var(--ink); }
.sc-sub { font-size: 12.5px; color: var(--ink-soft); margin: 4px 0 14px; }
.sc-row { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.sc-row:last-child { margin-bottom: 0; }
.sc-label { flex: 0 0 32px; font-size: 13px; color: var(--ink-soft); }
.sc-chips { display: flex; gap: 7px; flex-wrap: wrap; }
.sc-chips .chip { padding: 6px 12px; font-size: 13px; }
.sc-chips .chip.active { background: var(--green); color: #fff; border-color: var(--green); }
/* 完成后收成一行，留痕给用户看系统记住了什么 */
.start-card.done { padding: 11px 16px; max-width: 340px; }
.sc-done { display: flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--ink); }
.sc-done-ico {
  flex: 0 0 17px; height: 17px; border-radius: 50%; background: var(--green); color: #fff;
  font-size: 11px; display: grid; place-items: center;
}
.sc-redo {
  margin-left: auto; border: none; background: transparent; color: var(--green-d);
  font-size: 12.5px; font-family: inherit; cursor: pointer; padding: 2px 4px; border-radius: 5px;
}
.sc-redo:hover { background: #e8f6ef; }
.composer textarea:disabled { background: #f6f8f8; cursor: not-allowed; }

/* ---------- 结果卡（问诊终点） ---------- */
.dx-card {
  align-self: flex-start; max-width: 92%; margin-left: 40px;
  background: #fff; border: 1px solid #cfe1da; border-radius: 16px;
  padding: 16px 18px 14px; animation: chips-in .3s ease both;
  box-shadow: 0 3px 14px rgba(21,60,48,.07);
}
.dx-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.dx-title { font-size: 16px; font-weight: 800; color: var(--ink); }
.dx-sub { font-size: 12px; color: var(--ink-soft); }
.dx-disp {
  display: inline-block; font-size: 14px; font-weight: 700;
  padding: 8px 14px; border-radius: 10px; margin-bottom: 14px;
}
.dx-disp.low { background: #e8f6ef; color: #1c7a55; }
.dx-disp.mid { background: #fff4e0; color: #a8630c; }
.dx-disp.high { background: #ffe9e6; color: #c0331f; }
.dx-sec {
  font-size: 12px; font-weight: 700; color: var(--ink-soft);
  letter-spacing: .04em; margin: 12px 0 7px;
}
.dx-sec:first-of-type { margin-top: 0; }
.dx-dir {
  border: 1px solid var(--line); border-radius: 11px;
  padding: 10px 12px; margin-bottom: 7px; background: #fafcfb;
}
.dx-dir-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dx-rank {
  flex: 0 0 18px; height: 18px; border-radius: 50%; background: var(--green); color: #fff;
  font-size: 11px; font-weight: 700; display: grid; place-items: center;
}
.dx-name { font-size: 14.5px; font-weight: 700; color: var(--ink); }
.dx-match { font-size: 11px; font-weight: 700; padding: 2px 7px; border-radius: 5px; }
.dx-match.m-hi { background: rgba(28,153,113,.14); color: var(--green-d); }
.dx-match.m-mid { background: #eef2f1; color: var(--ink-soft); }
.dx-match.m-rule { background: #ffe9e6; color: #c0331f; }
.dx-basis { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; }
.dx-b {
  background: #fff; border: 1px solid var(--line); border-radius: 6px;
  padding: 3px 8px; font-size: 12px; color: var(--ink-soft);
}
.dx-src { margin-top: 7px; font-size: 11.5px; color: var(--green-d); }
.dx-ul { margin: 0; padding-left: 18px; }
.dx-ul li { font-size: 13.5px; color: var(--ink); line-height: 1.8; }
.dx-ul.dx-ask li { color: var(--ink-soft); }
/* 下一步：挂号 / 购药入口 */
.dx-next { display: flex; gap: 8px; }
.dx-next-btn {
  flex: 1; display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  border: 1px solid var(--line); background: #fafcfb; border-radius: 11px;
  padding: 10px 12px; cursor: pointer; font-family: inherit; text-align: left;
  transition: border-color .15s, background .15s;
}
.dx-next-btn:hover { border-color: var(--green); background: #f2faf7; }
.dx-next-ico { font-size: 17px; line-height: 1.2; }
.dx-next-t { font-size: 13.5px; font-weight: 700; color: var(--ink); }
.dx-next-s { font-size: 11.5px; color: var(--ink-soft); }
.dx-slot:not(:empty) { margin-top: 8px; }

/* Mock 面板（挂号 / 药房） */
.mk-card {
  border: 1px solid #cfe1da; border-radius: 11px; padding: 12px; background: #fff;
  animation: chips-in .2s ease both;
}
.mk-head { display: flex; align-items: center; gap: 7px; margin-bottom: 9px; }
.mk-title { font-size: 13px; font-weight: 700; color: var(--ink); }
.mk-mock {
  font-size: 10.5px; font-weight: 600; color: #a8630c; background: #fff4e0;
  padding: 1px 6px; border-radius: 4px;
}
.mk-row {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 0; border-bottom: 1px solid var(--line);
}
.mk-row:last-of-type { border-bottom: none; }
.mk-main { flex: 1; min-width: 0; }
.mk-name { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.mk-meta { font-size: 11.5px; color: var(--ink-soft); margin-top: 2px; }
.mk-slot { font-size: 12.5px; font-weight: 700; padding: 4px 9px; border-radius: 6px; white-space: nowrap; }
.mk-slot.high { background: #ffe9e6; color: #c0331f; }
.mk-slot.mid { background: #fff4e0; color: #a8630c; }
.mk-slot.low { background: #e8f6ef; color: #1c7a55; }
.mk-check {
  display: flex; align-items: flex-start; gap: 7px; margin: 10px 0;
  font-size: 12px; color: var(--ink-soft); line-height: 1.5; cursor: pointer;
}
.mk-check input { margin-top: 2px; accent-color: var(--green); }
.mk-btn {
  width: 100%; border: none; background: var(--green); color: #fff;
  border-radius: 9px; padding: 9px; font-size: 13.5px; font-weight: 700;
  font-family: inherit; cursor: pointer; transition: background .15s;
}
.mk-btn:hover { background: var(--green-d); }
.mk-card.ok { background: #f2faf7; }
.mk-ok-t { font-size: 14px; font-weight: 700; color: var(--green-d); }
.mk-ok-s { font-size: 12.5px; color: var(--ink-soft); line-height: 1.6; margin-top: 4px; }
.mk-note { font-size: 11.5px; color: var(--ink-soft); line-height: 1.6; margin-top: 9px; }
.mk-mock-foot { font-size: 11px; color: #9fb0ba; margin-top: 7px; }

.dx-foot {
  margin-top: 14px; padding-top: 11px; border-top: 1px dashed var(--line);
  font-size: 11.5px; color: #9fb0ba; line-height: 1.6;
}
.dx-acts { display: flex; gap: 8px; margin-top: 11px; }
.dx-btn {
  flex: 1; border: 1px solid var(--green); background: #fff; color: var(--green-d);
  border-radius: 9px; padding: 8px; font-size: 13px; font-weight: 600;
  font-family: inherit; cursor: pointer; transition: background .15s, color .15s;
}
.dx-btn:hover { background: var(--green); color: #fff; }
@media print {
  .avatar-panel, .composer, .option-bar, .topbar, .chat-head, .disclaimer, .term-panel { display: none !important; }
  .dx-acts { display: none !important; }
  .dx-card { max-width: 100%; margin: 0; box-shadow: none; }
}

/* ---------- 正文里的可点击医学术语 ---------- */
a.term {
  color: #2f6fe4; text-decoration: none; cursor: pointer;
  border-bottom: 1px solid rgba(47,111,228,.3);
  padding-bottom: 1px; transition: background .15s, border-color .15s;
}
a.term:hover { background: rgba(47,111,228,.09); border-bottom-color: #2f6fe4; }
a.term svg {
  width: 10px; height: 10px; margin-left: 2px; vertical-align: 3px;
  fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round;
}

/* ---------- 术语侧栏 ---------- */
.term-panel {
  position: fixed; top: 0; right: 0; bottom: 0; width: 380px; max-width: 88vw;
  background: #fff; border-left: 1px solid var(--line);
  box-shadow: -8px 0 28px rgba(21,60,48,.1);
  display: flex; flex-direction: column; z-index: 40;
  transform: translateX(100%); transition: transform .24s cubic-bezier(.4,0,.2,1);
}
.term-panel.open { transform: none; }
.tp-head {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 18px; border-bottom: 1px solid var(--line); flex: 0 0 auto;
}
.tp-title { flex: 1; font-size: 17px; font-weight: 700; color: var(--ink); }
.tp-close {
  border: none; background: transparent; color: var(--ink-soft);
  font-size: 24px; line-height: 1; cursor: pointer; padding: 0 4px; border-radius: 6px;
}
.tp-close:hover { background: #eef4f2; color: var(--ink); }
.tp-body { flex: 1; overflow-y: auto; padding: 16px 18px 22px; }
.tp-loading { color: var(--ink-soft); font-size: 13px; }
.tp-short {
  color: var(--ink); font-size: 14.5px; font-weight: 600; line-height: 1.65;
  padding-left: 9px; border-left: 3px solid var(--green); margin-bottom: 12px;
}
.tp-detail { color: var(--ink-soft); font-size: 13.5px; line-height: 1.85; margin-bottom: 16px; }
.tp-sec {
  font-size: 12px; font-weight: 700; color: var(--ink-soft);
  letter-spacing: .04em; margin-bottom: 7px;
}
.tp-ask { margin-top: 16px; }
.tp-btn {
  width: 100%; border: 1px solid var(--green); background: #fff; color: var(--green-d);
  border-radius: 10px; padding: 10px; font-size: 13.5px; font-weight: 600;
  font-family: inherit; cursor: pointer; transition: background .15s, color .15s;
}
.tp-btn:hover:not(:disabled) { background: var(--green); color: #fff; }
.tp-btn:disabled { opacity: .55; cursor: default; }
.tp-answer:not(:empty) {
  margin-top: 12px; background: #f6f9f8; border: 1px solid var(--line);
  border-radius: 10px; padding: 11px 13px;
  color: var(--ink); font-size: 13.5px; line-height: 1.8;
}
.tp-answer .md-p { margin: 0 0 5px; }
.tp-answer .md-p:last-child { margin-bottom: 0; }

/* ---------- 智能思考过程卡 ---------- */
.proc-msg { max-width: 92%; }
.proc-col { display: flex; flex-direction: column; gap: 8px; min-width: 0; flex: 1; }
.proc-head { font-size: 13.5px; color: var(--ink-soft); font-weight: 600; padding-top: 4px; }
.proc-card {
  background: #f6f9f8; border: 1px solid var(--line); border-radius: 14px;
  padding: 12px 14px; animation: chips-in .25s ease both;
}
.proc-row {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 0; position: relative; color: #9fb0ba; font-size: 13.5px;
  transition: color .25s;
}
/* 左侧竖线把三行串起来 */
.proc-row:not(:last-of-type)::before {
  content: ""; position: absolute; left: 9px; top: 27px; bottom: -7px;
  width: 1px; background: var(--line);
}
.proc-row.done { color: var(--ink); }
.proc-row.skipped { opacity: .45; }
.proc-row.expandable { cursor: pointer; }
.proc-ico { flex: 0 0 19px; height: 19px; display: grid; place-items: center; z-index: 1; background: #f6f9f8; }
.proc-ico svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.proc-row[data-step="profile"].done .proc-ico svg { fill: rgba(28,153,113,.14); }
.proc-row.done .proc-ico { color: var(--green); }
.proc-text { flex: 1; min-width: 0; }
.proc-text b { color: var(--green-d); font-weight: 600; }
.pd-note { color: var(--ink-soft); font-weight: 400; }
.proc-spin {
  flex: 0 0 12px; height: 12px; border-radius: 50%;
  border: 1.6px solid var(--line); border-top-color: var(--green);
  animation: proc-spin .7s linear infinite;
}
@keyframes proc-spin { to { transform: rotate(360deg); } }
.proc-chev { flex: 0 0 16px; height: 16px; color: #9fb0ba; transition: transform .2s; }
.proc-chev svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.proc-chev.up { transform: rotate(180deg); }
.proc-detail {
  display: none; padding: 2px 0 8px 28px;
}
.proc-detail.open { display: block; animation: chips-in .2s ease both; }
.pd-sub { color: var(--ink-soft); font-size: 12.5px; }
.pd-sub b { color: var(--green-d); }

/* 模型自述的思考步骤 */
.pd-steps { display: flex; flex-direction: column; gap: 5px; margin-bottom: 7px; }
.pd-step { display: flex; align-items: flex-start; gap: 8px; font-size: 12.5px; line-height: 1.6; }
.pd-step-n {
  flex: 0 0 16px; height: 16px; margin-top: 2px; border-radius: 50%;
  background: rgba(28,153,113,.12); color: var(--green-d);
  font-size: 10.5px; font-weight: 700; display: grid; place-items: center;
}
.pd-step-t { color: var(--ink); }

/* 文献类型标签 */
.pd-tag {
  display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 4px;
  background: rgba(28,153,113,.1); color: var(--green-d);
  font-size: 10.5px; font-weight: 600; vertical-align: 1px; white-space: nowrap;
}
.pd-src-n { color: var(--green-d); font-weight: 700; margin-right: 4px; }

.pd-grid { display: flex; flex-wrap: wrap; gap: 6px; }
.pd-item { display: flex; gap: 6px; background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 4px 9px; font-size: 12.5px; }
.pd-k { color: var(--ink-soft); }
.pd-v { color: var(--ink); font-weight: 600; }
.pd-src {
  display: block; background: #fff; border: 1px solid var(--line); border-radius: 10px;
  padding: 8px 11px; margin-bottom: 6px; text-decoration: none; transition: border-color .15s, transform .05s;
}
.pd-src:hover { border-color: var(--green); }
.pd-src:active { transform: translateY(1px); }
.pd-src-t { color: var(--ink); font-size: 13px; font-weight: 600; line-height: 1.4; }
.pd-src-m { color: var(--green-d); font-size: 11.5px; margin-top: 2px; }
.pd-src-g { color: var(--ink-soft); font-size: 12px; margin-top: 3px; line-height: 1.5; }

/* 快捷选项卡 + 通用 chip + 入场动画 */
@keyframes chips-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.quick-replies {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 2px 0 10px 40px; align-self: flex-start; max-width: 86%;
  animation: chips-in .25s ease both;
}

/* 选项条：贴在输入框正上方，单行横向滚动，点击即发送 */
.option-bar {
  display: flex; gap: 8px; align-items: center;
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none; -ms-overflow-style: none;
  -webkit-overflow-scrolling: touch;
}
.option-bar::-webkit-scrollbar { display: none; }
.option-bar:not(:empty) {
  padding: 12px 16px 0;
  animation: chips-in .25s ease both;
}
.option-bar .chip { flex: 0 0 auto; white-space: nowrap; }

.chip {
  border: 1px solid var(--green); color: var(--green-d); background: #fff;
  border-radius: 999px; padding: 7px 14px; font-size: 13.5px; font-family: inherit;
  cursor: pointer; transition: background .15s, color .15s, transform .05s;
}
.chip:hover { background: var(--green); color: #fff; }
.chip:active { transform: translateY(1px); }
/* 已填入输入框的选项：保持选中态，直到本轮发送 */
.chip.active { background: var(--green); color: #fff; border-color: var(--green); }

/* 部位选择图（腹部分区） */
.body-picker {
  align-self: flex-start; max-width: 86%; margin-left: 40px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  padding: 12px 14px; animation: chips-in .25s ease both;
}
.bp-title {
  font-size: 13.5px; color: var(--ink); font-weight: 700; margin-bottom: 6px;
  border-left: 3px solid var(--green); padding-left: 7px; line-height: 1.2;
}
.bp-title strong { color: var(--green-d); font-weight: 700; }
.bp-hint { color: var(--ink-soft); font-size: 12px; font-weight: 400; }
.body-svg { width: 224px; height: auto; display: block; margin: 4px auto 10px; }
.body-svg .torso { fill: #eaf4f1; stroke: #cfe1da; stroke-width: 2; }
.body-svg .rib { stroke: #cfe1da; stroke-width: 2; fill: none; }
.body-svg .navel { fill: #b3cabf; }
.body-svg .region { cursor: pointer; }
.body-svg .region rect,
.body-svg .region path,
.body-svg .region circle.hit { fill: #fff; stroke: #cfe0d9; stroke-width: 1.5; transition: fill .15s, stroke .15s; }
.body-svg .region text {
  fill: var(--ink-soft); font-size: 11.5px; font-weight: 600; font-family: inherit;
  text-anchor: middle; dominant-baseline: middle; pointer-events: none;
  transition: fill .15s;
}
.body-svg .region:hover rect,
.body-svg .region:hover path,
.body-svg .region:hover circle.hit { fill: #d3efe4; stroke: var(--green); }
.body-svg .region:hover text { fill: var(--green-d); }
/* 选中态：多选，选中的区域保持高亮直到发送 */
.body-svg .region.on rect,
.body-svg .region.on path,
.body-svg .region.on circle.hit { fill: var(--green); stroke: var(--green-d); }
.body-svg .region.on text { fill: #fff; }
.body-svg .region:focus { outline: none; }
.body-svg .region:focus rect,
.body-svg .region:focus path,
.body-svg .region:focus circle.hit { stroke: var(--green); stroke-width: 2.5; }

/* 头痛定位：正面/背面双视图，五官与后颈只作方向标志，不参与点击 */
.body-svg.head-map { width: min(470px, 100%); margin-top: 8px; }
.head-map .head-base {
  fill: #edf6f3; stroke: #c7dcd4; stroke-width: 2.2;
}
.head-map .ear {
  fill: #edf6f3; stroke: #c7dcd4; stroke-width: 2; stroke-linecap: round;
}
.head-map .landmark {
  fill: none; stroke: #91afa3; stroke-width: 1.8;
  stroke-linecap: round; pointer-events: none;
}
.head-map .hairline { stroke-width: 2.2; }
.head-map .view-label {
  fill: var(--ink); font-size: 14px; font-weight: 800; font-family: inherit;
  text-anchor: middle;
}
.head-map .orientation-note {
  fill: var(--ink-soft); font-size: 11px; font-family: inherit; text-anchor: middle;
}
.head-map .region path {
  fill: rgba(255,255,255,.76); stroke: #bdd5cc; stroke-width: 1.5;
}
.head-map .region text { font-size: 10.5px; }
.head-map .region text.small { font-size: 9.5px; }
.head-map .region:hover path { fill: #d3efe4; }
.head-map .region.on path { fill: var(--green); }
.bp-extra { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
.bp-extra .chip.on { background: var(--green); color: #fff; border-color: var(--green); }

/* 就诊卡（建档信息 + 问诊摘要） */
.intake-card {
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 16px;
}
.intake-title {
  font-size: 13px; font-weight: 800; color: var(--ink);
  display: flex; align-items: center; gap: 7px; margin-bottom: 10px;
}
.intake-title::before {
  content: ""; width: 3px; height: 13px; background: var(--green); border-radius: 2px;
}
/* 摘要不再自己封顶滚动，由 .avatar-panel 整栏滚。
   原先这里有 max-height:232px + overflow-y:auto，那是页面整体还会滚动时加的，
   为的是别把左栏撑高、把数字人顶出视口。现在 .layout 定高、左栏自己是滚动容器，
   再留一个内层滚动就成了套娃：18 行的病历摘要挤在 232px 的小盒子里，
   鼠标滚到这里还会被 overscroll-behavior:contain 吃掉，外层滚不动。 */
.summary-list {
  display: flex; flex-direction: column; gap: 6px;
  padding-right: 4px;
}
/* 滚动条样式给真正的滚动容器 */
.avatar-panel::-webkit-scrollbar { width: 5px; }
.avatar-panel::-webkit-scrollbar-track { background: transparent; }
.avatar-panel::-webkit-scrollbar-thumb { background: #d5e2dc; border-radius: 3px; }
.avatar-panel::-webkit-scrollbar-thumb:hover { background: #b8ccc3; }
.avatar-panel { scrollbar-width: thin; scrollbar-color: #d5e2dc transparent; }
.summary-empty {
  font-size: 12.5px; color: #9aa9b3; line-height: 1.65;
  background: var(--bubble-ai); border-radius: 10px; padding: 11px 12px;
}
.summary-item {
  display: flex; gap: 8px; align-items: baseline; font-size: 13px;
  background: var(--bubble-ai); border-radius: 8px; padding: 7px 11px;
  animation: chips-in .2s ease both;
}
/* 危险信号组：常驻置顶红标。整个会话都在，滚不走。 */
.sum-g.g-rf .sum-gt { color: #c0392b; border-left-color: #e74c3c; }
.sum-g.g-rf .summary-item { background: #fdeceb; border: 1px solid #f5c6c2; }
.sum-g.g-rf .sv { color: #c0392b; font-weight: 700; }

/* 摘要按病史采集框架分组：主诉 + 五项辅诉。组名做左侧竖线的小标题，
   组内条目缩进，让它读起来像一份病历而不是一堆键值对。 */
.sum-g { display: flex; flex-direction: column; gap: 5px; }
.sum-g + .sum-g { margin-top: 9px; }
.sum-gt {
  font-size: 11.5px; font-weight: 700; color: var(--green-d);
  letter-spacing: .3px; padding-left: 7px; border-left: 2px solid var(--green);
  line-height: 1.1; margin-bottom: 1px;
}
.summary-item .sk { color: var(--ink-soft); flex: 0 0 58px; font-size: 12.5px; }
/* 组名与键名相同的组（家族史/个人史/系统回顾/主诉）不重复写键名，
   但保留占位宽度，让各组的值仍然左对齐成一列。 */
.summary-item .sk.sk-empty { flex: 0 0 0; }
.summary-item .sv { color: var(--ink); font-weight: 600; word-break: break-word; }
.summary-item .sv.risk-high { color: #d64545; }
.summary-item .sv.risk-mid { color: #d98324; }
.summary-item .sv.risk-low { color: var(--green-d); }

/* 右：对话 */
.chat-panel {
  background: var(--panel); border: 1px solid var(--line); border-radius: 18px;
  display: flex; flex-direction: column;
  /* 高度由 .layout 定死。min-height 是布局还是自然高度时留下的，现在会反过来
     顶破视口：640 高的屏上 layout 只有 536，min-height:560 硬撑出 24px 溢出。
     单列 fallback 那边仍然需要它，所以挪进 @media 里。 */
  min-height: 0;
  box-shadow: 0 8px 26px rgba(20,60,50,.06); overflow: hidden;
}
.chat-head {
  padding: 16px 20px; border-bottom: 1px solid var(--line);
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.chat-heading { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.chat-title { font-weight: 800; font-size: 16px; }
.chat-sub { color: var(--ink-soft); font-size: 12px; }

@media (max-width: 620px) {
  .chat-head { align-items: flex-start; flex-wrap: wrap; }
  .chat-heading { width: 100%; }
}

.messages {
  flex: 1; overflow-y: auto; padding: 20px; display: flex; flex-direction: column; gap: 14px;
}
.msg { display: flex; gap: 10px; max-width: 86%; }
.msg .avatar-dot {
  width: 30px; height: 30px; border-radius: 50%; flex: 0 0 30px;
  background: #d9efe7 center/cover; margin-top: 2px;
}
.msg .bubble {
  padding: 11px 14px; border-radius: 14px; font-size: 14.5px; line-height: 1.7;
  white-space: pre-wrap; word-break: break-word;
}
.msg.ai { align-self: flex-start; }
.msg.ai .bubble { background: var(--bubble-ai); color: var(--ink); border-top-left-radius: 4px; }
.msg.user { align-self: flex-end; flex-direction: row-reverse; }
.msg.user .bubble { background: var(--bubble-user); color: #fff; border-top-right-radius: 4px; }
/* 只覆盖底色：用 background 简写会把上面的 center/cover 一并重置，头像就只显示左上角一小块 */
.msg.user .avatar-dot { background-color: #cfe9ff; }

/* 气泡内 markdown 渲染 */
.bubble .md-p { margin: 0; }
.bubble .md-p + .md-p { margin-top: 4px; }
.bubble .md-h { font-weight: 800; margin: 8px 0 4px; font-size: 15px; }
/* 「出现这些请尽快就医」= 以后要留意的清单。它此前和「目前看」共用 .md-h，
   长得一模一样，混在回答里根本不像警示。橙色分级：它比正文重，但比置顶的
   红旗横幅（= 你现在就有危险）轻。 */
.bubble .md-h-warn {
  color: #b9541b; border-left: 3px solid #e8833a; padding-left: 8px;
  margin-top: 11px;
}
.bubble .md-h-warn ~ .md-l { color: #8a4a22; }

/* 风险筛查命中时，这一行在过程卡里变红 —— 安全通道要看得见它在工作 */
.proc-row.proc-alert .proc-ico { color: #d64545; }
.proc-row.proc-alert .proc-text { color: #c0392b; }
.proc-row.proc-alert .proc-text b { color: #c0392b; }

/* 红旗横幅：患者【已经说出来】的危险信号。置顶在答案之上——不放结果卡里，
   因为结果卡要滚、且只有最后一轮才有，而红旗第一轮就可能响。 */
.rf-banner {
  border-radius: 12px; padding: 11px 13px; margin: 0 0 10px;
  background: #fff6ed; border: 1px solid #f0c9a4; border-left: 4px solid #e8833a;
  animation: rf-in .28s cubic-bezier(.2,.8,.2,1) both;
}
.rf-banner.rf-er {
  background: #fdeceb; border-color: #f0b6b1; border-left-color: #d64545;
}
@keyframes rf-in {
  from { opacity: 0; transform: translateY(-5px); }
  to   { opacity: 1; transform: none; }
}
.rf-top { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; }
.rf-icon { font-size: 15px; line-height: 1; }
.rf-level { font-weight: 800; font-size: 14.5px; color: #b9541b; letter-spacing: .2px; }
.rf-er .rf-level, .rf-er .rf-icon { color: #c0392b; }
.rf-signs { font-size: 13px; color: var(--ink); line-height: 1.7; }
.rf-signs b { font-weight: 700; color: #b9541b; }
.rf-er .rf-signs b { color: #c0392b; }
.rf-why { font-size: 12.5px; color: var(--ink-soft); margin-top: 3px; }
.rf-act {
  margin-top: 8px; font-size: 13px; font-weight: 700; color: #fff;
  background: #e8833a; border-radius: 8px; padding: 7px 11px; display: inline-block;
}
.rf-er .rf-act { background: #d64545; }
.bubble .md-gap { height: 7px; }
.bubble ul, .bubble ol { margin: 5px 0; padding-left: 20px; }
.bubble li { margin: 2px 0; }
.bubble strong { font-weight: 800; }
.bubble em { font-style: italic; }
.bubble code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px;
  background: rgba(15,40,35,.08); padding: 1px 5px; border-radius: 5px;
}
.msg.user .bubble code { background: rgba(255,255,255,.22); }

.typing-dots span {
  display: inline-block; width: 6px; height: 6px; margin: 0 2px; border-radius: 50%;
  background: #9fb3bd; animation: blink-dot 1.2s infinite;
}
.typing-dots span:nth-child(2){ animation-delay: .2s; }
.typing-dots span:nth-child(3){ animation-delay: .4s; }
@keyframes blink-dot { 0%,80%,100%{opacity:.3} 40%{opacity:1} }

.caret::after { content: "▍"; color: var(--green); animation: caret 1s steps(1) infinite; }
@keyframes caret { 50% { opacity: 0; } }

/* 输入区 */
.composer {
  display: flex; gap: 10px; padding: 14px 16px; border-top: 1px solid var(--line);
  /* stretch 而不是 flex-end：发送按钮的 padding 是 0 22px（无垂直 padding），
     高度全靠 line-height 撑出 21px，而输入框 44、照片/病历 36 —— 三个控件
     三个高度。flex-end 只把它们底对齐，对不齐的高度还在。stretch 直接拉平。 */
  align-items: stretch;
}
/* 上传入口：照片 / 病历 */
.up-group { display: flex; gap: 6px; flex: 0 0 auto; }
.up-btn {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  /* 纵向也要居中。原先只有 align-items(横向)，高度靠 padding 撑得正好所以看不出来；
     .composer 改成 align-items:stretch 后按钮被拉到 46px，多出来的空间全堆在下面，
     图标和字被顶到顶上去了。 */
  justify-content: center;
  border: 1px solid var(--line); background: #fff; color: var(--ink-soft);
  border-radius: 11px; padding: 7px 9px; cursor: pointer; font-family: inherit;
  transition: border-color .15s, color .15s, background .15s;
}
.up-btn:hover:not(:disabled) { border-color: var(--green); color: var(--green-d); background: #f2faf7; }
.up-btn:disabled { opacity: .45; cursor: not-allowed; }
.up-btn svg {
  width: 19px; height: 19px; fill: none; stroke: currentColor;
  stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
.up-btn span { font-size: 10.5px; font-weight: 600; }
.voice-btn.recording {
  border-color: #d64545; color: #b52d2d; background: #fff1ef;
}
.voice-btn.recording svg { animation: voice-pulse 1s ease-in-out infinite; }
.voice-btn.transcribing {
  border-color: var(--green); color: var(--green-d); background: #edf9f5;
}
.composer .voice-btn.voice-mode {
  border: 1px solid var(--green); color: #fff; background: var(--green);
  box-shadow: 0 0 0 3px rgba(31, 139, 105, .12);
}
.composer .voice-btn.voice-mode.recording {
  border-color: #d64545; color: #fff; background: #c83c3c;
  box-shadow: 0 0 0 3px rgba(200, 60, 60, .13);
}
.composer .voice-btn.voice-mode.transcribing {
  border-color: #237c8b; color: #fff; background: #237c8b;
}
.composer .voice-btn.voice-mode.speaking-now {
  border-color: #8b6b23; color: #fff; background: #8b6b23;
}
@keyframes voice-pulse {
  0%, 100% { opacity: .45; transform: scale(.92); }
  50% { opacity: 1; transform: scale(1.08); }
}

/* 上传的照片气泡 */
.img-bubble { padding: 6px !important; }
.up-thumb { display: block; max-width: 220px; border-radius: 9px; }
.up-cap { font-size: 13px; padding: 6px 4px 2px; }

/* 病历识别与核对 */
.ocr-card {
  align-self: flex-start; max-width: 92%; margin-left: 40px;
  background: #fff; border: 1px solid #cfe1da; border-radius: 14px;
  padding: 14px; animation: chips-in .25s ease both;
}
.ocr-head { margin-bottom: 10px; }
.ocr-title { font-size: 14px; font-weight: 800; color: var(--ink); }
.ocr-body { display: flex; gap: 14px; align-items: flex-start; }
.ocr-img {
  flex: 0 0 190px; width: 190px; border-radius: 9px;
  border: 1px solid var(--line); display: block;
}
.ocr-side { flex: 1; min-width: 0; }
.ocr-tip {
  font-size: 12px; color: var(--ink-soft); line-height: 1.6; margin-bottom: 9px;
  background: #fff4e0; border-radius: 7px; padding: 7px 9px;
}
.ocr-tip b { color: #a8630c; }
.ocr-row { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; }
.ocr-k {
  flex: 0 0 92px; font-size: 12px; color: var(--ink-soft);
  display: flex; align-items: center; gap: 4px;
}
.ocr-c { font-size: 10px; font-weight: 700; padding: 1px 4px; border-radius: 3px; }
.ocr-c.c-high { background: #e8f6ef; color: #1c7a55; }
.ocr-c.c-medium { background: #fff4e0; color: #a8630c; }
.ocr-c.c-low { background: #ffe9e6; color: #c0331f; }
.ocr-v {
  flex: 1; min-width: 0; border: 1px solid var(--line); border-radius: 7px;
  padding: 5px 8px; font-size: 13px; font-family: inherit; color: var(--ink); outline: none;
}
.ocr-v:focus { border-color: var(--green); }
.ocr-del {
  flex: 0 0 22px; height: 22px; border: none; background: transparent;
  color: #9fb0ba; font-size: 17px; cursor: pointer; border-radius: 5px; line-height: 1;
}
.ocr-del:hover { background: #ffe9e6; color: #c0331f; }
.ocr-unread { font-size: 11.5px; color: #c0331f; margin-top: 7px; }
.ocr-empty { font-size: 13px; color: var(--ink-soft); line-height: 1.7; }
.ocr-acts { display: flex; gap: 8px; align-items: center; margin-top: 11px; }
.ocr-acts .mk-btn { flex: 1; }
.ocr-skip {
  border: none; background: transparent; color: var(--ink-soft);
  font-size: 12.5px; font-family: inherit; cursor: pointer; padding: 6px 10px; border-radius: 7px;
}
.ocr-skip:hover { background: #eef4f2; }
.ocr-card.done { padding: 11px 14px; }
.ocr-ok { font-size: 13.5px; font-weight: 600; color: var(--green-d); }
.composer textarea {
  flex: 1; resize: none; border: 1px solid var(--line); border-radius: 12px;
  padding: 11px 14px; font-size: 14.5px; font-family: inherit; line-height: 1.5;
  max-height: 140px; outline: none; transition: border .2s;
}
.composer textarea:focus { border-color: var(--green); }
.composer button {
  border: none; background: var(--green); color: #fff; font-weight: 700;
  padding: 0 22px; border-radius: 12px; cursor: pointer; font-size: 14.5px;
  transition: background .2s, opacity .2s;
}
.composer button:hover { background: var(--green-d); }
.composer button:disabled { opacity: .5; cursor: not-allowed; }

.disclaimer { color: #9fb0ba; font-size: 12px; text-align: center; padding: 0 16px 14px; }
