/**
 * MythosX Anvil 使用教程 · 首屏连接拓扑舞台的样式（gt- 前缀，只作用于 .gt-stage 内部）。
 *
 * 业务定位：硬件是离线渲染的透明 WebP 图层（不在这里画），topology.js 只搭结构、切类名；
 * 图层淡入、方式切换、插卡入场、线缆描出、流动光点、标注、联动高亮的节奏全部在这里，改动效不用动脚本。
 * 颜色一律取 mx.css 的令牌：唯一的彩色是 --accent，只用在流动光点、在用端口的暖光和高亮部件的描光上；
 * 标注（编号圈、引线、文字）一律中性，不发光、无阴影、无渐变底（控件规范 v2）。
 *
 * 动效规则（架构 §7，Owner 11-10 要求放慢）：只用不过冲的曲线；入场约 4 秒、切换约 1.4 秒，动作之间留停顿；联动高亮仍是 200ms；入场一次；视口外或页面隐藏时 .is-paused 停掉循环；
 * prefers-reduced-motion: reduce 时取消入场、流动和全部过渡。
 */

/* 挂载点尺寸归页面（16:10 / 4:5）；舞台铺满它，每个场景（构图）里主图、覆盖层、标注层三层叠放 */
.gt-mount { position: relative; }
/* overflow: hidden：拉远 / 推近时场景会放大到舞台外（见下），越出的部分裁掉；转台放到整帧时也靠它裁 */
.gt-stage { position: absolute; inset: 0; overflow: hidden; --gt-k: 2; }

/* 场景：没声明跨房间专用构图时只有一个；声明了时两个场景叠放，切到 / 切走跨房间时像同一台相机拉远看两个房间、切回时推近。
   两个变换由脚本算（zoomOf，优先按 anchors 的 zoomFrom 精确对位）：共用构图（.gt-base）离场时套 --gt-away（缩小平移到和专用构图同一相机），
   专用构图离场时套 --gt-near（放大到和共用构图同一相机，是 away 的逆）。两个场景同一拍、同一条曲线、同样时长地变换，
   任何一帧目标机和卡都重合，交叉淡时没有重影。算不出对位时两个变换都是 none，只交叉淡。离场的场景过渡完 visibility: hidden，不再绘制。
   拉远（data-xf="out"，去跨房间）：.05s 起 .8s 两个场景一起缩（同房间的调试机和旧线这时也在淡出、收回），
     接近到位时 .65–.9s 交叉淡（专用构图这时放大不到 3%，羽化带还在舞台内）；随后专用构图里交换机依次出现、1.1s 起描线。
   推近（data-xf="in"，回同房间）：跨房间的线先收（.35s），.35–.65s 交叉淡到已对位好的共用构图，.55s 起 .8s 两个场景一起推近，.8s 起描新线。
   曲线对称缓入缓出、不过冲 */
.gt-scene {
  position: absolute; inset: 0; transform-origin: 0 0; visibility: visible;
  transition: opacity .35s var(--ease), visibility 0s;
}
.gt-scene:not(.is-cur) { opacity: 0; visibility: hidden; transition: opacity .35s var(--ease), visibility 0s linear .35s; }
.gt-scene.gt-base:not(.is-cur) { transform: var(--gt-away, none); }
.gt-scene:not(.gt-base):not(.is-cur) { transform: var(--gt-near, none); }
.gt-stage[data-xf="out"] .gt-scene.gt-base:not(.is-cur) { transition: transform .8s var(--gt-draw) .05s, opacity .25s var(--ease) .65s, visibility 0s linear .9s; }
.gt-stage[data-xf="out"] .gt-scene.is-cur { transition: transform .8s var(--gt-draw) .05s, opacity .25s var(--ease) .65s, visibility 0s; }
.gt-stage[data-xf="in"] .gt-scene:not(.is-cur) { transition: transform .8s var(--gt-draw) .55s, opacity .3s var(--ease) .35s, visibility 0s linear .65s; }
.gt-stage[data-xf="in"] .gt-scene.gt-base.is-cur { transition: opacity .3s var(--ease) .35s, transform .8s var(--gt-draw) .55s, visibility 0s; }
.gt-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: hidden; user-select: none; -webkit-user-select: none; }
/* 四边羽化：图层和覆盖层在舞台四边各 8% 内渐隐到透明，任何东西碰到舞台边缘都是淡出、不是被切断，
   舞台和页面之间没有可见边界（Owner 11-10「场景和背景融入的不和谐」）。标注是 HTML 层，不加这层蒙版，字不会被淡掉 */
.gt-svg {
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent), linear-gradient(180deg, transparent, #000 8%, #000 92%, transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent), linear-gradient(180deg, transparent, #000 8%, #000 92%, transparent);
  mask-composite: intersect;
}
/* 覆盖层（流动光点、端口暖光）单独成一个合成层：循环动画只重画这一小张，渲染图层不跟着每帧重画 */
.gt-over { pointer-events: none; will-change: transform; }


/* 图层：加载完成才淡入（失败的那层一直不显示，不出破图） */
.gt-svg .gt-img { opacity: 0; transition: opacity .4s var(--ease), filter .2s var(--ease); }
.gt-svg .gt-img.is-loaded { opacity: 1; }

/* 线缆描出 ----------------------------------------------------------------
   每种方式一个蒙版：粗白线沿 paths 从卡端口描到对端，描完后整块白底淡入，蒙版不再裁掉线缆的落地阴影。
   时长由脚本按段数写入（Owner 11-10：「动画有点太快了，应该慢一点让客户看清」）：
     --len 折线长度；--sd / --sdl 切换时这一段的时长与起点（单段 .5s；经交换机两段各 .3s，依次）；
     --ed / --edl 入场时这一段的时长与起点（单段 1.2s；经交换机两段各 .9s，依次）；
     路线组上的 --fd / --fe 是切换 / 入场时线描完的时刻，白底、光点和端口暖光从这时出现。
   切走时白底先收、白线 .35s 退回卡端口；新线要等旧线收完、新卡插到底以后才描（分拍，不同时进行）。
   描线用对称的缓入缓出（无回弹）：匀速感更强，客户看得清线从哪里走到哪里 */
.gt-stage { --gt-draw: cubic-bezier(.45, 0, .25, 1); }
.gt-svg .gt-mfill { fill: #fff; opacity: 0; transition: opacity .15s var(--ease); }
.gt-svg .gt-mpath {
  fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: var(--len) var(--len); stroke-dashoffset: var(--len);
  transition: stroke-dashoffset .35s var(--ease);
}
.gt-svg .gt-mroute.is-on .gt-mpath { stroke-dashoffset: 0; transition: stroke-dashoffset var(--sd) var(--gt-draw) var(--sdl); }
.gt-svg .gt-mroute.is-on .gt-mfill { opacity: 1; transition: opacity .25s var(--ease) calc(var(--fd) - .1s); }
/* 光猫接外网的那段光纤（跨房间的 paths.uplink）只做静态：不描、不跑光点，随光猫和主交换机一起淡入（.6s，入场 2.05s）、一起淡出 */
.gt-svg .gt-mup { fill: none; stroke: #fff; stroke-linecap: round; stroke-linejoin: round; opacity: 0; transition: opacity .35s var(--ease) .4s; }
.gt-svg .gt-mroute.is-on .gt-mup { opacity: 1; transition: opacity .4s var(--ease) .6s; }
/* 光点用线缆图层的透明度当蒙版：线被别的物体挡住的那段，光点也看不见 */
.gt-svg .gt-amask { mask-type: alpha; }

/* 流动光点与端口暖光：只在当前方式上跑，线描完才出现；正向亮、反向暗一半。
   速度是上一版的约 0.6 倍、间距更大（更稀、更慢）：每 9.8 秒走 220 个画布像素 */
.gt-svg .gt-flow { opacity: 0; transition: opacity .2s var(--ease); }
.gt-svg .gt-route.is-on .gt-flow { opacity: 1; transition: opacity .25s var(--ease) calc(var(--fd) - .1s); }
.gt-svg .gt-dots {
  fill: none; stroke: var(--accent); stroke-linecap: round; stroke-width: calc(3.4px * var(--gt-k));
  stroke-dasharray: 0 220px; animation: gt-flow 9.8s linear infinite;
}
.gt-svg .gt-dots-r { stroke-width: calc(2.4px * var(--gt-k)); opacity: .5; animation-name: gt-flow-r; }
.gt-svg .gt-g0 { stop-color: var(--accent); stop-opacity: .6; }
.gt-svg .gt-g1 { stop-color: var(--accent); stop-opacity: 0; }
.gt-svg .gt-glow { animation: gt-glow 3.6s ease-in-out infinite alternate; }
.gt-svg .gt-route:not(.is-on) .gt-dots, .gt-svg .gt-route:not(.is-on) .gt-glow { animation: none; }
@keyframes gt-flow { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -220px; } }
@keyframes gt-flow-r { from { stroke-dashoffset: 110px; } to { stroke-dashoffset: 330px; } }
@keyframes gt-glow { from { opacity: .35; } to { opacity: 1; } }

/* 方式切换（约 1.4 秒，分拍进行，不同时）-----------------------------------
   0–.35s 旧线退回卡端口、旧光点收掉 → .2–.5s 旧卡沿插槽方向（insert 位移的 60%）退出、.18s 内就淡掉 → .5–.9s 新卡滑入插到底，
   不透明度晚 .12s 才起（卡层被机箱挡住的挖空跟着卡平移，位移大的那几帧让它基本透明，看不出直边缺口）
   → .8s 起新线描出（单段 .5s，经交换机两段各 .3s）→ 线描完前 .1s 白底、光点和端口暖光淡入（.25s）。
   只换接法不换卡时卡不动；交换机在旧线收完后升起（.45s 起）、切走时随旧线下沉，位移不超过 8 个画布像素；
   副标和端口小字随新线出现（.8s 起）交叉淡入 */
.gt-svg .gt-card { transform: var(--gt-out); opacity: 0; transition: transform .3s var(--ease) .2s, opacity .18s var(--ease) .2s; }
.gt-svg .gt-card.is-on { transform: none; opacity: 1; transition: transform .4s var(--ease) .5s, opacity .25s var(--ease) .62s; }
.gt-svg .gt-sw { opacity: 0; transform: translateY(8px); transition: opacity .35s var(--ease) .05s, transform .35s var(--ease) .05s; }
.gt-svg .gt-sw.is-on { opacity: 1; transform: none; transition: opacity .4s var(--ease) .45s, transform .4s var(--ease) .45s; }
/* 跨房间：房间、三台交换机、另一个房间的调试机依次淡入（--ri），切走时按相反顺序淡出（--ro），延迟由脚本写入；
   同房间的调试机（.gt-rmx）在切到跨房间时 .1s 起淡出，切回来 .5s 起淡入，赶在新线描到它之前到场 */
.gt-svg .gt-rm { opacity: 0; transition: opacity .35s var(--ease) var(--ro); }
.gt-svg .gt-rm.is-on { opacity: 1; transition: opacity .4s var(--ease) var(--ri); }
.gt-svg .gt-rmx { opacity: 0; transition: opacity .35s var(--ease) .1s; }
.gt-svg .gt-rmx.is-on { opacity: 1; transition: opacity .35s var(--ease) .5s; }
.gt-stage .gt-fade { opacity: 0; transition: opacity .3s var(--ease); }
.gt-stage .gt-fade.is-on { opacity: 1; transition: opacity .35s var(--ease) .8s; }

/* 标注 ------------------------------------------------------------------
   第七轮（Owner 11-10「你模型上的字太丑太突兀了」）：说明式标注——字一律放在模型外的空白区，排成对齐的列（右侧列左对齐、左侧列右对齐、
   等行距），一根发丝细引线从对齐边水平出去一小段再斜到锚点，锚点处一个 3px 小点；模型上不出现任何字，所以不再描边。
   HTML 标注层由脚本对齐到画面内容框，每块按画布百分比定位；字号固定像素：名称 13px / 500 / 最亮正文色，副标 12px / 400 / 次亮色。
   不用发光、模糊投影、渐变、底色胶囊（控件规范 v2） */
.gt-labels { position: absolute; pointer-events: none; }
/* 两套标注（同房间 / 跨房间）各占满标注层，整套交叉淡入淡出 */
.gt-lset { position: absolute; inset: 0; }
.gt-lab { position: absolute; }
/* 跨房间的小标签：不带编号。设备标签同名称一档（带引线指到设备）；区域标签同副标一档、字距略宽（不带引线，标一片区域） */
.gt-tagt { display: block; font: 500 13px/18px var(--sans); color: var(--text); }
.gt-reg .gt-tagt { font-weight: 400; font-size: 12px; color: var(--text-2); letter-spacing: .06em; }
/* 带 data-gp 的标注（①–④ 和设备标签）接受指针：悬停或点击触发联动高亮（脚本在 document 上统一监听）；转动时不接受 */
.gt-lab[data-gp] .gt-lab-i { pointer-events: auto; cursor: default; }
.gt-stage.is-turning .gt-lab-i { pointer-events: none; }
.gt-lab-i { display: flex; align-items: flex-start; gap: 8px; white-space: nowrap; }
/* 左侧列：块右对齐到对齐边，编号圈挨着引线那一侧（排在右边），文字右对齐 */
.gt-lab.is-left .gt-lab-i { flex-direction: row-reverse; text-align: right; }
.gt-lab.is-left .gt-txt { justify-items: end; }
/* 放不下 / 被挡住的标注淡出（静态排版和转台跟随同一规则） */
.gt-lab .gt-lab-i { transition: opacity .2s var(--ease); }
.gt-lab.is-off .gt-lab-i { opacity: 0; }
/* 编号圈按控件规范 v2「去油」：只有一圈中性细线和等宽数字，没有底色、没有暖金、不发光 */
.gt-num {
  flex: none; display: grid; place-items: center; width: 20px; height: 20px; border: 1px solid rgba(var(--ink-rgb), .4); border-radius: 50%;
  font: 500 11px/1 var(--mono); color: var(--text);
}
.gt-txt { display: grid; gap: 2px; }
.gt-name { font: 500 13px/20px var(--sans); color: var(--text); }
/* 几条副标叠在同一格：标注块宽度取最宽的那条，切换方式时标注块不挪、不跳 */
.gt-subs { display: grid; }
.gt-subs > * { grid-area: 1 / 1; }
.gt-sub { font: 400 12px/16px var(--sans); color: var(--text-2); }
/* 副标一律不折行（主线 11-10：折行出了孤字）；跨房间列式用短版副标，还放不下就脚本加 gt-nosub 不显示副标 */
.gt-lab.gt-nosub .gt-subs { display: none; }
.gt-lab.is-left .gt-subs { justify-self: end; }
.gt-port { font: 500 11px/16px var(--mono); letter-spacing: .04em; color: var(--text-2); }
/* 引线：1px 发丝（不随缩放变粗），锚点处 3px 实心小点，同一色 */
.gt-svg .gt-lead-l { fill: none; stroke: rgba(var(--ink-rgb), .38); stroke-width: 1; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.gt-svg .gt-lead-d { fill: none; stroke: rgba(var(--ink-rgb), .7); stroke-width: 3; stroke-linecap: round; vector-effect: non-scaling-stroke; }
/* 图例模式（窄构图一律；宽构图放不下 ①–④ 时退到它，脚本给场景加 .is-legend）：标注块和引线不显示，模型上只留编号点（.gt-mark，放在锚点上），
   名称和副标排在舞台底部的图例（.gt-legend）里，编号一一对应；画面缩进图例以上的高度（脚本把两个 SVG 的高度设成剩余高度）。
   编号点：18px 底色圆、一圈细线、等宽数字——这是模型上唯一的「字」，按任务书只留小编号点 */
.gt-mark {
  display: none; position: absolute; width: 18px; height: 18px; margin: -9px 0 0 -9px; border-radius: 50%; box-sizing: border-box;
  background: var(--bg); border: 1px solid rgba(var(--ink-rgb), .5); font: 500 10px/16px var(--mono); color: var(--text); text-align: center;
}
.gt-scene.is-legend .gt-mark { display: block; }
.gt-scene.is-legend .gt-lab, .gt-scene.is-legend .gt-leads { display: none; }
.gt-legend {
  position: absolute; left: 0; right: 0; bottom: 0; display: none; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 6px 16px;
  padding: 10px 2px 0; pointer-events: none;
}
.gt-scene.is-legend .gt-legend { display: grid; }
.gt-lg-i { display: flex; align-items: flex-start; gap: 8px; white-space: nowrap; }
.gt-lg-i .gt-num { width: 18px; height: 18px; font-size: 10px; }
.gt-lg-i .gt-name { line-height: 18px; }
.gt-lg-i.gt-reg .gt-name { font-weight: 400; font-size: 12px; color: var(--text-2); letter-spacing: .06em; }

/* 联动高亮：页面卡片指针移入 / 聚焦时，对应图层提亮并描一圈暖光，其余图层和标注压暗到 45%；
   阴影层（.gt-shd）跟着部件一起压暗或保持，但不提亮、不描光——否则暖光会把落地阴影也描出一圈 */
.gt-stage [data-gp] { transition: opacity .2s var(--ease); }
.gt-stage[data-hl] [data-gp] { opacity: .45; }
.gt-stage[data-hl="target"] [data-gp="target"],
.gt-stage[data-hl="card"] [data-gp="card"],
.gt-stage[data-hl="link"] [data-gp="link"],
.gt-stage[data-hl="debug"] [data-gp="debug"] { opacity: 1; }
.gt-stage[data-hl="target"] .gt-svg:not(.gt-over) [data-gp="target"] .gt-img:not(.gt-shd),
.gt-stage[data-hl="card"] .gt-svg:not(.gt-over) [data-gp="card"] .gt-img:not(.gt-shd),
.gt-stage[data-hl="link"] .gt-svg:not(.gt-over) [data-gp="link"] .gt-img:not(.gt-shd),
.gt-stage[data-hl="debug"] .gt-svg:not(.gt-over) [data-gp="debug"] .gt-img:not(.gt-shd) {
  filter: brightness(1.18) drop-shadow(0 0 calc(3px * var(--gt-k)) rgba(var(--accent-rgb), .7));
}

/* 首次入场（第六轮，Owner 11-10「加载太慢，黑屏时间太长」）-----------------------------
   原先是约 4 秒的分步揭示（机器 → 插卡 → 描线 → 标注），用户前几秒看到的是没线、没标注的舞台，像还没加载完。
   现在：.is-pre 是入场前的隐藏态——主图、覆盖层、引线、标注都不透明度 0，但位置就是最终位置（不滑入、不描线）；
   舞台进入视口、首屏那一张图（合成整图或这一方式的图层）落定后，脚本加 .is-quick 并去掉 .is-pre：
     0–.3s 完整画面淡入（机器、卡、线、阴影一起）→ .3s 起光点跟上 → 引线、标注在 .is-occ 到时淡入（.35s）：
     占用网格建好（本机约 .4s）或 1.5s 超时时脚本加 .is-occ，最早也在 .3s 后——先放行再重排会看见标注边淡入边挪位。
   描线、插卡、交换机升起这些动作只在切换方式时播（过渡写在各自的基础规则里）；1.5s 后脚本去掉 .is-quick / .is-occ。 */
.gt-stage.is-pre .gt-scene .gt-svg, .gt-stage.is-pre .gt-leads, .gt-stage.is-pre .gt-lab-i { opacity: 0; }
.gt-stage.is-pre .gt-lab-i { transform: translateY(6px); }
.gt-stage.is-quick:not(.is-occ) .gt-leads, .gt-stage.is-quick:not(.is-occ) .gt-lab-i { opacity: 0; }
.gt-stage.is-quick:not(.is-occ) .gt-lab-i { transform: translateY(6px); }
.gt-stage.is-quick .gt-scene .gt-svg:not(.gt-over) { transition: opacity .3s var(--ease); }
.gt-stage.is-quick .gt-scene .gt-svg.gt-over { transition: opacity .35s var(--ease) .3s; }
.gt-stage.is-quick .gt-leads { transition: opacity .35s var(--ease); }
.gt-stage.is-quick .gt-lab-i { transition: opacity .35s var(--ease), transform .35s var(--ease); }
/* 合成整图（首屏一张顶全部图层，见 topology.js build）：首屏用到时 .is-on，这一方式的逐层图层到齐后去掉，.3s 淡出露出一致的分层 */
.gt-svg .gt-compg { opacity: 0; transition: opacity .3s var(--ease); }
.gt-svg .gt-compg.is-on { opacity: 1; }

/* 视口外或页面隐藏：停掉循环动画 */
.gt-stage.is-paused .gt-svg .gt-dots, .gt-stage.is-paused .gt-svg .gt-glow { animation-play-state: paused; }

/* 360 度转台 ----------------------------------------------------------------
   只在宽构图、当前方式有转台帧时可转（.can-turn，脚本切）：光标 grab / grabbing，不写任何提示文字；
   touch-action: pan-y 让竖向滑动仍是页面滚动，只有横向拖动归舞台。舞台可聚焦（←、→、Home），焦点环按控件规范 v2。
   .gt-tt 铺满舞台、和图层一样四边羽化（转台帧铺了页面底色，羽化只为和静态画面同一处理）；里面的画布对齐画面内容框，
   静止对位时按 --tt-rest（restCrop）放大，和静态画面逐像素重合。进入转动：画布 .2s 交叉淡入，随后 .4s 放到整帧（.is-full）；
   转回：裁切用 --tt-back（与转回的转角同一时长）收回 restCrop，再 .2s 淡出。转动中（.is-turning）标注、引线、光点 .2s 淡出，结束后淡回。
   减少动态效果时这些过渡都被下面的媒体查询关掉：切帧直接到位 */
.gt-stage.can-turn { cursor: grab; touch-action: pan-y; user-select: none; -webkit-user-select: none; }
.gt-stage.can-turn.is-grabbing { cursor: grabbing; }
.gt-stage:focus { outline: none; }
.gt-stage:focus-visible { outline: 1.5px solid rgba(var(--accent-rgb), .8); outline-offset: 3px; }
.gt-tt {
  position: absolute; inset: 0; opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .2s var(--ease), visibility 0s linear .2s;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent), linear-gradient(180deg, transparent, #000 8%, #000 92%, transparent);
  -webkit-mask-composite: source-in;
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent), linear-gradient(180deg, transparent, #000 8%, #000 92%, transparent);
  mask-composite: intersect;
}
.gt-tt.is-on { opacity: 1; visibility: visible; transition: opacity .2s var(--ease), visibility 0s; }
.gt-tt-c { position: absolute; display: block; transform-origin: 0 0; transform: var(--tt-rest, none); transition: transform var(--tt-back, .4s) var(--gt-draw); }
.gt-tt.is-full .gt-tt-c { transform: none; transition: transform .4s var(--gt-draw); }
.gt-stage .gt-labels, .gt-stage .gt-leads, .gt-stage .gt-over { transition: opacity .25s var(--ease) .15s; }
.gt-stage.is-turning:not(.is-track) .gt-labels, .gt-stage.is-turning .gt-leads, .gt-stage.is-turning .gt-over { opacity: 0; transition: opacity .2s var(--ease); }
/* 画布淡入后把静态画面（两个 SVG：图层 + 光点）隐掉（晚 .2s 起，.2s）：画布四边羽化，静态图层不隐会在羽化带里透出来（实测两侧各一条机箱的竖影）；
   只隐 SVG 不隐整个场景，HTML 标注层留着给跟随用；转回时 SVG 按默认的 .35s 淡回，和画布 .2s 淡出交叉 */
/* 两个 SVG 的框由脚本设成内容框（模型为给标注列腾位置缩小时随之缩小）；overflow 可见：引线要画到模型框外的标注列上 */
.gt-scene .gt-svg { position: absolute; overflow: visible; transition: opacity .35s var(--ease); }
.gt-tt-leads { overflow: visible; }
.gt-stage.is-turning .gt-scene.is-cur .gt-svg { opacity: 0; transition: opacity .2s var(--ease) .2s; }
/* 标注跟随（第六轮）：有 track.json 的方式（.is-track）转动时标注层不淡出，整帧态（.is-tt-full）下每块标注按当前帧的锚点就位；
   进入转动到放到整帧之间、以及转回途中（裁切在收、画面在动）标注先淡出 .2s；被挡住的锚点那块标注 .is-off 淡出；
   引线画在转台自己的覆盖 SVG（.gt-tt-leads，随整帧态一起出现）。没有 track 的方式维持原样：转动时标注整层淡出 */
/* 标注层要叠在转台画布之上（.gt-tt 是后追加到舞台的兄弟元素，默认盖住场景里的 HTML 标注层；.gt-scene 静止时没有自己的层叠上下文，z-index 能越过它） */
.gt-stage.is-track .gt-scene.is-cur .gt-labels { z-index: 2; }
.gt-stage.is-turning.is-track:not(.is-tt-full) .gt-lab-i { opacity: 0; }
.gt-tt-leads { position: absolute; pointer-events: none; opacity: 0; transition: opacity .2s var(--ease); }
.gt-stage.is-tt-full .gt-tt-leads { opacity: 1; }
/* 「复位」按钮：次按钮，外观是 guide.css 的统一按钮 .mx-btn（按钮规范 v3：图标与文字同一行、36px、细线、无阴影无渐变），
   这里只管位置——转离了第 0 帧时出现（第六轮起所有人都有：没有自动转回了），放在挂载点右下角、舞台之外。
   排版时它的矩形是障碍（topology.js 按实际尺寸量，不写死高度） */
.gt-reset { position: absolute; right: 16px; bottom: 16px; }

/* 减少动态效果：不入场、不流动、切换与高亮直接到位；端口暖光保留为静止的一圈
   （mx.css 只把时长压到 0.01ms，循环动画要整个关掉，否则会高速闪烁） */
@media (prefers-reduced-motion: reduce) {
  .gt-stage, .gt-stage * { transition: none !important; animation: none !important; }
  .gt-svg .gt-dots { display: none; }
}

/* 英文版的图例：英文名称比中文长，nowrap 下窄屏一栏 150px 放不下会伸出图例项；允许换行（图例高度由脚本按实际高度量，只在英文页生效） */
html[lang="en-US"] .gt-lg-i { white-space: normal; }
html[lang="en-US"] .gt-lg-i .gt-txt { min-width: 0; }
