/* ═══════════════════════════════════════════════════════════════════════
   维修远程协助 · 专家端样式表
   版本：20260928-video-fit-r37（视频比例自适应 + 控件条预留 + 左列滚动兜底）

   令牌与状态色来源（事实优先级：本文件 < 下列规范 < 真机/工程文件）：
     Docs/Design/空间UI视觉规范与样板迁移指南.md
     Docs/Design/按钮配色与交互状态统一规范.md
     Docs/Design/网页端视觉规范与令牌说明书.md   ← 本文件的说明书

   迁移约束（改动前必读）：
   1. app.js:42 alignLiveStageWithToolWorkspace() 用 matchMedia('(min-width:1051px)')，
      并向 .video-stage 写 --live-stage-offset。断点必须保持 1050px，
      .video-stage 必须继续消费该属性。
   2. app.js:38 把真实视频宽高写入 --remote-frame-aspect，令牌名不得改。
   3. JS 依赖的选择器不得重命名：
      .annotation-tools .tool / .spatial-point-tools .spatial-tool（后代选择器）
      .expert-tool-tab / .expert-tool-panel(.active) / .tool-workspace-stage / .video-stage
      [data-device-step] / .device-part-button / .device-highlight-select-button
      .device-part-number / .device-removed-part（后四者由 JS 动态创建）
      JS 切换的类：active done ok error selected local model-view-locked interaction-active
   4. 标注画布按自身 getBoundingClientRect() 换算坐标，外层可加装饰框但不得改变
      .tool-workspace-stage 的确定尺寸与 canvas 的 width/height:100%。
   ═══════════════════════════════════════════════════════════════════════ */

/* ─────────────── 1. 设计令牌 ─────────────── */
:root{
  color-scheme: dark;

  /* JS 会按真实视频宽高覆写，默认 16:9 —— 名称不得改 */
  --remote-frame-aspect: 16 / 9;
  /* JS 会写入对齐偏移；消费处已加 48px 上限，防止模式切换后残留过大偏移 */
  --live-stage-offset: 0px;
  /* 原生 video 控件条预留高度：舞台底部留出这条空白，控件条才不会叠进画面内。
     消费处成对出现——.video-stage 的 padding-bottom 与 video 的 object-position，
     只改一处会让画面重新被控件条压住。 */
  --video-controls-reserve: 40px;

  /* 基底：不透明平面，靠明度三级分层，不靠阴影 */
  --page:            #08131e;
  --surface-1:       #0b1724;
  --surface-2:       #0e1b28;
  --surface-3:       #05080c;
  --surface-sunken:  #0d1826;
  --surface-hover:   #1b3348;
  --surface-active:  #14506f;
  --surface-raise:   #10293d;
  --surface-deep:    #0a1725;
  --surface-off:     #0a121c;
  --thumb:           #22405a;

  /* 结构线：整体降饱和，青色不再到处抢戏 */
  --line-soft:       #4cafe826;
  --line:            #4cafe838;
  --line-strong:     #4cafe85c;

  /* 链路通道 · 青（远程协助、数据、连接） */
  --link-rgb:        88, 211, 255;
  --link:            #58d3ff;
  --link-deep:       #1684d8;
  --link-surface:    #0f405e;
  --link-chip:       #186fa39e;

  /* 维修通道 · 琥珀（设备部件、预案与动作请求） */
  --amber-rgb:       255, 211, 78;
  --amber:           #ffd34e;
  --amber-deep:      #d6a94f;
  --amber-surface:   #3a2c10;
  --amber-chip:      #604819;
  --amber-hover:     #5a431a;
  --amber-active:    #6b501f;
  --amber-border-hi: #ffe08a;
  --amber-on-bright: #2a1f05;

  /* 语义状态 */
  --ok:              #5de0b2;
  --ok-surface:      #10483f;
  --ok-border:       #1f7a66bf;
  --danger:          #ff7a7a;
  --danger-press:    #ff2d2d;
  --danger-surface:  #4c171f;
  --danger-normal:   #4c171ff0;
  --danger-hover:    #ff7affff;
  --danger-active:   #ff2d2dff;
  --danger-on-bright:#2b0b0f;
  --error-text:      #ff9b9b;
  --warn:            #ffc86b;

  /* 状态前景色 */
  --fg-on-link:      #d6f4ff;
  --fg-on-ok:        #d7fff0;
  --fg-on-amber:     #fff2c9;
  --fg-on-danger:    #ffe5e5;
  --fg-amber:        #ffe9ad;
  --fg-amber-hi:     #fff6d8;
  --fg-amber-max:    #fffbe8;
  --fg-hud:          #bfeeff;

  /* 浮层玻璃：混合质感策略中仅浮层允许使用 */
  --glass-drawer:    #081722d9;
  --glass-overlay:   #071827e8;
  --glass-hud:       #061525c9;
  --glass-amber:     #1c1608e6;

  /* 按钮五态背景：直接取自《按钮配色与交互状态统一规范》ColorBlock 原值 */
  --btn-normal:      #2b465aeb;
  --btn-hover:       #58b4ecff;
  --btn-pressed:     #30b9ffff;
  --btn-selected:    #40a6f0ff;
  --btn-disabled:    #33434d70;
  /* 标签色为 web 侧对规范的刻意偏离：hover/pressed/selected 背景过亮，
     白字对比度仅约 2.2:1 不达 WCAG AA，故亮背景改用深色标签。
     背景五态仍与 PICO 头显侧完全一致。详见网页端规范说明书 5.3。 */
  --btn-label:       #ffffff;
  --btn-on-bright:   #06121c;

  /* 文字：白色 alpha 阶梯（替代原先散落的蓝调灰） */
  --text-1:          rgba(255,255,255,.95);
  --text-2:          rgba(255,255,255,.72);
  --text-3:          rgba(255,255,255,.52);
  --text-4:          rgba(255,255,255,.34);
  --text-disabled:   rgba(255,255,255,.28);

  /* 排版：6 档字号，行高一律 = 字号 + 8px，全站下限 13px */
  --font-body:   'Noto Sans SC', 'Source Han Sans SC', 'Microsoft YaHei', 'PingFang SC', sans-serif;
  --font-display:'ZCOOL QingKe HuangYou', 'Noto Sans SC', 'Microsoft YaHei', sans-serif;
  --font-mono:   'IBM Plex Mono', 'Cascadia Mono', Consolas, 'Noto Sans SC', ui-monospace, monospace;

  --fs-display: 20px;  --lh-display: 28px;
  --fs-title:   16px;  --lh-title:   24px;
  --fs-sub:     15px;  --lh-sub:     23px;
  --fs-body:    15px;  --lh-body:    23px;
  --fs-label:   14px;  --lh-label:   22px;
  --fs-caption: 13px;  --lh-caption: 21px;   /* 全站可读文字下限 */
  --fs-mono:    13px;  --lh-mono:    21px;

  --fw-regular: 400;
  --fw-medium:  500;   /* 按钮默认字重（规范要求避免过粗，原为 700） */
  --fw-bold:    700;   /* 只给 h1/h2 与需强调的数值 */

  /* 几何：圆角 4 档、间距 5 档 */
  --r-xs:   4px;
  --r-sm:   8px;
  --r-md:   12px;
  --r-pill: 999px;

  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-6: 24px;

  /* 仪表语言：切角与发光预算，可整体调节 */
  --notch:           14px;
  --glow-strength:   1;
  --notch-clip: polygon(0 var(--notch), var(--notch) 0, 100% 0, 100% calc(100% - var(--notch)), calc(100% - var(--notch)) 100%, 0 100%);

  /* 阴影：只给浮层，主体平面不用 */
  --shadow-float:   0 16px 42px #0008104e;
  --shadow-overlay: 0 24px 64px #000810a0;

  /* 动效：规范 Fade Duration 0.08s */
  --dur-state: .08s;
  --dur-ui:    .18s;
  --ease:      cubic-bezier(.4,0,.2,1);
}

/* ─────────────── 2. 基础与排版 ─────────────── */
*{ box-sizing:border-box; }
html,body{ height:100%; }
body{
  margin:0;
  padding:var(--sp-3);
  font-family:var(--font-body);
  font-size:var(--fs-body);
  line-height:var(--lh-body);
  font-weight:var(--fw-regular);
  color:var(--text-2);
  background:
    radial-gradient(120% 80% at 12% -10%, #123a56 0%, transparent 55%),
    radial-gradient(90% 60% at 100% 110%, #0d2438 0%, transparent 60%),
    var(--page);
  -webkit-font-smoothing:antialiased;
}
main{ width:min(1760px,100%); margin:0 auto; display:grid; gap:var(--sp-3); }

h1,h2,h3,h4{ margin:0; color:var(--text-1); font-weight:var(--fw-bold); }
h1{ font-family:var(--font-display); font-size:var(--fs-display); line-height:var(--lh-display); font-weight:400; letter-spacing:.02em; }
h2{ font-family:var(--font-display); font-size:var(--fs-title);   line-height:var(--lh-title);   font-weight:400; letter-spacing:.02em; }
h3{ font-size:var(--fs-sub);   line-height:var(--lh-sub);   font-weight:var(--fw-medium); }
h4{ font-size:var(--fs-label); line-height:var(--lh-label); font-weight:var(--fw-medium); }
p{ margin:0; color:var(--text-3); }
small{ font-size:var(--fs-caption); line-height:var(--lh-caption); color:var(--text-4); }
strong{ color:var(--text-1); font-weight:var(--fw-medium); }
.mono{ font-family:var(--font-mono); font-size:var(--fs-mono); line-height:var(--lh-mono); font-variant-numeric:tabular-nums; }
.tool-help{ font-size:var(--fs-caption); line-height:var(--lh-caption); color:var(--text-4); }
[hidden]{ display:none !important; }

/* 卡片：用 .card 类，不再用裸 section 选择器（消除原先五处 reset） */
.card{
  background:var(--surface-1);
  border:1px solid var(--line);
  border-radius:var(--r-md);
  padding:var(--sp-4);
}

/* 切角仪表框：外层 1px 充当描边，内层承载内容 */
.notch-frame{ padding:1px; background:var(--line-strong); clip-path:var(--notch-clip); }
.notch-body{ background:var(--surface-1); clip-path:var(--notch-clip); }

/* 发光工具类已于 r35 移除（2026-09-07 用户决定：真实画面不需要光照效果）。
   --glow-strength 令牌保留，仅服务于 LIVE 状态点呼吸与输入焦点环。 */

/* ─────────────── 3. 表单控件 ─────────────── */
label{ display:grid; gap:var(--sp-1); font-size:var(--fs-label); line-height:var(--lh-label); color:var(--text-3); }
input,textarea,select{
  padding:9px 11px;
  font:inherit;
  font-size:var(--fs-label);
  line-height:var(--lh-label);
  color:var(--text-1);
  background:var(--surface-3);
  border:1px solid var(--line-strong);
  border-radius:var(--r-sm);
  transition:border-color var(--dur-state) var(--ease), box-shadow var(--dur-state) var(--ease);
}
input::placeholder,textarea::placeholder{ color:var(--text-4); }
input:focus-visible,textarea:focus-visible,select:focus-visible,button:focus-visible{
  outline:none;
  border-color:var(--link);
  box-shadow:0 0 0 3px rgb(var(--link-rgb) / calc(.22 * var(--glow-strength)));
}
input:disabled,textarea:disabled,select:disabled{ color:var(--text-disabled); background:var(--surface-off); border-color:var(--line-soft); cursor:not-allowed; }
input{ width:12em; }
textarea{ width:100%; resize:vertical; }
select{ min-width:15em; }
#room{
  font-family:var(--font-mono);
  font-size:var(--fs-display); line-height:var(--lh-display);
  letter-spacing:.42em;
  text-align:center;
  padding:10px 8px 10px 18px;   /* 抵消 letter-spacing 末位空隙，视觉居中 */
  color:var(--link);
}

/* ─────────────── 4. 按钮五态 · 严格对齐已批准规范 ─────────────── */
button{
  display:inline-flex; align-items:center; justify-content:center; gap:6px;
  padding:9px 14px;
  font-family:inherit;
  font-size:var(--fs-label);
  line-height:var(--lh-label);
  font-weight:var(--fw-medium);
  color:var(--btn-label);
  background:var(--btn-normal);
  border:1px solid transparent;
  border-radius:var(--r-sm);
  cursor:pointer;
  transition:background-color var(--dur-state) var(--ease),
             color var(--dur-state) var(--ease),
             border-color var(--dur-state) var(--ease),
             box-shadow var(--dur-state) var(--ease);
}
button svg{ width:15px; height:15px; flex:0 0 auto; }
button:hover:not(:disabled){ background:var(--btn-hover);    color:var(--btn-on-bright); }
button:active:not(:disabled){ background:var(--btn-pressed);  color:var(--btn-on-bright); }
button.active,button[aria-pressed="true"]{ background:var(--btn-selected); color:var(--btn-on-bright); }
button:disabled{ background:var(--btn-disabled); color:var(--text-disabled); cursor:not-allowed; }

button.danger{ background:var(--danger-normal); color:var(--fg-on-danger); }
button.danger:hover:not(:disabled){ background:var(--danger-hover);  color:var(--danger-on-bright); }
button.danger:active:not(:disabled){ background:var(--danger-active); color:var(--danger-on-bright); }
button.danger.active{ background:var(--danger-hover); color:var(--danger-on-bright); }
button.danger:disabled{ background:var(--btn-disabled); color:var(--text-disabled); }

/* 幽灵按钮：密集工具条用，降低视觉噪声 */
button.ghost{ background:var(--surface-2); border-color:var(--line-strong); color:var(--text-2); }
button.ghost:hover:not(:disabled){ background:var(--link-surface); border-color:var(--link); color:var(--btn-label); }
button.ghost:active:not(:disabled){ background:var(--surface-active); border-color:var(--btn-pressed); color:var(--btn-label); }
button.ghost.active{ background:var(--link-surface); border-color:var(--link); color:var(--btn-label); }
button.ghost:disabled{ background:var(--surface-2); border-color:var(--line-soft); color:var(--text-disabled); }

/* 维修通道按钮：琥珀语义 */
button.amber{ background:var(--amber-surface); border-color:var(--amber-deep); color:var(--fg-amber); }
button.amber:hover:not(:disabled){ background:var(--amber-hover); border-color:var(--amber); color:var(--fg-amber-hi); }
button.amber:active:not(:disabled){ background:var(--amber-active); border-color:var(--amber-border-hi); color:var(--fg-amber-max); }
button.amber.active{ background:var(--amber); border-color:var(--fg-amber); color:var(--amber-on-bright); }
button.amber.active:hover:not(:disabled){ background:var(--amber); color:var(--amber-on-bright); }
button.amber:disabled{ background:var(--btn-disabled); border-color:var(--line-soft); color:var(--text-disabled); }

/* ─────────────── 5. chip / 状态点 ─────────────── */
.chip{
  display:inline-flex; align-items:center; gap:6px;
  padding:4px 10px;
  border:1px solid var(--line-soft);
  border-radius:var(--r-pill);
  background:var(--surface-2);
  color:var(--text-3);
  font-size:var(--fs-caption); line-height:var(--lh-caption);
  white-space:nowrap;
}
.chip svg{ width:13px; height:13px; }
.chip--link{ border-color:var(--line-strong); background:var(--link-chip); color:var(--fg-on-link); }
.chip--ok{ border-color:color-mix(in srgb, var(--ok) 40%, transparent); background:var(--ok-surface); color:var(--fg-on-ok); }
.chip--amber{ border-color:color-mix(in srgb, var(--amber-deep) 50%, transparent); background:var(--amber-chip); color:var(--fg-on-amber); }
.chip--danger{ border-color:color-mix(in srgb, var(--danger) 40%, transparent); background:var(--danger-surface); color:var(--fg-on-danger); }

.dot{ width:7px; height:7px; border-radius:50%; background:currentColor; flex:0 0 auto; }
.dot--live{ animation:pulse calc(2.2s / max(var(--glow-strength),.001)) ease-in-out infinite; }
@keyframes pulse{
  0%,100%{ box-shadow:0 0 0 0 rgb(var(--link-rgb) / calc(.55 * var(--glow-strength))); opacity:1; }
  50%    { box-shadow:0 0 0 5px rgb(var(--link-rgb) / 0); opacity:.55; }
}

/* ─────────────── 6. 顶部状态条（始终可见） ─────────────── */
.topbar{ width:min(1760px,100%); margin:0 auto; }
.topbar .notch-body{
  display:flex; align-items:center; gap:var(--sp-4);
  padding:10px var(--sp-4);
  background:linear-gradient(90deg, var(--surface-raise), var(--surface-1) 38%);
}
.topbar-id{ display:flex; flex-direction:column; gap:2px; flex:0 0 auto; padding-right:var(--sp-4); border-right:1px solid var(--line); }
.topbar-id h1{ font-size:var(--fs-title); line-height:var(--lh-title); }
.topbar-chips{ display:flex; flex-wrap:wrap; gap:6px; flex:1 1 auto; min-width:0; }
.topbar-actions{ display:flex; gap:var(--sp-2); flex:0 0 auto; }

/* ─────────────── 7. 状态条
   JS 写入的是长句（实测最长 52 个中文字符），装不进 chip，
   故用整行可换行的状态条，并限定最大高度内部滚动。 ─────────────── */
.status-strip{
  width:min(1760px,100%); margin:0 auto;
  display:flex; flex-wrap:wrap; gap:var(--sp-2); align-content:flex-start;
  max-height:104px; overflow-y:auto;
  padding:var(--sp-2) var(--sp-3);
  border:1px solid var(--line); border-radius:var(--r-sm);
  background:var(--surface-1);
}
.stat{
  display:inline-flex; gap:var(--sp-2); align-items:baseline;
  padding:5px 11px;
  border:1px solid var(--line-soft); border-radius:var(--r-sm);
  background:var(--surface-sunken);
  font-size:var(--fs-caption); line-height:var(--lh-caption);
}
.stat > strong{ flex:0 0 auto; color:var(--text-3); font-weight:var(--fw-medium); }
.stat > span{ color:var(--text-2); }
.stat > span.ok{ color:var(--ok); }
.stat > span.error{ color:var(--error-text); }
.stat:has(.ok){ border-color:color-mix(in srgb, var(--ok) 32%, transparent); }
.stat:has(.error){ border-color:color-mix(in srgb, var(--danger) 42%, transparent); background:#1a0d10; }

/* ─────────────── 8. 接入舱（未加入会话） ─────────────── */
.join-stage{ display:grid; place-items:center; padding:var(--sp-6) 0; position:relative; }
.join-stage::before{
  content:""; position:absolute; inset:0;
  background-image:
    linear-gradient(rgb(var(--link-rgb) / .045) 1px, transparent 1px),
    linear-gradient(90deg, rgb(var(--link-rgb) / .045) 1px, transparent 1px);
  background-size:56px 56px;
  mask-image:radial-gradient(70% 60% at 50% 45%, #000 0%, transparent 78%);
  pointer-events:none;
}
.join-pod{ width:min(600px,100%); position:relative; z-index:1; }
.join-pod > .notch-body{ padding:var(--sp-6); background:linear-gradient(168deg, var(--surface-raise) 0%, var(--surface-1) 42%, var(--surface-deep) 100%); }
.join-eyebrow{
  display:flex; align-items:center; gap:var(--sp-2); margin-bottom:var(--sp-3);
  font-family:var(--font-mono); font-size:var(--fs-caption); line-height:var(--lh-caption);
  letter-spacing:.18em; text-transform:uppercase; color:var(--link);
}
.join-eyebrow svg{ width:15px; height:15px; }
.join-eyebrow::after{ content:""; flex:1; height:1px; background:linear-gradient(90deg,var(--line-strong),transparent); }
.join-pod h1{ margin-bottom:var(--sp-2); }
.join-lede{ font-size:var(--fs-label); line-height:var(--lh-label); color:var(--text-3); margin-bottom:var(--sp-6); }
#join-form{ display:grid; gap:var(--sp-4); margin-bottom:var(--sp-4); }
#join-form label{ gap:6px; }
#join-form input{ width:100%; }
#join{ min-height:46px; font-size:var(--fs-body); line-height:var(--lh-body); }
.join-note{ margin-top:var(--sp-4); padding-top:var(--sp-4); border-top:1px solid var(--line-soft); display:grid; gap:6px; }
.join-note p{ display:flex; gap:8px; align-items:flex-start; font-size:var(--fs-caption); line-height:var(--lh-caption); color:var(--text-4); }
.join-note svg{ width:14px; height:14px; flex:0 0 auto; margin-top:3px; color:var(--link-deep); }

/* 入场动画：一次性编排 */
.rise{ opacity:0; transform:translateY(14px); animation:rise .52s var(--ease) forwards; }
@keyframes rise{ to{ opacity:1; transform:none; } }
.rise:nth-child(1){ animation-delay:.04s } .rise:nth-child(2){ animation-delay:.10s }
.rise:nth-child(3){ animation-delay:.16s } .rise:nth-child(4){ animation-delay:.22s }
.rise:nth-child(5){ animation-delay:.28s }

/* ─────────────── 9. 状态机：接入舱 ⇄ 操作台（纯 CSS，零 JS 改动）
   信号来源：app.js:467 加入成功后 leaveButton.disabled = false
             app.js:536 离开后 leaveButton.disabled = true
   不支持 :has() 的浏览器退回原始文档流（两块都显示），功能不受损。 ─────────────── */
@supports selector(:has(*)){
  .console-area{ display:none; }
  /* 用 grid 行分配而非 calc() 常量：状态条长句换行导致高度变化时，
     操作台会自动吸收剩余空间，不需要重算魔法数字。 */
  body:has(#leave:not([disabled])){
    height:100dvh; overflow:hidden;
    display:grid; grid-template-rows:auto minmax(0,1fr); gap:var(--sp-3);
  }
  body:has(#leave:not([disabled])) main{ min-height:0; grid-template-rows:auto minmax(0,1fr); }
  body:has(#leave:not([disabled])) .join-stage{ display:none; }
  body:has(#leave:not([disabled])) .console-area{ display:block; height:100%; min-height:0; }
}

/* ─────────────── 10. 双栏操作台 ─────────────── */
.expert-console{
  display:grid;
  grid-template-columns:minmax(0,1.35fr) minmax(420px,.85fr);
  gap:var(--sp-3);
  min-height:0;
  height:100%;
}
.live-column,.tool-column{
  min-width:0; min-height:0;
  display:grid; gap:var(--sp-3); align-content:start;
  padding:var(--sp-4);
  background:var(--surface-1);
  border:1px solid var(--line);
  border-radius:var(--r-md);
}
/* 左列用 flex 列而非 grid 行：grid 的 auto 行高必须在 intrinsic sizing 阶段预计算，
   而那时 .stage-inner 的 width:100% 还无法解析，行高会算错（实测 382px vs 实际 624px）；
   舞台于是溢出整行，又因为它是定位元素、绘制在非定位元素之上，把后面的行整行盖住
   ——画面模式控件就是这样"消失"的。flex 列按内容自然排布，没有这一步预计算。
   内容超出固定视口时由左列自己滚动，避免被 body{overflow:hidden} 直接裁掉。 */
.live-column{
  display:flex; flex-direction:column; gap:var(--sp-3); align-content:normal;
  overflow-y:auto;
}
/* flex 主轴默认允许收缩，会把 audio / 媒体统计压成 0 高；一律保持自然高度，
   空间不足交给上面的 overflow-y 滚动，而不是把控件压没。 */
.live-column > *{ flex-shrink:0; }
.tool-column{ grid-template-rows:auto minmax(0,1fr); }

.console-heading{ display:flex; justify-content:space-between; align-items:start; gap:var(--sp-3); }
.console-heading h2{ margin-bottom:2px; }
.console-heading p{ font-size:var(--fs-caption); line-height:var(--lh-caption); color:var(--text-4); }

.live-badge{
  display:inline-flex; align-items:center; gap:7px;
  padding:5px 11px 5px 9px;
  border:1px solid color-mix(in srgb, var(--ok) 40%, transparent);
  background:var(--ok-surface); color:var(--fg-on-ok);
  font-family:var(--font-mono); font-size:var(--fs-caption); line-height:var(--lh-caption);
  letter-spacing:.12em; white-space:nowrap;
  clip-path:polygon(0 6px,6px 0,100% 0,100% calc(100% - 6px),calc(100% - 6px) 100%,0 100%);
}

/* ─────────────── 11. 视频舞台 ─────────────── */
/* 不加边框、切角、发光或任何叠加层（2026-09-07 用户决定）：真实画面优先。
   舞台跟随真实视频比例，避免被左列剩余高度拉大；video 用 contain 保证不裁剪、
   不拉伸、不被遮盖。
   ⚠️ 比例必须落在 .stage-inner 上，不能落在 .video-stage 上：.video-stage 在 auto 行里
   吃 aspect-ratio 时，行高按内容（≈0）算，元素会溢出整行并盖住后面的行
   （它是定位元素，绘制在非定位元素之上）——画面模式控件曾因此整行不可见。
   ⚠️ 也不要给 .stage-inner 同时设 height 与 aspect-ratio——那会让宽度退化为
   "高度×比例"并左对齐，把舞台背景漏成一大块色板（r34 的实际缺陷）。
   .video-stage 仍是 app.js 写 --live-stage-offset 的目标，保留 margin-top 消费点，
   48px 上限防止切维修模式时残留偏移把画面推出视口。 */
.video-stage{
  position:relative; width:100%; flex-shrink:0;
  margin-top:min(var(--live-stage-offset, 0px), 48px);
  overflow:hidden;
  background:#000;
  border-radius:var(--r-sm);
}
/* 画面区 = 列宽 × 真实比例；padding-bottom 再把原生控件条的高度额外加到舞台底部。
   只有 width 与 aspect-ratio，没有 height —— r34 的宽度退化正是"height 与
   aspect-ratio 并存"造成的。舞台高度由这里撑开，grid 行高才与实际一致。 */
.stage-inner{
  position:relative; width:100%;
  box-sizing:content-box;
  aspect-ratio:var(--remote-frame-aspect);
  padding-bottom:var(--video-controls-reserve);
  background:#000;
}
/* 绝对定位让 video 填满 .stage-inner 的 padding box（含底部预留区）；
   object-position:top 把画面顶到上沿，控件条落在预留区里，不再压住画面。
   去掉 object-position 画面会居中，控件条重新压住画面底边。 */
video{ position:absolute; inset:0; display:block; width:100%; height:100%;
       background:#000; object-fit:contain; object-position:top; }
audio{ width:100%; height:34px; }

/* 专家端独占画面选择。它只改变专家观看的编码源表现，不属于维修动作通道。 */
.video-mode-control{
  display:flex; flex-wrap:wrap; align-items:center; gap:var(--sp-2);
  padding:8px 10px; background:var(--surface-sunken);
  border:1px solid var(--line-soft); border-radius:var(--r-sm);
}
.video-mode-label{ color:var(--text-3); font-size:var(--fs-caption); line-height:var(--lh-caption); white-space:nowrap; }
.video-mode-control button{ min-height:32px; padding:5px 11px; font-size:var(--fs-caption); }
.video-mode-status{ flex:1 1 12em; color:var(--text-4); font-size:var(--fs-caption); line-height:var(--lh-caption); }
.video-mode-status.ok{ color:var(--fg-on-ok); }
.video-mode-status.error{ color:var(--fg-on-danger); }

/* 媒体统计：等宽 + tabular-nums，刷新不抖 */
#media-stats{
  max-height:4.6em; overflow:auto; margin:0; padding:9px 11px;
  white-space:pre-wrap; color:var(--text-3);
  background:var(--surface-sunken);
  border:1px solid var(--line-soft); border-radius:var(--r-sm);
  font-family:var(--font-mono); font-size:var(--fs-mono); line-height:var(--lh-mono);
  font-variant-numeric:tabular-nums;
}

/* 事件抽屉：浮层玻璃 */
.event-drawer{
  padding:10px var(--sp-3);
  border:1px solid var(--line); border-radius:var(--r-sm);
  background:var(--glass-drawer);
  backdrop-filter:blur(9px);
}
.event-drawer summary{
  cursor:pointer; list-style:none; display:flex; align-items:center; gap:8px;
  font-size:var(--fs-caption); line-height:var(--lh-caption); color:var(--link); letter-spacing:.04em;
}
.event-drawer summary::-webkit-details-marker{ display:none; }
.event-drawer summary svg{ width:13px; height:13px; transition:transform var(--dur-ui) var(--ease); }
.event-drawer[open] summary svg.chev{ transform:rotate(90deg); }
#remote-event-log{
  min-height:66px; max-height:118px; overflow:auto; margin:9px 0 0; padding:9px 10px;
  white-space:pre-wrap; color:var(--text-3);
  background:var(--surface-3); border:1px solid var(--line-soft); border-radius:var(--r-xs);
  font-family:var(--font-mono); font-size:var(--fs-mono); line-height:var(--lh-mono);
  font-variant-numeric:tabular-nums;
}
#remote-event-log.ok{ color:var(--ok); }
#remote-event-log.error{ color:var(--error-text); }

/* ─────────────── 12. 右列：双模式切换（纯 CSS，radio 驱动） ─────────────── */
.mode-switch{ display:grid; grid-template-columns:1fr 1fr; gap:1px; padding:1px; background:var(--line); border-radius:var(--r-sm); overflow:hidden; }
.mode-radio{ position:absolute; width:1px; height:1px; opacity:0; pointer-events:none; }
.mode-label{
  display:flex; align-items:center; justify-content:center; gap:7px;
  min-height:44px; padding:6px 8px;
  background:var(--surface-2); color:var(--text-3);
  font-size:var(--fs-label); line-height:var(--lh-label); cursor:pointer;
  transition:background-color var(--dur-state) var(--ease), color var(--dur-state) var(--ease);
}
.mode-label svg{ width:15px; height:15px; }
.mode-label:hover{ background:var(--surface-hover); color:var(--text-1); }
.mode-radio:focus-visible + .mode-label{ box-shadow:inset 0 0 0 2px var(--link); }
.mode-radio:checked + .mode-label.m-annotate{ background:var(--link-surface); color:var(--btn-label); box-shadow:inset 0 -2px 0 var(--link); }
.mode-radio:checked + .mode-label.m-repair{ background:var(--amber-surface); color:var(--fg-amber); box-shadow:inset 0 -2px 0 var(--amber); }
.mode-radio:checked + .mode-label.m-repair:hover{ background:var(--amber-hover); color:var(--fg-amber-hi); }
.tool-column-head{ display:grid; gap:var(--sp-2); align-content:start; }
.mode-panes{ min-height:0; display:grid; gap:var(--sp-3); align-content:start; }
.mode-pane{ min-height:0; }
.mode-pane-annotate{ display:grid; grid-template-rows:auto minmax(0,1fr); gap:var(--sp-3); }
.mode-pane-repair{ display:grid; grid-template-rows:minmax(0,1fr); overflow:auto; align-content:start; }
@supports selector(:has(*)){
  .mode-pane-repair{ display:none; }
  body:has(#expert-mode-repair:checked) .mode-pane-annotate{ display:none; }
  body:has(#expert-mode-repair:checked) .mode-pane-repair{ display:grid; }
}

/* 标注模式内三 tab：层级低于模式切换，视觉必须更弱 */
.expert-tool-tabs{ display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--sp-1); }
.expert-tool-tab{
  min-height:38px; padding:6px 8px;
  background:transparent; border:1px solid transparent; border-radius:var(--r-sm);
  color:var(--text-3); font-size:var(--fs-label); line-height:var(--lh-label); font-weight:var(--fw-regular);
}
.expert-tool-tab:hover:not(:disabled){ background:var(--surface-2); border-color:var(--line-soft); color:var(--text-1); }
.expert-tool-tab.active{ background:var(--link-surface); border-color:var(--link); color:var(--btn-label); font-weight:var(--fw-medium); }
.expert-tool-tab.active:hover{ background:var(--surface-active); border-color:var(--link); color:var(--btn-label); }

.expert-tool-content{ min-height:0; overflow:auto; display:grid; align-content:start; }
.expert-tool-panel{ display:none; gap:var(--sp-3); align-content:start; min-width:0; }
.expert-tool-panel.active{ display:grid; }

.tool-panel-heading{ display:grid; align-content:start; gap:2px; }
.tool-panel-heading h3{ margin:0; }

.tool-workspace-stage{
  position:relative; width:100%; min-height:170px;
  display:grid; place-items:center;
  aspect-ratio:var(--remote-frame-aspect);
  overflow:hidden; background:var(--surface-3);
  border:1px solid var(--line-strong); border-radius:var(--r-sm);
}
#annotation-canvas,#spatial-point-canvas{
  display:block; width:100%; height:100%; max-height:none;
  object-fit:contain; touch-action:none; cursor:crosshair;
}
#annotation-canvas[hidden],#spatial-point-canvas[hidden],#spatial-frame-placeholder[hidden]{ display:none; }
#annotation-placeholder,#spatial-frame-placeholder{ padding:var(--sp-4); text-align:center; color:var(--text-4); font-size:var(--fs-label); line-height:var(--lh-label); }

.tool-panel-footer{ display:grid; gap:var(--sp-2); padding-top:var(--sp-3); border-top:1px solid var(--line-soft); }
.annotation-tools,.spatial-point-tools,.maintenance-command-tools,.text-send-row,.annotation-send-row{
  display:flex; flex-wrap:wrap; gap:var(--sp-2); align-items:center;
}
.annotation-tools > button,.spatial-point-tools > button{ min-height:38px; }
.annotation-tools label,.spatial-point-tools label,.maintenance-command-tools label{
  display:flex; flex-direction:row; align-items:center; gap:6px;
  padding:4px 9px 4px 5px;
  border:1px solid var(--line-strong); border-radius:var(--r-sm);
  background:var(--surface-2);
  font-size:var(--fs-caption); line-height:var(--lh-caption); color:var(--text-3);
}
.annotation-tools input[type="color"],.spatial-point-tools input[type="color"],.maintenance-command-tools input[type="color"]{
  width:40px; height:30px; padding:2px; border-radius:var(--r-xs); cursor:pointer;
}
.annotation-tools input[type="color"]:disabled,.spatial-point-tools input[type="color"]:disabled{ cursor:not-allowed; }

/* 工具分段容器：把绘制工具收进一个视觉组，降低工具条噪声。
   注意 .tool / .spatial-tool 类名与父子关系是 JS 选择器，不得改动。 */
.tool-seg{ display:flex; gap:var(--sp-1); padding:3px; background:var(--surface-2); border:1px solid var(--line-soft); border-radius:var(--r-sm); }
.tool-seg button{ min-height:32px; padding:5px 11px; border-radius:var(--r-xs); background:transparent; color:var(--text-3); font-size:var(--fs-caption); line-height:var(--lh-caption); }
.tool-seg button:hover:not(:disabled){ background:var(--surface-hover); color:var(--text-1); }
.tool-seg button.active{ background:var(--link-surface); color:var(--btn-label); box-shadow:inset 0 0 0 1px var(--link); }
.tool-seg button.active:hover:not(:disabled){ background:var(--surface-active); color:var(--btn-label); }
.tool-seg button:disabled{ background:transparent; color:var(--text-disabled); }
.tool-spacer{ flex:1 1 auto; }

.description-label{ margin-top:2px; }
.text-instruction-stage{ padding:var(--sp-3); }
.text-instruction-stage textarea{ height:100%; min-height:150px; resize:none; background:var(--surface-3); }

/* 状态行：ok / error 由 app.js setState() 切换 */
#annotation-status,#spatial-point-status,#text-instruction-status,#maintenance-command-status{ font-size:var(--fs-caption); line-height:var(--lh-caption); color:var(--text-4); }
#annotation-status.ok,#spatial-point-status.ok,#text-instruction-status.ok,#maintenance-command-status.ok{ color:var(--ok); }
#annotation-status.error,#spatial-point-status.error,#text-instruction-status.error,#maintenance-command-status.error{ color:var(--error-text); }
.spatial-point-status-row{ align-items:center; gap:var(--sp-2); }

/* ─────────────── 13. 维修协同模式（琥珀通道） ─────────────── */
.repair-workspace{ display:grid; gap:var(--sp-3); align-content:start; min-width:0; }
.repair-workspace-heading{ display:flex; justify-content:space-between; align-items:start; gap:var(--sp-3); padding:var(--sp-3); border-left:3px solid var(--amber); border-radius:var(--r-xs); background:var(--surface-sunken); }
.repair-workspace-heading h2{ margin-bottom:3px; }
.repair-workspace-heading p{ font-size:var(--fs-caption); line-height:var(--lh-caption); color:var(--text-4); }

.maintenance-command-status{
  display:grid; gap:6px; padding:9px 11px;
  border-left:3px solid var(--amber-deep); border-radius:var(--r-xs);
  background:var(--surface-sunken);
  font-size:var(--fs-caption); line-height:var(--lh-caption); color:var(--text-3);
}

/* 维修区并入右列后宽度收窄，模型与操作面板改为纵向堆叠 */
.device-model-operator{ display:grid; grid-template-columns:minmax(0,1fr); gap:var(--sp-3); align-content:start; min-width:0; }
.device-model-pane,.device-operation-pane{ min-width:0; display:grid; gap:var(--sp-2); align-content:start; }

.device-model-toolbar{
  display:flex; flex-wrap:wrap; gap:var(--sp-2); align-items:center; justify-content:space-between;
  padding:8px 11px;
  border:1px solid var(--line); border-radius:var(--r-sm); background:var(--surface-1);
}
.device-model-toolbar label{ display:flex; flex-direction:row; align-items:center; gap:6px; padding:0; border:0; background:transparent; font-size:var(--fs-caption); line-height:var(--lh-caption); color:var(--text-3); }
.device-model-toolbar input[type="checkbox"]{ width:auto; accent-color:var(--amber); }
.device-model-toolbar span{ font-size:var(--fs-caption); line-height:var(--lh-caption); color:var(--text-4); }
#device-model-status{ font-family:var(--font-mono); font-variant-numeric:tabular-nums; }

.device-focus-badge{
  padding:4px 10px;
  border:1px solid color-mix(in srgb, var(--ok) 45%, transparent);
  border-radius:var(--r-pill);
  background:var(--ok-surface);
  color:var(--fg-on-ok);
  font-size:var(--fs-caption); line-height:var(--lh-caption); white-space:nowrap;
}

.device-model-viewport{
  position:relative; height:clamp(300px,32vh,420px); min-height:300px; overflow:hidden;
  background:radial-gradient(ellipse 70% 60% at 50% 42%, #12293c 0%, #07111d 72%);
  border:1px solid var(--line-strong);
  clip-path:var(--notch-clip);
  touch-action:none;
}
/* 画布宿主只承载 three.js canvas；浮层是它的兄弟节点，
   因此 operator 构造器的 replaceChildren() 不会摘除浮层。 */
.device-model-canvas{ position:absolute; inset:0; }
.device-model-canvas canvas{ display:block; width:100%; height:100%; cursor:grab; }
.device-model-canvas canvas:active{ cursor:grabbing; }
.device-model-operator.model-view-locked .device-model-canvas canvas{ cursor:default; }

/* 浮层：玻璃质感仅在此层使用 */
.device-view-help{
  position:absolute; top:12px; right:12px; z-index:5;
  width:min(272px,calc(100% - 24px)); padding:11px;
  border:1px solid color-mix(in srgb, var(--link) 45%, transparent);
  border-radius:var(--r-sm);
  background:var(--glass-overlay);
  backdrop-filter:blur(11px);
  box-shadow:var(--shadow-float);
  color:var(--text-2);
}
.device-view-help[hidden]{ display:none; }
.device-view-help-heading{ display:flex; align-items:center; justify-content:space-between; gap:var(--sp-2); }
.device-view-help-heading strong{ color:var(--text-1); font-size:var(--fs-caption); line-height:var(--lh-caption); letter-spacing:.06em; }
.device-view-help-heading button{ min-width:30px; min-height:30px; padding:2px 8px; background:var(--surface-raise); border-radius:var(--r-xs); }
.device-view-help p{ margin:8px 0 10px; color:var(--text-3); font-size:var(--fs-caption); line-height:var(--lh-caption); }
.device-view-actions{ display:grid; grid-template-columns:40px 1fr 40px; gap:6px; }
.device-view-actions button{ min-height:32px; padding:4px 8px; }

.device-removal-zone{
  position:absolute; right:12px; bottom:12px; z-index:4;
  display:grid; gap:5px; width:min(206px,calc(100% - 24px)); padding:9px 11px;
  border:1px dashed var(--amber-deep); border-radius:var(--r-sm);
  background:color-mix(in srgb, var(--amber-chip) 78%, transparent);
  backdrop-filter:blur(9px);
  color:var(--fg-amber); pointer-events:none;
}
.device-removal-zone strong{ font-size:var(--fs-caption); line-height:var(--lh-caption); letter-spacing:.04em; }
.device-removal-zone > span{ color:color-mix(in srgb, var(--fg-amber) 68%, transparent); font-size:var(--fs-caption); line-height:var(--lh-caption); }
.device-removal-zone #device-removed-parts{ display:flex; flex-wrap:wrap; gap:var(--sp-1); min-height:22px; }
/* .device-removed-part 由 device-model-operator.js:2113 动态创建，类名不得改 */
.device-removed-part{
  padding:3px 9px;
  border:1px solid var(--amber-deep); border-radius:var(--r-pill);
  background:var(--amber-chip); color:var(--fg-on-amber);
  font-family:var(--font-mono); font-size:var(--fs-caption); line-height:var(--lh-caption);
}

.device-screw-labels{ position:absolute; inset:0; pointer-events:none; }
/* .device-part-number 由 device-model-operator.js:1260 动态创建，类名不得改。
   容器 22px→24px 是为容纳 13px 下限字号。 */
.device-part-number{
  position:absolute; display:grid; place-items:center;
  width:24px; height:24px;
  border:1px solid var(--fg-on-link); border-radius:50%;
  background:color-mix(in srgb, var(--link-deep) 62%, transparent);
  color:var(--btn-label);
  font-family:var(--font-mono); font-size:var(--fs-caption); line-height:1; font-weight:600;
  font-variant-numeric:tabular-nums;
  transform:translate(-50%,-50%);
  box-shadow:0 2px 8px #000b;
}

.device-selection-status{
  min-height:2.8em; margin:0; padding:9px 11px;
  border-left:3px solid var(--amber-deep); border-radius:var(--r-xs);
  background:var(--surface-sunken);
  color:var(--text-3); font-size:var(--fs-caption); line-height:var(--lh-caption);
}

.device-operation-pane{ padding:var(--sp-3); border:1px solid var(--line); border-radius:var(--r-sm); background:var(--surface-1); }
.device-operation-pane > h3{ margin:0; }

.device-interaction-card{
  display:grid; gap:var(--sp-3); margin:0; padding:var(--sp-3);
  border:1px solid color-mix(in srgb, var(--amber) 32%, transparent);
  border-radius:var(--r-sm);
  background:linear-gradient(150deg, #1a2c3c, #101d2a 58%);
}
.device-interaction-heading{ display:flex; justify-content:space-between; align-items:start; gap:var(--sp-3); }
.device-interaction-heading h3{ margin:0 0 3px; }
.device-interaction-heading p{ max-width:44em; font-size:var(--fs-caption); line-height:var(--lh-caption); color:var(--text-4); }
.device-interaction-card .tool-help{ min-height:2.8em; }

.device-mode-badge{
  flex:0 0 auto; padding:4px 10px;
  border:1px solid #6f86a4; border-radius:var(--r-pill);
  color:var(--text-3); font-size:var(--fs-caption); line-height:var(--lh-caption); white-space:nowrap;
}
.device-mode-badge.active{ border-color:var(--ok); background:var(--ok-surface); color:var(--fg-on-ok); }
.device-mode-badge.local{ border-color:var(--warn); background:#65471b; color:#fff0c9; }

/* 步骤列表：琥珀通道，done / active 由 JS classList.toggle 切换 */
.device-step-list{ display:grid; gap:6px; }
.device-step-list button{
  justify-content:flex-start; gap:9px; width:100%;
  min-height:40px; padding:7px 11px; text-align:left;
  border:1px solid var(--line-strong); border-radius:var(--r-sm);
  background:var(--surface-2); color:var(--text-3);
  font-size:var(--fs-label); line-height:var(--lh-label); font-weight:var(--fw-regular);
}
.device-step-list button:hover:not(:disabled){ background:var(--amber-surface); border-color:var(--amber-deep); color:var(--fg-amber); }
.device-step-list button.active{ background:var(--amber-surface); border-color:var(--amber); color:var(--fg-amber-hi); font-weight:var(--fw-medium); box-shadow:inset 3px 0 0 var(--amber); }
.device-step-list button.done{ background:var(--ok-surface); border-color:#54d6aa; color:var(--fg-on-ok); }
.device-step-list button:disabled{ background:var(--btn-disabled); border-color:var(--line-soft); color:var(--text-disabled); }

.device-tool-picker,.device-interaction-actions{ display:flex; flex-wrap:wrap; gap:var(--sp-2); }
.device-interaction-actions button{ flex:1 1 12em; }
/* .device-tool-button 与 #device-local-demo 目前无对应 HTML 实体（功能已下线），
   但 JS 仍保留 dataset.deviceTool 与 local 状态分支，故样式保留为休眠规则，不清理。 */
.device-tool-button{ flex:1 1 9em; min-height:40px; padding:7px 10px; }
.device-tool-button.active{ border-color:var(--fg-on-link); box-shadow:0 0 0 2px rgb(var(--link-rgb) / .40) inset; }
.device-interaction-actions button#device-local-demo{ border-color:#8b6a32; background:#4b3618; }
.device-interaction-actions button#device-local-demo.active{ border-color:#ffd477; background:#75511c; color:#fff4d0; }
.device-model-operator.interaction-active .device-operation-row{ display:none; }
.device-operation-row,.device-highlight-row{ display:flex; flex-wrap:wrap; gap:var(--sp-2); align-items:center; }
.device-highlight-row label{ display:flex; flex-direction:row; align-items:center; gap:6px; font-size:var(--fs-caption); line-height:var(--lh-caption); }

/* 部件列表：容器为空，子按钮由 device-model-operator.js:2067 动态创建 */
.device-part-list{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:6px; }
.device-part-button{
  min-height:42px; padding:7px 10px; justify-content:flex-start; text-align:left;
  font-size:var(--fs-label); line-height:var(--lh-label); font-weight:var(--fw-regular);
  background:var(--surface-2); border-color:var(--line-strong); color:var(--text-3);
}
.device-part-button:hover:not(:disabled){ background:var(--amber-surface); border-color:var(--amber-deep); color:var(--fg-amber); }
.device-highlight-select-button{ cursor:pointer; user-select:none; }
.device-part-button.selected{
  background:var(--amber-surface); border-color:var(--amber); color:var(--fg-amber-hi);
  font-weight:var(--fw-medium);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--amber) 45%, transparent);
}
.device-part-button.selected:hover:not(:disabled){ background:var(--amber-hover); color:var(--fg-amber-max); }

.device-highlight-card{ display:grid; gap:var(--sp-2); margin:2px 0 0; padding:var(--sp-3); border:1px solid var(--line); border-radius:var(--r-sm); background:var(--surface-sunken); }
.device-highlight-card h3{ margin:0; }
.device-highlight-demo-actions{ display:flex; flex-wrap:wrap; gap:var(--sp-2); }
.device-highlight-demo-actions button{ flex:1 1 10em; }
.device-highlight-color-control{
  display:flex; flex:0 1 12em; flex-direction:row; align-items:center; justify-content:space-between; gap:7px;
  min-height:40px; padding:5px 9px;
  border:1px solid var(--line-strong); border-radius:var(--r-sm);
  background:var(--surface-2); color:var(--text-3);
  font-size:var(--fs-caption); line-height:var(--lh-caption);
}
.device-highlight-color-control input[type="color"]{ width:40px; height:30px; padding:2px; border:1px solid var(--line-strong); border-radius:var(--r-xs); background:transparent; cursor:pointer; }

/* ─────────────── 14. 滚动条 ─────────────── */
.status-strip::-webkit-scrollbar,.expert-tool-content::-webkit-scrollbar,#remote-event-log::-webkit-scrollbar,#media-stats::-webkit-scrollbar{ width:9px; height:9px; }
.status-strip::-webkit-scrollbar-thumb,.expert-tool-content::-webkit-scrollbar-thumb,#remote-event-log::-webkit-scrollbar-thumb,#media-stats::-webkit-scrollbar-thumb{
  background:var(--thumb); border-radius:99px; border:2px solid transparent; background-clip:padding-box;
}
.status-strip::-webkit-scrollbar-track,.expert-tool-content::-webkit-scrollbar-track,#remote-event-log::-webkit-scrollbar-track,#media-stats::-webkit-scrollbar-track{ background:transparent; }

/* ─────────────── 15. 响应式
   断点必须与 app.js:43 的 matchMedia('(min-width:1051px)') 保持一致 ─────────────── */
@media (max-width: 1050px){
  body{ padding:10px; }
  @supports selector(:has(*)){
    body:has(#leave:not([disabled])){ height:auto; overflow:auto; }
    body:has(#leave:not([disabled])) main{ height:auto; }
  }
  .expert-console{ grid-template-columns:minmax(0,1fr); height:auto; }
  .live-column,.tool-column{ min-height:0; }
  .live-column{ grid-template-rows:auto auto auto auto auto; }
  .video-stage{ min-height:220px; }
  .device-model-viewport{ height:380px; }
  .topbar .notch-body{ flex-wrap:wrap; }
  .topbar-id{ padding-right:0; border-right:0; }
}
@media (max-width: 640px){
  .expert-tool-tabs{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .device-model-viewport{ height:300px; min-height:300px; }
  .device-part-list{ grid-template-columns:minmax(0,1fr); }
  .mode-switch{ grid-template-columns:minmax(0,1fr); }
  .status-strip{ max-height:none; }
}
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
  }
}

/* 云端档案：覆盖协同工具区，左侧直播与语音继续运行。 */
.console-area{ position:relative; }
.archive-view[hidden],.archive-timeline[hidden],.archive-photos[hidden]{ display:none; }
.archive-view{
  position:absolute; z-index:20; inset:0 0 0 34%;
  display:flex; flex-direction:column; gap:12px; min-height:0;
  padding:18px; overflow:hidden; background:var(--surface-1);
  border:1px solid var(--line-strong); border-radius:var(--r-md);
  box-shadow:-12px 0 30px #0009;
}
.archive-heading,.archive-view-actions,.archive-pages{ display:flex; align-items:center; justify-content:space-between; gap:10px; }
.archive-heading h2,.archive-list-pane h3,.archive-timeline h3{ margin:0; }
.archive-heading p,.archive-status,.archive-muted{ color:var(--text-3); font-size:var(--fs-caption); }
.archive-heading p{ margin:4px 0 0; }
.archive-status{ min-height:20px; margin:0; }
.archive-layout{ display:grid; grid-template-columns:minmax(210px,32%) minmax(0,1fr); gap:12px; flex:1; min-height:0; }
.archive-list-pane,.archive-main-pane{ min-height:0; overflow:auto; padding:14px; background:var(--surface-2); border:1px solid var(--line); border-radius:var(--r-sm); }
.archive-list-pane{ display:flex; flex-direction:column; gap:10px; }
.archive-list{ display:flex; flex-direction:column; gap:8px; flex:1; overflow:auto; }
.archive-list button{ display:block; width:100%; text-align:left; padding:10px; background:var(--surface-1); border:1px solid var(--line); }
.archive-list button.selected{ border-color:var(--link); background:var(--link-surface); }
.archive-list button strong,.archive-list button span{ display:block; }
.archive-list button span{ margin-top:4px; font-size:var(--fs-caption); color:var(--text-3); }
.archive-pages button{ padding:5px 8px; min-height:32px; }
.archive-pages{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); }
.archive-pages button{ white-space:nowrap; }
.archive-pages span{ grid-column:1/-1; grid-row:1; text-align:center; white-space:nowrap; font-size:var(--fs-caption); }
.archive-main-pane{ background:var(--surface-1); }
.archive-preview h3{ margin:0 0 14px; }
.archive-preview dl{ display:grid; grid-template-columns:100px minmax(0,1fr); gap:8px 12px; }
.archive-preview dt{ color:var(--text-3); }.archive-preview dd{ margin:0; overflow-wrap:anywhere; }
.archive-preview-actions{ display:flex; flex-wrap:wrap; gap:10px; margin-top:18px; }
.archive-events{ display:flex; flex-direction:column; gap:8px; margin-top:12px; }
.archive-event{ padding:10px; border-left:3px solid var(--link); background:var(--surface-2); }
.archive-event strong,.archive-event span{ display:block; }
.archive-event span{ color:var(--text-3); font-size:var(--fs-caption); margin-top:4px; }
.archive-event p{ margin:6px 0; white-space:pre-wrap; overflow-wrap:anywhere; }
.archive-photo-list{ display:grid; gap:12px; margin-top:12px; }
.archive-photo-list img{ max-width:100%; max-height:55vh; object-fit:contain; justify-self:center; }
@media (max-width:1050px){ .archive-view{ position:fixed; inset:12px; } }
@media (max-width:760px){
  .archive-layout{ grid-template-columns:1fr; grid-template-rows:auto minmax(260px,1fr); overflow:auto; }
  .archive-list-pane{ max-height:none; }
  .archive-list{ flex:0 0 auto; max-height:34vh; }
  .archive-view{ overflow:auto; }
}
