/* 格物 · 展品页布局（v2）
   舞台占满全屏，界面是浮在舞台上的玻璃：左上展签、右上工具、左侧控制台、右侧展签卡、底部模式挂件。
   所有展品共用同一套分区。 */
@import url("./base.css");

:root {
  --gut: 20px;         /* 屏幕边距 */
  --pw: 320px;         /* 控制台宽度 */
  --shift: 172px;      /* 挂件、仪表、字幕相对屏幕中心的右移量（让出控制台）；3D 画面的中心由 main.js 按舞台安全区实时计算 */
  --top: 76px;         /* 控制台、展签卡的上沿：顶栏 40 + 上下各 16 / 20 */
  --dock-h: 64px;
}

html, body { height: 100%; overflow: hidden; }
body.exhibit {
  background:
    radial-gradient(46% 42% at calc(50% + var(--shift)) 44%, rgba(31, 110, 255, 0.13), transparent 72%),
    radial-gradient(80% 50% at 50% 115%, rgba(20, 50, 110, 0.35), transparent 70%),
    #000;
}
/* 暗角 */
body.exhibit::after {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 3;
  background: radial-gradient(120% 95% at calc(50% + var(--shift) * 0.6) 48%, transparent 58%, rgba(0, 0, 0, 0.6));
}
#view { position: fixed; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; z-index: 1; }

/* ---------- 刻度 ----------
   间距只用 4 / 8 / 12 / 16 / 20 / 24；顶栏三组控件同高 40，中线对齐；
   控制台内容左右各 16，分组内文字再缩进 12（小节标题与它对齐）。
   可读文字最低 --label-3（44%），最小 12px；--label-4 只给分隔线和装饰。 */

/* 中文正文只在标点和空格处断行，不把一个词拆到两行 */
.lead, .note, .info p, .info li, .caption .cap-text, .steps li, .warn, .foot { word-break: keep-all; overflow-wrap: anywhere; }
/* 仪表的说明栏很窄，按标点断行会参差不齐：这里用常规断行 */
.hud .phase .txt { line-break: strict; text-wrap: pretty; }

/* ---------- 舞台读数：比例尺 ---------- */
.stage-hud { position: fixed; inset: 0; pointer-events: none; z-index: 4; }
.scalebar { position: absolute; left: calc(var(--pw) + var(--gut) + 24px); bottom: 28px; display: flex; flex-direction: column; gap: 5px; font-size: 12px; font-weight: 500; color: var(--label-3); font-variant-numeric: tabular-nums; transition: opacity 0.4s; }
.scalebar i { display: block; height: 5px; border: 1px solid rgba(245, 245, 247, 0.55); border-top: 0; border-radius: 0 0 2px 2px; transition: width 0.4s var(--ease); }

/* ---------- 顶栏：返回 · 展签 · 位置 · 工具，全部 40 高 ---------- */
.topbar {
  position: fixed; top: var(--gut); left: var(--gut); right: var(--gut); z-index: 10;
  display: flex; align-items: center; gap: 12px; height: 40px; pointer-events: none;
}
.topbar > * { pointer-events: auto; }
.brand { display: flex; align-items: center; gap: 12px; }
.brand .back {
  width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center; flex: none;
  color: var(--label); text-decoration: none; transition: transform 0.4s var(--spring), background-color 0.25s;
}
.brand .back .ic { width: 18px; height: 18px; stroke-width: 2.2; margin-left: -1px; }
.brand .back:hover { background: rgba(70, 70, 78, 0.55); }
.brand .back:active { transform: scale(0.92); }
.placard { display: flex; flex-direction: column; justify-content: center; height: 40px; text-shadow: 0 1px 12px rgba(0, 0, 0, 0.6); }
.placard .no { font-size: 12px; font-weight: 600; line-height: 15px; color: var(--label-2); letter-spacing: 0.01em; font-variant-numeric: tabular-nums; }
.placard h1 { margin: 0; font-family: var(--font-display); font-size: 19px; font-weight: 600; line-height: 24px; letter-spacing: 0.01em; white-space: nowrap; }
.placard h1 span { font-size: 13px; font-weight: 500; color: var(--label-3); margin-left: 8px; letter-spacing: 0; }

/* 展签也是展品菜单的开关：点一下展开所有展品（按身体部位 / 展区分组） */
.placard.switch { border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; padding: 0 10px 0 8px; margin: 0 -2px 0 -8px; border-radius: 12px; align-items: flex-start; transition: background-color 0.25s; }
.placard.switch:hover { background: rgba(255, 255, 255, 0.07); }
.placard.switch:active { transform: scale(0.98); }
.placard.switch:focus-visible { outline: 2px solid var(--accent-hi); outline-offset: 2px; }
.placard.switch h1 { display: flex; align-items: center; }
.sw-caret { display: inline-grid; place-items: center; width: 18px; height: 18px; margin-left: 4px; border-radius: 50%; color: var(--label-2); background: rgba(255, 255, 255, 0.1); transition: transform 0.4s var(--spring), background-color 0.25s; }
.sw-caret .ic { width: 11px; height: 11px; stroke-width: 2.6; transform: rotate(90deg); }
.placard.switch[aria-expanded="true"] .sw-caret { transform: rotate(180deg); background: rgba(255, 255, 255, 0.2); }
.switcher { position: fixed; z-index: 30; width: 312px; background: rgba(28, 28, 32, 0.9); max-height: calc(100vh - 96px); overflow: auto; padding: 6px; border-radius: var(--r-xl); scrollbar-width: none; transform-origin: 24px 0; }
.switcher::-webkit-scrollbar { display: none; }
.switcher[hidden], .sw-scrim[hidden] { display: none; }
/* 标题行和暗幕只在手机上出现（桌面是小弹出菜单，点外面就收） */
.switcher .sw-head, .sw-scrim { display: none; }
.switcher.show { animation: menuIn 0.42s var(--spring) both; }
@keyframes menuIn { from { opacity: 0; transform: scale(0.94) translateY(-6px); } }
.switcher .sw-g + .sw-g { margin-top: 2px; }
.switcher h5 { margin: 0; padding: 10px 10px 4px; font-size: 12px; font-weight: 600; color: var(--label-3); display: flex; align-items: center; gap: 6px; }
.switcher h5 i { width: 3px; height: 3px; border-radius: 50%; background: currentColor; }
.switcher a { display: grid; grid-template-columns: 28px 1fr auto 14px; align-items: center; gap: 10px; height: 40px; padding: 0 10px 0 6px; border-radius: 12px; color: var(--label); text-decoration: none; font-size: 14px; font-weight: 500; transition: background-color 0.2s; }
.switcher a:hover, .switcher a:focus-visible { background: rgba(255, 255, 255, 0.09); outline: none; }
.switcher a.on { background: rgba(31, 143, 255, 0.16); }
.switcher .sw-ic { width: 28px; height: 28px; border-radius: 8px; display: grid; place-items: center; background: rgba(255, 255, 255, 0.08); color: var(--accent-hi); }
.switcher a.on .sw-ic { background: var(--accent); color: #fff; }
.switcher .sw-ic .ic { width: 17px; height: 17px; }
.switcher .sw-no { font-size: 12px; color: var(--label-3); font-variant-numeric: tabular-nums; }
.switcher a > .ic { width: 14px; height: 14px; color: var(--accent-hi); stroke-width: 2.4; }
.switcher .sw-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 6px 4px 0; padding: 10px 6px 6px; border-top: 0.5px solid rgba(255, 255, 255, 0.1); font-size: 12px; color: var(--label-3); }
.switcher .sw-foot a { display: inline-flex; grid-template-columns: none; height: 28px; padding: 0 8px 0 4px; gap: 4px; font-size: 13px; color: var(--label-2); }
.switcher .sw-foot a .ic { width: 14px; height: 14px; color: currentColor; }
.switcher kbd { display: inline-grid; place-items: center; min-width: 18px; height: 18px; margin-right: 3px; border-radius: 5px; background: rgba(255, 255, 255, 0.1); font: 600 11px/1 var(--font); color: var(--label-2); }

/* 离开当前展品（不支持跨页视图过渡的浏览器）：整页淡出 */
body.leaving > * { opacity: 0; transition: opacity 0.2s var(--ease); }

/* 语境视图里有自己展品的邻居器官：标注带箭头，描一圈科技蓝 */
.lbl.go span { gap: 2px; padding-right: 6px; box-shadow: var(--spec), inset 0 0 0 1px rgba(61, 225, 255, 0.5), 0 4px 14px rgba(0, 0, 0, 0.35); }
.lbl.go span .ic { width: 12px; height: 12px; stroke-width: 2.4; color: var(--accent-hi); transition: transform 0.4s var(--spring); }
.lbl.go:hover span { background: var(--accent); color: #fff; }
.lbl.go:hover span .ic { color: #fff; transform: translateX(2px); }
/* 控制台：同在胸腔的其它展品 */
.sibs { display: flex; flex-wrap: wrap; gap: 8px; }
.sib { display: inline-flex; align-items: center; gap: 6px; height: calc(36px * var(--fs)); padding: 0 10px 0 12px; border-radius: 999px; background: var(--fill-2); color: var(--label); text-decoration: none; font-size: calc(14px * var(--fs)); font-weight: 500; transition: background-color 0.2s, transform 0.4s var(--spring); }
.sib:hover { background: var(--accent); text-decoration: none; }
.sib:active { transform: scale(0.96); }
.sib .sib-hall { color: var(--label-3, rgba(245,245,247,0.44)); font-size: calc(12px * var(--fs)); font-weight: 400; }
.sib .ic { width: 17px; height: 17px; color: var(--accent-hi); }
.sib:hover .ic { color: #fff; }
.sib .ic:last-child { width: 12px; height: 12px; stroke-width: 2.4; color: var(--label-3); }
.sib:focus-visible { outline: 2px solid var(--accent-hi); outline-offset: 2px; }
/* 语境视图：体内的展品（当前这件高亮） */
.organs { display: grid; gap: 10px; }
.og { display: grid; grid-template-columns: 64px 1fr; align-items: start; gap: 8px; }
.og-n { font-size: 12px; font-weight: 500; color: var(--label-3); line-height: calc(36px * var(--fs)); white-space: nowrap; }
.og-l { display: flex; flex-wrap: wrap; gap: 6px; }
.og .sib { padding: 0 12px 0 10px; }
.sib.on { background: var(--accent); color: #fff; cursor: default; box-shadow: 0 6px 18px -8px rgba(31, 143, 255, 0.9), inset 0 0.5px 0 rgba(255, 255, 255, 0.3); }
.sib.on .ic { color: #fff; }
.sib.on:active { transform: none; }
/* 语境视图悬停提示：跟着光标 */
.hover-tip { position: fixed; left: 0; top: 0; z-index: 25; pointer-events: none; display: flex; align-items: center; gap: 6px; height: 30px; padding: 0 12px 0 9px; border-radius: 999px; background: rgba(30, 30, 34, 0.82); -webkit-backdrop-filter: blur(16px) saturate(180%); backdrop-filter: blur(16px) saturate(180%); box-shadow: var(--spec), 0 6px 18px rgba(0, 0, 0, 0.4); font-size: 13px; color: var(--label); white-space: nowrap; opacity: 0; transition: opacity 0.15s; }
.hover-tip.on { opacity: 1; }
.hover-tip .ic { width: 16px; height: 16px; color: var(--accent-hi); }
.hover-tip b { font-weight: 600; }
.hover-tip span { color: var(--label-2); }

/* 展签卡：前往另一件展品 */
.info .info-go { margin-top: 14px; gap: 6px; }
.info .info-go[hidden] { display: none; }

/* 位置：胸腔 › 心脏（胶囊分段，当前项白底） */
.crumb { display: flex; align-items: center; height: 40px; padding: 3px; border-radius: 999px; margin-left: 8px; }
.crumb button { white-space: nowrap;
  display: inline-flex; align-items: center; gap: 5px; height: 34px; border: 0; background: none; cursor: pointer;
  padding: 0 14px 0 11px; border-radius: 999px; font-size: 13px; font-weight: 500; color: var(--label-2);
  transition: color 0.2s, background-color 0.25s;
}
.crumb button .ic { width: 15px; height: 15px; }
.crumb button:hover { color: var(--label); }
/* 顶栏放不下时：没选中的一项只留图标（fitCrumb 加 .tight） */
.crumb.tight button:not(.on) { padding: 0 10px; }
.crumb.tight button:not(.on) .t { display: none; }
.crumb button.on { color: #1d1d1f; background: #f5f5f7; }
.crumb .sep { color: var(--label-4); display: inline-flex; padding: 0 1px; }
.crumb .sep .ic { width: 12px; height: 12px; }

.tools { margin-left: auto; display: flex; align-items: center; gap: 2px; height: 40px; padding: 3px; border-radius: 999px; }

/* ---------- 模式挂件：浮在舞台下方（visionOS ornament） ---------- */
.dock {
  position: fixed; z-index: 10; bottom: var(--gut); left: calc(50% + var(--shift)); transform: translateX(-50%);
  display: flex; gap: 0; padding: 6px; border-radius: 999px;
  transition: opacity 0.5s var(--ease), transform 0.6s var(--ease);
}
.dock.off { opacity: 0; transform: translate(-50%, 24px) scale(0.96); pointer-events: none; }
/* 胸腔视图：挂件留在原处但退后，告诉观众"进去以后有五种看法"，点任何一项都会先放大心脏 */
.dock.dim { opacity: 0.62; }
.dock.dim:hover, .dock.dim:focus-within { opacity: 1; }
.dock.dim .ind { opacity: 0; }
.dock button {
  position: relative; z-index: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  width: 72px; height: 52px; padding: 0; border: 0; background: none; border-radius: 999px;
  color: var(--label-2); cursor: pointer; font-size: 11.5px; font-weight: 600; letter-spacing: 0.02em;
  transition: color 0.3s, transform 0.4s var(--spring);
}
.dock button .ic { width: 20px; height: 20px; transition: transform 0.45s var(--spring); }
.dock button:hover { color: var(--label); }
.dock button:active { transform: scale(0.92); }
.dock button.on { color: #fff; }
.dock button.on .ic { color: var(--accent-2); }
/* 选中项：一片更亮的玻璃透镜 */
.dock .ind {
  position: absolute; z-index: 0; top: 6px; bottom: 6px; left: 0; width: 72px; border-radius: 999px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.08));
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.3), inset 0 0 0 0.5px rgba(255, 255, 255, 0.18), 0 6px 16px -6px rgba(0, 0, 0, 0.6);
  transition: transform 0.6s var(--spring), width 0.6s var(--spring), opacity 0.3s;
}

/* ---------- 左：控制台（macOS 侧栏式） ---------- */
.panel {
  /* 面板随内容高度收缩（像 visionOS 的窗口），内容超过一屏才滚动；不留一大块空玻璃 */
  position: fixed; left: var(--gut); top: var(--top); z-index: 9; width: var(--pw); max-height: calc(100vh - var(--top) - var(--gut));
  display: flex; flex-direction: column; border-radius: var(--r-xl); overflow: hidden;
  transition: height 0.4s var(--ease);
}
.panel .grabber { display: none; }
.panel .p-scroll { overflow: auto; padding: 18px 16px 20px; scrollbar-width: none; overscroll-behavior: contain; }
.panel .p-scroll::-webkit-scrollbar { display: none; }
/* 下面还有内容：底部渐隐，提示可以往下滚 */
.panel .p-scroll.more { -webkit-mask-image: linear-gradient(#000 calc(100% - 40px), transparent); mask-image: linear-gradient(#000 calc(100% - 40px), transparent); }
/* 切换模式：旧内容就地淡出，新内容同时浮现，面板不会闪空 */
.panel .p-ghost { position: absolute; left: 0; right: 0; overflow: hidden; pointer-events: none; animation: ghostOut 0.26s var(--ease) forwards; }
@keyframes ghostOut { to { opacity: 0; transform: translateY(-6px); filter: blur(4px); } }

/* 标题区：分类 · 标题 + 朗读 · 引导语 */
.p-kicker { display: flex; align-items: center; gap: 5px; font-size: calc(12px * var(--fs)); font-weight: 600; line-height: 16px; color: var(--accent-hi); }
.p-kicker .ic { width: 14px; height: 14px; stroke-width: 2; }
.p-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 4px; }
.p-head h2 { margin: 0; font-family: var(--font-display); font-size: calc(22px * var(--fs)); font-weight: 600; letter-spacing: 0.01em; line-height: 1.25; }
.lead { margin: 8px 0 0; font-size: calc(13.5px * var(--fs)); line-height: 1.6; color: var(--label-2); }

/* 小节：标题与分组里的文字对齐（缩进 12） */
.p-sec { margin-top: 20px; }
.p-sec h4 { display: flex; align-items: baseline; justify-content: space-between; margin: 0 0 6px; padding: 0 12px; font-size: calc(12px * var(--fs)); font-weight: 600; line-height: 16px; color: var(--label-3); letter-spacing: 0.01em; }
.p-sec h4 em { font-style: normal; font-weight: 500; color: var(--label-2); font-variant-numeric: tabular-nums; }
.row { display: flex; gap: 8px; }
.row .btn { flex: 1; }

/* 分组里的滑块行、说明行 */
.srow { display: flex; align-items: center; gap: 12px; min-height: calc(40px * var(--fs)); padding: 0 12px; font-size: calc(13.5px * var(--fs)); color: var(--label); }
.srow > span { flex: none; }
.srow input { flex: 1; }
.srow.off > span { color: var(--label-3); }

/* 关键数字：一个分组，三栏，发丝线分隔 */
.stats { display: grid; grid-template-columns: repeat(3, 1fr); margin-top: 16px; padding: 12px 0 10px; }
.stats div { text-align: center; position: relative; }
.stats div + div::before { content: ""; position: absolute; left: 0; top: 4px; bottom: 4px; width: 0.5px; background: var(--hair); }
.stats b { display: block; font-size: calc(24px * var(--fs)); font-weight: 600; letter-spacing: -0.01em; line-height: 1.2; font-variant-numeric: tabular-nums; }
.stats.dense b { font-size: calc(20px * var(--fs)); }
.stats b small { font-size: 12px; font-weight: 500; color: var(--label-3); margin-left: 2px; letter-spacing: 0; }
.stats div > span { font-size: 12px; color: var(--label-3); }

/* 情形：分组列表 + 对勾 */
.scen {
  display: flex; align-items: center; gap: 8px; width: 100%; min-height: calc(40px * var(--fs));
  text-align: left; border: 0; background: none; padding: 0 12px;
  cursor: pointer; font-size: calc(13.5px * var(--fs)); font-weight: 400; color: var(--label);
  transition: background-color 0.15s;
}
.scen small { margin-left: auto; font-size: calc(12.5px * var(--fs)); color: var(--label-3); font-variant-numeric: tabular-nums; }
.scen .ic { width: 15px; height: 15px; stroke-width: 2.4; color: var(--accent-hi); opacity: 0; transform: scale(0.5); transition: opacity 0.2s, transform 0.4s var(--spring); }
.scen:hover { background: rgba(255, 255, 255, 0.035); }
.scen:active { background: rgba(255, 255, 255, 0.07); }
.scen.on { font-weight: 600; }
.scen.on .ic { opacity: 1; transform: none; }
.scen.on small { color: var(--label-2); }

/* 说明：分组里的一段文字 + 朗读 */
.note { font-size: calc(12.5px * var(--fs)); line-height: 1.6; color: var(--label-3); margin: 8px 12px 0; }
.note-box { display: flex; gap: 10px; align-items: flex-start; padding: 12px; margin-top: 16px; }
.note-box > * + *::before { display: none; } /* 说明框也是 .group：按钮和正文之间不画分组分隔线 */
.note-box .say { width: 24px; height: 24px; margin-top: 1px; }
.note-box .say .ic { width: 13px; height: 13px; }
.note-box .note { margin: 0; flex: 1; color: var(--label-2); font-size: calc(13px * var(--fs)); }
.warn { display: flex; gap: 10px; align-items: flex-start; font-size: calc(13px * var(--fs)); line-height: 1.55; color: #ffe2a8; background: rgba(255, 207, 107, 0.1); box-shadow: inset 0 0 0 0.5px rgba(255, 207, 107, 0.2); padding: 10px 12px; border-radius: var(--r-md); margin-top: 8px; }
.warn::before { content: "!"; flex: none; width: 16px; height: 16px; margin-top: 2px; border-radius: 50%; display: grid; place-items: center; font-size: 11px; font-weight: 800; color: #1d1d1f; background: var(--amber); }
.legend { display: grid; gap: 4px; margin-top: 8px; padding: 0 12px; font-size: calc(12.5px * var(--fs)); line-height: 1.6; color: var(--label-2); }
.legend span { display: flex; align-items: center; gap: 8px; }
.legend i { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.legend .poor i { background: var(--blood-poor); box-shadow: 0 0 6px var(--blood-poor); }
.legend .rich i { background: var(--blood-rich); box-shadow: 0 0 6px var(--blood-rich); }
.legend .elec i { background: var(--elec); box-shadow: 0 0 6px var(--elec); }
.legend .air i { background: var(--air); box-shadow: 0 0 6px var(--air); }
.legend .co2 i { background: var(--co2); box-shadow: 0 0 6px var(--co2); }
.legend [class^="lobe-"] i, .legend [class^="t-"] i { border-radius: 3px; }
.legend .urine i { background: var(--urine); box-shadow: 0 0 6px var(--urine); } .legend .water i { background: var(--water); box-shadow: 0 0 6px var(--water); }
.legend .glucose i { background: var(--glucose); box-shadow: 0 0 6px var(--glucose); } .legend .salt i { background: var(--salt); box-shadow: 0 0 6px var(--salt); }
.legend .parietal i { background: var(--parietal); } .legend .chief i { background: var(--chief); }
.legend .portal i { background: var(--portal); box-shadow: 0 0 6px var(--portal); }
.legend [class^="seg-"] i { border-radius: 3px; }
.legend .seg-s1 i { background: var(--seg-s1); } .legend .seg-s2 i { background: var(--seg-s2); } .legend .seg-s3 i { background: var(--seg-s3); } .legend .seg-s4 i { background: var(--seg-s4); }
.legend .seg-s5 i { background: var(--seg-s5); } .legend .seg-s6 i { background: var(--seg-s6); } .legend .seg-s7 i { background: var(--seg-s7); } .legend .seg-s8 i { background: var(--seg-s8); } .legend .seg-s9 i { background: var(--seg-s9); } .legend .seg-s10 i { background: var(--seg-s10); }
.legend .stool i { background: var(--stool); box-shadow: 0 0 6px var(--stool); } .legend .fat i { background: var(--fat); box-shadow: 0 0 6px var(--fat); }
.legend span[style*="--c"] i { background: var(--c); border-radius: 3px; } /* 颜色由展品直接给（大脑的脑叶 / 功能区配色） */
.legend .flora i { background: var(--flora); box-shadow: 0 0 6px var(--flora); } .legend .bile i { background: var(--bile); box-shadow: 0 0 6px var(--bile); }
.legend .insulin i { background: var(--insulin); box-shadow: 0 0 6px var(--insulin); } .legend .glucagon i { background: var(--glucagon); box-shadow: 0 0 6px var(--glucagon); } .legend .enzyme i { background: var(--enzyme); box-shadow: 0 0 6px var(--enzyme); }
.legend .t-cortex i { background: var(--t-cortex); } .legend .t-medulla i { background: var(--t-medulla); } .legend .t-collect i { background: var(--t-collect); }
.legend .lobe-rul i { background: var(--lobe-rul); } .legend .lobe-rml i { background: var(--lobe-rml); } .legend .lobe-rll i { background: var(--lobe-rll); }
.legend .lobe-lul i { background: var(--lobe-lul); } .legend .lobe-lll i { background: var(--lobe-lll); }

/* 导览步骤：分组列表，当前步蓝底 */
.steps { list-style: none; padding: 0; margin: 0; }
.steps li { font-size: calc(13px * var(--fs)); color: var(--label-2); padding: 10px 12px 10px 44px; cursor: pointer; line-height: 1.5; transition: background-color 0.15s, color 0.2s; --sep-x: 44px; }
.steps li:hover { background: rgba(255, 255, 255, 0.035); color: var(--label); }
.steps li i { position: absolute; left: 12px; top: 10px; width: 22px; height: 22px; border-radius: 50%; background: var(--fill-2); font-style: normal; font-size: 11.5px; font-weight: 600; display: grid; place-items: center; color: var(--label-2); font-variant-numeric: tabular-nums; transition: background-color 0.3s, color 0.3s; }
.steps li.done { color: var(--label-3); }
.steps li.done i { color: var(--accent-hi); background: var(--accent-soft); }
.steps li.on { color: #fff; background: var(--accent-soft); }
.steps li.on i { background: var(--accent); color: #fff; }

/* 署名：窄屏时放在控制台底部（宽屏在右下角） */
.p-credit { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 24px 12px 0; font-size: 12px; line-height: 1.6; color: var(--label-3); }
.p-credit a { color: var(--label-2); text-decoration: none; }
.p-credit .badge { font-weight: 600; color: var(--amber); padding: 2px 8px; border-radius: 999px; background: rgba(255, 207, 107, 0.1); }

/* ---------- 右：展签（部位说明卡） ---------- */
.info { position: fixed; right: var(--gut); top: var(--top); z-index: 9; width: 336px; max-height: calc(100vh - var(--top) - var(--gut) - var(--dock-h) - 16px); overflow: auto; padding: 16px 16px 16px; border-radius: var(--r-xl); scrollbar-width: none; }
.info::-webkit-scrollbar { display: none; }
.info[hidden] { display: none; }
.info.show { animation: cardIn 0.6s var(--ease) both; }
@keyframes cardIn { from { opacity: 0; transform: translateY(8px) scale(0.97); filter: blur(8px); } }
.i-top { display: flex; align-items: center; gap: 6px; }
.i-top .tag { font-size: 12px; font-weight: 600; line-height: 16px; color: var(--accent-hi); padding: 4px 10px; border-radius: 999px; background: var(--accent-soft); }
.i-top .grow { flex: 1; }
.i-top .close { width: 28px; height: 28px; border-radius: 50%; border: 0; background: var(--fill-2); color: var(--label-2); cursor: pointer; display: grid; place-items: center; transition: background-color 0.2s, transform 0.4s var(--spring); }
.i-top .close .ic { width: 13px; height: 13px; stroke-width: 2.4; }
.i-top .close:hover { background: var(--fill); color: var(--label); }
.i-top .close:active { transform: scale(0.9); }
.info h3 { margin: 14px 0 0; font-family: var(--font-display); font-size: calc(24px * var(--fs)); font-weight: 600; letter-spacing: 0.01em; line-height: 1.2; }
.info .en { margin: 2px 0 0; font-size: 13px; color: var(--label-3); }
.info p { font-size: calc(14px * var(--fs)); line-height: 1.65; color: var(--label-2); margin: 10px 0 0; }
.info ul { margin: 14px 0 0; padding: 0; list-style: none; }
.info ul:empty { display: none; }
.info li { font-size: calc(13px * var(--fs)); line-height: 1.55; color: var(--label-2); padding: 10px 12px 10px 26px; }
.info li::after { content: ""; position: absolute; left: 12px; top: calc(10px + 0.775em - 2.5px); width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }

/* ---------- 底：心动周期仪表 ---------- */
.hud {
  position: fixed; left: calc(50% + var(--shift)); bottom: calc(var(--gut) + var(--dock-h) + 12px); transform: translateX(-50%); z-index: 8;
  width: min(700px, calc(100vw - var(--pw) - var(--gut) * 4)); min-width: 460px;
  padding: 12px 12px 12px 16px; display: grid; grid-template-columns: 1fr 1.3fr; gap: 16px; align-items: center; border-radius: 20px;
}
.hud[hidden] { display: none; }
.hud .phase { font-size: calc(13px * var(--fs)); line-height: 1.55; color: var(--label-2); }
.hud .phase .ph { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.hud .phase b { font-size: calc(15px * var(--fs)); color: var(--label); font-weight: 600; }
.hud .phase .ph i { width: 8px; height: 8px; border-radius: 50%; box-shadow: 0 0 8px currentColor; }
.hud .phase .say { width: 24px; height: 24px; margin-left: auto; }
.hud .phase .say .ic { width: 13px; height: 13px; }
.hud .ecgwrap { position: relative; }
.hud canvas { width: 100%; height: 92px; display: block; border-radius: 10px; background: rgba(0, 0, 0, 0.35); box-shadow: inset 0 0 0 0.5px rgba(125, 255, 176, 0.14); }
.hud .bpm { position: absolute; right: 10px; top: 7px; font-size: 12px; font-weight: 600; color: var(--green); font-variant-numeric: tabular-nums; text-shadow: 0 0 10px rgba(125, 255, 176, 0.5); }
.hud .timeline { display: flex; height: 3px; margin-top: 8px; position: relative; gap: 2px; }
.hud .timeline span { display: block; height: 100%; border-radius: 2px; opacity: 0.7; }
.hud .timeline em { position: absolute; top: -4px; width: 2px; height: 11px; margin-left: -1px; background: #fff; border-radius: 1px; box-shadow: 0 0 6px rgba(255, 255, 255, 0.8); }
/* 精简仪表：导览时和字幕同屏，只留阶段名、心率和时间轴，别把展品挤没了 */
.hud.compact { display: flex; align-items: center; gap: 16px; width: min(540px, calc(100vw - var(--pw) - var(--gut) * 4)); min-width: 0; height: 40px; padding: 0 16px; border-radius: 999px; }
.hud.compact .phase { flex: none; }
.hud.compact .phase .ph { margin: 0; }
.hud.compact .phase .txt, .hud.compact .phase .say, .hud.compact canvas { display: none; }
.hud.compact .ecgwrap { flex: 1; display: flex; align-items: center; gap: 12px; min-width: 0; }
.hud.compact .bpm { position: static; order: 2; flex: none; }
.hud.compact .timeline { flex: 1; margin: 0; }

/* ---------- 导览字幕 ---------- */
/* --hud-h 由 main.js 按仪表的实际高度写入：字幕总是正好停在仪表上方 */
.caption { position: fixed; left: calc(50% + var(--shift)); transform: translateX(-50%); bottom: calc(var(--gut) + var(--dock-h) + 12px); z-index: 11; width: min(640px, calc(100vw - var(--pw) - var(--gut) * 4)); padding: 16px 20px 14px; border-radius: 20px; }
.caption[hidden] { display: none; }
.caption.raised { bottom: calc(var(--gut) + var(--dock-h) + 20px + var(--hud-h, 0px)); }
.caption .cap-hint { display: flex; width: fit-content; align-items: center; gap: 6px; margin: -2px auto 10px; padding: 4px 10px; border-radius: 999px; background: var(--accent-soft); color: var(--accent-2); font-size: 12px; font-weight: 600; animation: hintPulse 1.8s var(--ease) infinite; }
.caption .cap-hint[hidden] { display: none; }
.caption .cap-hint .ic { width: 14px; height: 14px; }
@keyframes hintPulse { 50% { opacity: 0.55; } }
.caption .cap-text { font-size: calc(17px * var(--fs)); font-weight: 500; line-height: 1.7; text-align: center; letter-spacing: 0.01em; text-wrap: pretty; }
.caption .ctl { display: flex; justify-content: center; align-items: center; gap: 8px; margin-top: 12px; }
.btn.round { width: 34px; height: 34px; padding: 0; }
.btn.round .ic { width: 15px; height: 15px; }
.caption .btn.primary { height: 34px; min-width: 92px; }
.caption .prog { height: 3px; margin-top: 14px; border-radius: 2px; background: var(--fill-2); overflow: hidden; }
.caption .prog i { display: block; height: 100%; border-radius: 2px; background: var(--accent); transition: width 0.8s var(--ease); }

/* ---------- 标注 ---------- */
/* 标签胶囊高 24：圆点在锚点，胶囊在右上 12 / 30 处，一根 45° 细引线连接 */
#labels { position: fixed; inset: 0; pointer-events: none; z-index: 5; }
.lbl { position: absolute; left: 0; top: 0; pointer-events: auto; cursor: pointer; white-space: nowrap; }
.lbl i { position: absolute; left: -4px; top: -4px; width: 8px; height: 8px; border-radius: 50%; background: #fff; box-shadow: 0 0 0 2.5px rgba(31, 143, 255, 0.35), 0 0 10px rgba(61, 225, 255, 0.75); }
.lbl i::after { content: ""; position: absolute; inset: -6px; border-radius: 50%; border: 1px solid rgba(255, 255, 255, 0.45); animation: ping 2.6s var(--ease) infinite; }
@keyframes ping { 0% { transform: scale(0.5); opacity: 1; } 100% { transform: scale(1.9); opacity: 0; } }
.lbl span {
  position: absolute; left: 12px; top: -30px; height: calc(24px * var(--fs)); display: flex; align-items: center;
  font-size: calc(12px * var(--fs)); font-weight: 500; padding: 0 10px; border-radius: 999px;
  background: rgba(30, 30, 34, 0.66); color: var(--label);
  -webkit-backdrop-filter: blur(16px) saturate(180%); backdrop-filter: blur(16px) saturate(180%);
  box-shadow: var(--spec), 0 4px 14px rgba(0, 0, 0, 0.35);
  transition: background-color 0.2s, color 0.2s, transform 0.4s var(--spring);
}
.lbl span::before { content: ""; position: absolute; left: -9px; bottom: -8px; width: 12px; height: 0.8px; background: rgba(255, 255, 255, 0.45); transform: rotate(-50deg); transform-origin: right; }
/* 防重叠：main.js 为每个标注挑一个不和别人、不和界面撞的方位（右上 / 左上 / 右下 / 左下） */
.lbl[data-pl="nw"] span { left: auto; right: 12px; }
.lbl[data-pl="nw"] span::before { left: auto; right: -9px; transform: rotate(50deg); transform-origin: left; }
.lbl[data-pl="se"] span { top: 8px; }
.lbl[data-pl="se"] span::before { bottom: auto; top: -7px; transform: rotate(50deg); }
.lbl[data-pl="sw"] span { left: auto; right: 12px; top: 8px; }
.lbl[data-pl="sw"] span::before { left: auto; right: -9px; bottom: auto; top: -7px; transform: rotate(-50deg); transform-origin: left; }
.lbl:focus-visible { outline: none; }
.lbl:focus-visible span { outline: 2px solid var(--accent-hi); outline-offset: 2px; }
.lbl.pop span { animation: pop 0.5s var(--spring); }
@keyframes pop { from { transform: scale(0.7) translateY(4px); opacity: 0; } }
.lbl:hover span, .lbl.on span { background: #f5f5f7; color: #1d1d1f; }
.lbl.primary i { background: var(--accent-2); width: 10px; height: 10px; left: -5px; top: -5px; }
.lbl.primary span { background: var(--accent); color: #fff; font-weight: 600; font-size: calc(13px * var(--fs)); height: calc(28px * var(--fs)); top: -34px; padding: 0 12px; box-shadow: 0 8px 24px -8px rgba(31, 143, 255, 0.95), inset 0 0.5px 0 rgba(255, 255, 255, 0.3); }
.lbl.primary:hover span { background: #3a9dff; color: #fff; }
/* 主标注被排到下方（se / sw）时也要画在下方：上一行的 top: -34px 和方位规则优先级相同、写在后面，会把它盖掉 */
.lbl.primary[data-pl="se"] span, .lbl.primary[data-pl="sw"] span { top: 8px; }
.lbl.measure { pointer-events: none !important; }
.lbl.measure i { display: none; }
.lbl.measure span { left: 0; top: -30px; transform: translateX(-50%); height: 22px; font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; background: rgba(0, 0, 0, 0.6); color: #d6ecff; padding: 0 8px; }
.lbl.measure span::before { display: none; }
/* 尺寸标签挂在尺寸线外侧，不压在对象上 */
.lbl.measure.end span { left: 10px; top: 0; transform: translateY(-50%); }
.lbl.measure.below span { top: 8px; }

/* 操作提示：出现几秒后自己淡出 */
.hint { position: fixed; left: calc(50% + var(--shift)); transform: translateX(-50%); bottom: calc(var(--gut) + var(--dock-h) + 16px); z-index: 4; font-size: 12px; font-weight: 500; color: var(--label-3); display: flex; gap: 6px; animation: hint 9s var(--ease) forwards; pointer-events: none; }
.hint[hidden] { display: none; }
.hint span { display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 10px; border-radius: 999px; background: rgba(255, 255, 255, 0.06); }
.hint .ic { width: 14px; height: 14px; }
@keyframes hint { 0% { opacity: 0; transform: translate(-50%, 8px); } 8%, 75% { opacity: 1; transform: translate(-50%, 0); } 100% { opacity: 0; transform: translate(-50%, 0); } }
/* 署名：右下角右对齐，最宽 240px（1281 宽时离模式挂件约 250px），不会碰到模式挂件；≤1280 收进控制台底部（.p-credit） */
.credit { position: fixed; right: calc(var(--gut) + 4px); bottom: var(--gut); z-index: 4; font-size: 12px; line-height: 1.5; color: var(--label-3); display: flex; flex-direction: column; align-items: flex-end; gap: 2px; max-width: 240px; text-align: right; }
/* 长的一行在 240px 内按词折行（不拆英文词），不伸到模式挂件底下 */
.credit span { word-break: keep-all; overflow-wrap: anywhere; }
.credit .badge { white-space: nowrap; }
.credit, .scalebar { text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9), 0 0 12px rgba(0, 0, 0, 0.8); } /* 满屏的语境画面上也读得清 */
.scalebar i { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.6); }
.credit a { color: var(--label-2); text-decoration: none; }
.credit a:hover { color: var(--label); }
.credit .badge { margin-bottom: 4px; font-weight: 600; color: var(--amber); padding: 2px 8px; border-radius: 999px; background: rgba(255, 207, 107, 0.1); }

/* 灵动岛提示：展品页顶栏中间是位置胶囊，提示放到顶栏下面、舞台正中，不压顶栏 */
.toast { top: calc(var(--gut) + 52px); left: calc(50% + var(--shift)); }

/* ---------- 加载 ---------- */
.loading { position: fixed; inset: 0; z-index: 50; display: grid; place-content: center; justify-items: center; gap: 14px; background: #000; transition: opacity 0.9s var(--ease), visibility 0.9s; }
.loading.done { opacity: 0; visibility: hidden; }
.loading .no { font-size: 13px; font-weight: 600; letter-spacing: 0.12em; color: var(--label-3); }
.loading h2 { margin: 0; font-family: var(--font-display); font-size: 44px; font-weight: 600; letter-spacing: 0.04em; background: linear-gradient(180deg, #fff, #9aa3b5); -webkit-background-clip: text; background-clip: text; color: transparent; }
.loading svg.ecg { width: 200px; height: 46px; overflow: visible; margin: 8px 0 4px; }
.loading svg.ecg path { fill: none; stroke: var(--accent-2); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 520; stroke-dashoffset: 520; animation: draw 1.8s var(--ease) infinite; filter: drop-shadow(0 0 6px rgba(61, 225, 255, 0.7)); }
@keyframes draw { to { stroke-dashoffset: -520; } }
.loading p { margin: 0; color: var(--label-3); font-size: 13px; }
.loading .bar { width: 160px; height: 3px; background: var(--fill-2); border-radius: 3px; overflow: hidden; }
.loading .bar i { display: block; height: 100%; width: 0; background: #f5f5f7; border-radius: 3px; transition: width 0.4s var(--ease); }

/* 儿童模式：更大的触控区 */
html.kid .dock button { width: 80px; height: 58px; font-size: 13px; }
html.kid .dock .ind { width: 80px; }
html.kid .dock button .ic { width: 23px; height: 23px; }

/* 原理模式固定使用教学配色：按钮亮着但是半透明，表示"锁定" */
.icon-btn.on.locked { background: rgba(245, 245, 247, 0.55); }
/* 顶栏工具第一次进入时依次亮出文字 */
.icon-btn.peek > span { opacity: 1; transform: translate(-50%, 0); transition-delay: 0s; }

/* ---------- 窄屏 ---------- */
@media (min-width: 1281px) { .p-credit { display: none; } }
@media (max-width: 1360px) { .hint span:nth-child(n + 3) { display: none; } }
@media (max-width: 1280px) { .credit { display: none; } }
@media (max-width: 1180px) {
  .placard h1 span, .crumb button .ic { display: none; }
}
/* 窄桌面：舞台只剩中间一条，展签卡改占控制台的位置（控制台暂时让开），不盖住展品 */
@media (min-width: 901px) and (max-width: 1280px) {
  .info { left: var(--gut); right: auto; width: var(--pw); max-height: calc(100vh - var(--top) - var(--gut)); }
  .panel { transition: opacity 0.35s var(--ease), transform 0.5s var(--ease); }
  body.sheet .panel { opacity: 0; transform: translateX(-16px) scale(0.98); pointer-events: none; }
}
@media (max-width: 900px) {
  :root { --gut: 10px; --top: 118px; }
  .topbar { top: calc(env(safe-area-inset-top) + 10px); gap: 8px; }
  .brand { gap: 8px; min-width: 0; }
  .placard .no { display: none; }
  .placard h1 { font-size: 17px; }
  .crumb { margin-left: 0; }
  .placard.switch { padding: 0 6px; margin: 0 -2px 0 -6px; }
  .switcher { left: var(--gut); right: var(--gut); top: calc(env(safe-area-inset-top) + 58px); width: auto; max-height: calc(100svh - 80px); }
  .switcher .sw-foot span { display: none; }
  /* 灵动岛提示：顶栏下面是模式挂件，提示放到挂件下方，不压展品名；折成两行时圆角收小 */
  .toast { top: var(--toast-top, calc(env(safe-area-inset-top) + 122px)); left: 50%; border-radius: 18px; }
  .switcher { padding-top: 0; background: rgb(28, 28, 32); } /* 铺满大半屏时不透：否则底下抽屉的边线会透上来 */
  .switcher .sw-head { display: flex; align-items: center; justify-content: space-between; position: sticky; top: 0; z-index: 1; height: 52px; margin: 0 -6px; padding: 0 10px 0 16px; background: rgb(28, 28, 32); border-bottom: 0.5px solid rgba(255, 255, 255, 0.1); }
  .switcher .sw-head b { font-size: 15px; font-weight: 600; color: var(--label); }
  .switcher .sw-close { width: 32px; height: 32px; border-radius: 50%; border: 0; background: var(--fill-2); color: var(--label); display: grid; place-items: center; cursor: pointer; position: relative; transition: transform 0.4s var(--spring); }
  .switcher .sw-close::before { content: ""; position: absolute; inset: -6px; } /* 触控热区 44px */
  .switcher .sw-close .ic { width: 14px; height: 14px; stroke-width: 2.4; }
  .switcher .sw-close:active { transform: scale(0.9); }
  .switcher .sw-g:first-of-type h5 { padding-top: 12px; }
  .sw-scrim { display: block; position: fixed; inset: 0; z-index: 29; background: rgba(0, 0, 0, 0.55); animation: swScrim 0.3s var(--ease) both; }
  @keyframes swScrim { from { opacity: 0; } }
  .crumb button { padding: 0 12px; }
  .crumb .sep { display: none; }
  .crumb.tight button:not(.on) .ic { display: block; width: 17px; height: 17px; }
  .crumb.tighter button { padding: 0 10px; }
  .crumb.tighter button:not(.on) { padding: 0 8px; }
  .crumb.tightest button.on .t { display: none; }
  .crumb.tightest button.on .ic { display: block; width: 17px; height: 17px; }
  .topbar.squeeze { gap: 4px; }
  .topbar.squeeze .brand { gap: 4px; }
  .topbar.squeeze .placard h1 { font-size: 14px; white-space: nowrap; }
  .topbar.squeeze .sw-caret { display: none; }
  .icon-btn > span { display: none; }
  .tools #btnLabels, .tools #btnTeach, .credit, .hint, .scalebar { display: none; }

  .dock { top: calc(env(safe-area-inset-top) + 58px); height: 52px; bottom: auto; left: 50%; right: auto; width: min(calc(100vw - var(--gut) * 2), 560px); transform: translateX(-50%); justify-content: space-between; padding: 4px; }
  .dock.off { transform: translate(-50%, -12px); }
  .dock button { flex: 1; width: auto; height: 44px; font-size: 10.5px; gap: 2px; }
  .dock button .ic { width: 18px; height: 18px; }
  .dock .ind { top: 4px; bottom: 4px; }
  html.kid .dock button { width: auto; height: 50px; }

  /* 控制台与展签卡：底部抽屉。展签卡出现时控制台让到屏幕外，两层磨砂不叠在一起 */
  .panel { top: auto; left: 50%; right: auto; bottom: 0; width: min(100vw, 720px); max-height: 44vh; border-radius: 22px 22px 0 0; transform: translateX(-50%); transition: max-height 0.5s var(--ease), transform 0.5s var(--ease); }
  .panel.collapsed { max-height: 132px; }
  body.sheet .panel { transform: translate(-50%, calc(100% + 12px)); }
  .panel .grabber { display: block; flex: none; height: 24px; width: 100%; border: 0; background: none; cursor: grab; position: relative; touch-action: none; }
  .panel.dragging { transition: none; }
  .panel.dragging .grabber { cursor: grabbing; }
  .panel .grabber::after { content: ""; position: absolute; left: 50%; top: 10px; width: 36px; height: 5px; margin-left: -18px; border-radius: 3px; background: var(--label-4); }
  .panel .p-scroll { padding: 2px 16px calc(env(safe-area-inset-bottom) + 20px); }
  .p-head h2 { font-size: calc(20px * var(--fs)); }
  .info { top: auto; bottom: 0; left: 50%; right: auto; width: min(100vw, 720px); transform: translateX(-50%); max-height: 56vh; z-index: 12; border-radius: 22px 22px 0 0; padding-bottom: calc(env(safe-area-inset-bottom) + 20px); background: rgba(24, 24, 28, 0.9); }
  .info.show { animation-name: sheetIn; }
  @keyframes sheetIn { from { transform: translate(-50%, 40%); opacity: 0; } }
  .info h3 { font-size: calc(22px * var(--fs)); }

  /* 仪表折成一行：阶段名 · 时间轴 · 心率 */
  .hud, .hud.compact { left: 50%; right: auto; top: var(--top); bottom: auto; transform: translateX(-50%); width: min(calc(100vw - var(--gut) * 2), 640px); min-width: 0; height: 40px; display: flex; align-items: center; gap: 12px; padding: 0 8px 0 14px; border-radius: 999px; }
  .hud .phase { flex: none; }
  .hud .phase .ph { margin: 0; gap: 7px; }
  .hud .phase b { font-size: calc(15px * var(--fs)); }
  .hud .phase .txt, .hud canvas { display: none; }
  .hud .phase .say { margin-left: 2px; }
  .hud .ecgwrap { flex: 1; display: flex; align-items: center; gap: 10px; min-width: 0; }
  .hud .bpm { position: static; order: 2; flex: none; }
  .hud .timeline { flex: 1; margin: 0; }
  /* 字幕：默认两行，点一下展开；和仪表同屏时排在仪表下面 */
  .caption, .caption.raised { left: 50%; right: auto; width: min(calc(100vw - var(--gut) * 2), 640px); transform: translateX(-50%); bottom: auto; top: var(--top); padding: 12px 14px 10px; border-radius: 20px; }
  .caption.raised { top: calc(var(--top) + var(--hud-h, 0px) + 8px); }
  .caption .cap-text { font-size: calc(15px * var(--fs)); line-height: 1.65; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; cursor: pointer; }
  .caption.open .cap-text { -webkit-line-clamp: unset; }
  .caption .ctl { margin-top: 10px; gap: 8px; }
  .caption .prog { margin-top: 10px; }
}

/* 没有物理尺度的展品（数学）不画比例尺：scaleUnit() 返回 false */
.scalebar[hidden] { display: none; }

/* 导览循环按钮：打开时亮科技蓝 */
.caption .btn.round.loop.on { background: var(--accent); color: #fff; }
