/* style.css —— 编辑器界面 + 画布内骨架元素样式 */

:root {
  /* 语义色 */
  --bg: #f4f5f7;
  --panel: #ffffff;
  --line: #e3e6ea;
  --text: #1f2328;
  --muted: #6b7480;
  --accent: #2f80ed;
  --skel: #8593a3;
  --danger: #c8102e;

  /* 界面面层（原先散在各处的硬编码色，收进来才谈得上换主题） */
  --surface: #ffffff;      /* 按钮 / 输入框 / 卡片底 */
  --surface-2: #f7f8fa;    /* hover 底 */
  --surface-3: #eef1f5;    /* 再深一档的 hover / 选中底 */
  --line-strong: #cfd5dd;
  --muted-faint: #98a1ac;
  --accent-soft: #e8f1fd;  /* 选中行底 */
  --canvas: #fbfbfc;       /* 画布底 */
  --grid: #d6dce4;         /* 画布网格线（无底图时更明显） */
  --glass: rgba(255, 255, 255, .93);
  --scrim: rgba(24, 30, 38, .28);
  --shadow: 0 12px 40px rgba(20, 26, 34, .22);
  --snap-soft: #fdf3e4;    /* 吸附提示（琥珀）的浅底 */
  --map-overlay-ink: #ffffff;             /* 经纬网 / 框选控制点 */
  --map-overlay-halo: rgba(0, 0, 0, .72); /* 压在地图上的暗色描边 */

  /* 两层导航：同色系，浅一档区分层级 */
  --bar-1: #ffffff;
  --bar-2: #eef2f9;

  /* ⚠ 这一句不能省：<input>/<select>/滚动条这些**原生控件**是按 color-scheme 渲染的，
     不声明的话即使把 --surface 换成深色，滑条轨道、下拉箭头、数字框仍然是白的。 */
  color-scheme: light;
}

/* 暗色：只换变量，画布里的符号颜色（红/蓝）不动 —— 那是数据不是配色 */
[data-theme="dark"] {
  --bg: #14171c;
  --panel: #1a1e24;
  --line: #2b3138;
  --text: #e6e9ee;
  --muted: #9aa4b2;
  --accent: #4a94f8;
  --skel: #8d99a8;
  --danger: #e8546b;

  --surface: #1f242b;
  --surface-2: #252b33;
  --surface-3: #2c333c;
  --line-strong: #3a424c;
  --muted-faint: #6f7a88;
  --accent-soft: #1e3050;
  --canvas: #14171c;
  --grid: #333b47;
  --glass: rgba(26, 30, 36, .93);
  --scrim: rgba(0, 0, 0, .55);
  --shadow: 0 12px 40px rgba(0, 0, 0, .5);
  --snap-soft: #3a2f1c;

  --map-overlay-ink: #ffffff;
  --map-overlay-halo: rgba(0, 0, 0, .78);

  --bar-1: #1a1e24;
  --bar-2: #232936;

  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  font: 13px/1.5 -apple-system, "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif;
  color: var(--text);
  background: var(--bg);
}

body { display: flex; flex-direction: column; }

/* ---------------------------------------------------------------- 工具栏 */

/* ---- 两层导航：同色系，第二层浅一档表示"下一层" ---- */

/* 顶部导航是悬浮层：不占文档高度，画布铺满整屏。
   两个圆角岛（品牌+项目 / 主模式+撤销重做）左对齐，岛与岛之间只留空隙。 */
.toolbar {
  position: fixed;
  top: 12px;
  left: 12px;
  right: 12px;
  z-index: 50;
  display: flex;
  flex-direction: column;
  border: 0;
  pointer-events: none;
}

.bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0;
  background: none;
}
.bar-1 {
  position: relative;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 10px;
  max-width: calc(100vw - 336px);
  background: none;
}

.nav-island {
  display: flex;
  align-items: center;
  gap: 3px;
  flex: 0 0 auto;
  padding: 4px 6px;
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow);
  backdrop-filter: blur(10px);
  pointer-events: auto;
}
.nav-brand { backdrop-filter: none; } /* 避免形成 fixed 子元素的包含块，文件卡片要对齐视口 12px */
.nav-actions { flex: 0 1 auto; min-width: 0; flex-wrap: wrap; row-gap: 3px; }

/* 二级菜单统一变成浮起来的圆角矩形，默认不再占据导航下方的一条横栏 */
.bar-2 {
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow);
  backdrop-filter: blur(10px);
  padding: 9px 11px;
  align-items: center;
  flex-wrap: wrap;
  row-gap: 7px;
  pointer-events: auto;
}
.bar-2-label {
  font-size: 11px;
  color: var(--muted-faint);
  letter-spacing: .05em;
  padding-right: 2px;
  white-space: nowrap;
}

/* 五个二级菜单共用一套堆叠逻辑：各自成块，可同时打开，按固定顺序纵向排列 */
.tool-stack {
  position: fixed;
  top: var(--nav-offset, 62px);
  left: 12px;
  width: max(160px, calc(100vw - 336px));
  z-index: 45;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  pointer-events: none;
}
.tool-stack > .bar-2 { width: max-content; max-width: 100%; }
.tool-stack > #bar-timeline { width: 100%; }

/* 态势 / 符号两块二级菜单：按可用横向宽度铺满，按钮与缩略图在标签右侧
   自己的容器里换行 —— 换行后的左边缘与第一行对齐，不会回到标签下面。 */
.tool-stack > #bar-new,
.tool-stack > #bar-unit {
  width: 100%;
  flex-wrap: nowrap;
  align-items: flex-start;
}
#bar-new > .bar-2-label,
#bar-unit > .bar-2-label {
  line-height: 30px;
  flex: 0 0 auto;
}
.bar-items {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  align-content: flex-start;
  gap: 7px 8px;
}
.unit-body {
  flex: 1 1 auto;
  flex-direction: column;
  flex-wrap: nowrap;
  align-items: stretch;
  gap: 2px;
}

.brand {
  font-weight: 600;
  font-size: 14px;
  margin-right: 4px;
  white-space: nowrap;
  flex: 0 0 auto;
}

/* 占位入口（队伍定义 / 时间轴编辑 / 新建元件）：是按钮但不抢视觉 */
.tb.ghost {
  background: transparent;
  border-color: transparent;
  color: var(--muted);
}
.tb.ghost:hover { background: var(--surface-2); border-color: var(--line-strong); color: var(--text); }

/* 四个主模式：淡蓝色填充，和菜单/撤销/重做明显区分 */
.tb.mode-soft {
  background: var(--accent-soft);
  border-color: transparent;
  color: var(--accent);
}
.tb.mode-soft:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
}
.tb.mode-soft.active { border-color: var(--accent); }

/* ---- 标题即项目菜单 ---- */

.brand.menu-btn {
  height: 30px;
  margin: 0;
  padding: 0 5px 0 8px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.brand.menu-btn:hover { background: var(--surface-2); }
.brand.menu-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* 项目卡片：身份区 → 文件操作 → 账户说明 */
.menu-card.project-card {
  position: fixed;
  top: var(--nav-offset, 62px);
  left: 12px;
  right: auto;
  width: 262px;
  min-width: 240px;
  max-width: calc(100vw - 24px);
  padding: 9px 11px;
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow);
  backdrop-filter: blur(10px);
}
.menu-sep {
  height: 1px;
  margin: 5px 2px;
  background: var(--line);
  flex: 0 0 auto;
}
.project-user {
  padding: 8px;
  border-radius: 7px;
  background: var(--surface-2);
}
.project-user-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 12px;
  color: var(--muted);
}
.project-user-row b { color: var(--text); font-weight: 600; }
.project-auth {
  width: 100%;
  margin-top: 5px;
  height: 28px;
  font-size: 11.5px;
  opacity: .62;
}
.project-doc-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 8px 3px;
  font-size: 11.5px;
  color: var(--muted);
}
.project-doc-row b {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text);
  font-weight: 500;
}
.project-card .menu-item { width: 100%; }
.project-account {
  padding: 6px 8px 4px;
  font-size: 11.5px;
  line-height: 1.65;
  color: var(--muted);
}
.project-account > div:nth-child(2) { color: var(--text); }
.project-deferred {
  margin-top: 3px;
  color: var(--muted-faint);
  font-size: 10.5px;
}

/* ---- 项目 / 视图下拉卡片 ---- */

.menu-wrap { position: relative; display: inline-flex; flex: 0 0 auto; }
.menu-btn { padding-right: 9px; }
.menu-caret { font-size: 9px; color: var(--muted); line-height: 1; }
.menu-card {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 60;
  min-width: 150px;
  padding: 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, .22);
}
.menu-item {
  display: flex;
  align-items: center;
  height: 30px;
  padding: 0 10px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 12.5px;
  text-align: left;
  cursor: pointer;
}
.menu-item:hover { background: var(--surface-3); }
.menu-item[aria-checked="true"] {
  background: var(--accent-soft);
  color: var(--accent);
}
/* 左下角的地形菜单向上展开 */
.menu-card.menu-up {
  top: auto;
  bottom: calc(100% + 6px);
}
.legend-terrain-wrap .menu-card {
  left: auto;
  right: 0;
  min-width: 130px;
}

/* ---- 明暗二选一：太阳 / 月亮图标 ---- */

.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 2px;
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: 9px;
  backdrop-filter: blur(6px);
  cursor: pointer;
  pointer-events: auto;
  flex: 0 0 auto;
}
.theme-ico {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 6px;
  color: var(--muted);
  transition: background .12s, color .12s;
}
.theme-ico svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.theme-moon svg { fill: currentColor; stroke: none; }
[data-theme="light"] .theme-moon,
[data-theme="dark"] .theme-sun { display: none; }
[data-theme="light"] .theme-sun,
[data-theme="dark"] .theme-moon { color: var(--accent); }
.theme-toggle:hover { background: var(--surface-2); }
.theme-toggle:hover .theme-ico { color: var(--text); }
.theme-toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.tb {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  height: 30px;
  padding: 0 11px;
  /* 按钮多了之后工具栏会换行 —— 换行要发生在**按钮之间**，
     不能让按钮里的文字自己折成两行（那样每个按钮都变成一个高矮不一的方块） */
  white-space: nowrap;
  flex: 0 0 auto;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  cursor: pointer;
  transition: .12s;
}
.tb:hover { background: var(--surface-2); border-color: var(--line-strong); }
.tb:active { transform: translateY(1px); }
.tb.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.tb.primary:hover { background: #2670d4; }
.tb.active { box-shadow: 0 0 0 3px rgba(47,128,237,.22); border-color: var(--accent); }

/* 循环开关的“开”用淡蓝底，不只靠描边 */
#btn-tl-loop.active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}
#btn-tl-loop.active:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
}
.ico { width: 15px; height: 15px; fill: currentColor; }
.sep { width: 1px; height: 20px; background: var(--line); margin: 0 4px; }
.spacer { flex: 1; }

.hint { color: var(--muted); font-size: 12px; }

/* 栏内联的"滑条 + 读数"（底图的比例/不透明度） */
.bar .inline {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  flex: 0 0 auto;
}
.bar .inline input[type=range] { width: 110px; }
.bar .inline output {
  min-width: 3.2em;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.bar .inline select {
  height: 24px;
  padding: 0 4px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 11.5px;
}
.bar .inline input[type=number] {
  width: 4.6em;
  font-variant-numeric: tabular-nums;
}
/* 1 帧 = 多少战斗时间：由三个输入算出来，放在控件行里常显 */
#o-tl-ratio {
  color: var(--accent);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- 主体 */

.stage { flex: 1; display: flex; min-height: 0; }

.canvas-wrap { position: relative; flex: 1; min-width: 0; }

#board {
  width: 100%;
  height: 100%;
  display: block;
  background: var(--canvas);
  touch-action: none;
  user-select: none;
  cursor: grab; /* 空白画布：小手，按住左键可拖拽平移 */
}

/* ---- 底图 ----
   默认不接收鼠标事件：底图往往铺满视口，如果它吃事件，空白处的拖动就变成拖图，
   画布平移只能靠中键。行里的「移动底图」开关负责临时打开它。 */
#layer-base { pointer-events: none; }
#layer-base.is-movable { pointer-events: all; cursor: move; }

/* 「图片 / 在线地图」二选一：切到地图时把导入的图片整层藏起来（模型不删） */
#layer-base.is-hidden { display: none; }

/* 在线地图：纯背景，永远不接收事件 */
#layer-tiles { pointer-events: none; }

/* ---- 二选一分段控件（segmented control）----
   原生没有对应元素，用 radio + label 做：radio 藏起来但保留键盘行为，
   选中态靠 `:checked + label`。 */
.seg {
  display: inline-flex;
  flex: 0 0 auto;
  border: 1px solid var(--line);
  border-radius: 7px;
  overflow: hidden;
  background: var(--surface);
}
.seg input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.seg label {
  display: inline-flex;
  align-items: center;
  height: 28px;
  padding: 0 13px;
  font-size: 13px;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
  transition: .12s;
}
.seg label + input + label { border-left: 1px solid var(--line); }
.seg label:hover { background: var(--surface-2); color: var(--text); }
.seg input:checked + label {
  background: var(--accent);
  color: #fff;
}
.seg input:focus-visible + label { box-shadow: inset 0 0 0 2px var(--accent); }
.seg input:disabled + label,
.seg label.is-disabled { opacity: .4; cursor: not-allowed; }

/* 底图那一行的两页（图片 / 在线地图）。[hidden] 已有全局 display:none */
.base-pane {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  flex: 0 0 auto;
}

/* 在线地图署名：贴画布右下角，固定字号，不随画布缩放 */
.map-credit {
  position: absolute;
  right: calc(var(--panel-width, 300px) + 24px);
  bottom: 10px;
  z-index: 3;
  transition: right .16s ease;
  font-size: 11px;
  color: var(--muted);
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 7px;
  user-select: none;
}
/* 屏幕比例尺：黑白相间的长条 + 地面距离，压在地图上但不吃事件 */
.map-scalebar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  pointer-events: none;
  user-select: none;
}
.map-scalebar[hidden] { display: none; }
.map-scalebar-bar {
  height: 6px;
  box-sizing: border-box;
  border: 1px solid var(--map-overlay-ink);
  background: repeating-linear-gradient(
    to right,
    var(--map-overlay-ink) 0 50%,
    var(--map-overlay-halo) 50% 100%
  );
  box-shadow: 0 0 2px var(--map-overlay-halo);
}
.map-scalebar-label {
  font-size: 10.5px;
  line-height: 1;
  color: var(--map-overlay-ink);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  text-shadow:
    0 0 2px var(--map-overlay-halo),
    0 0 2px var(--map-overlay-halo);
}
.map-credit a { color: inherit; text-decoration: none; }
.map-credit a:hover { text-decoration: underline; }

/* 矩形配准的拖拽预览：画在世界坐标里，所以线宽会随缩放变 ——
   它是拖动时才有的一闪而过的东西，不必为它引入 non-scaling-stroke。 */
.base-extent-layer { pointer-events: none; }
.bm-extent {
  fill: var(--accent-soft);
  fill-opacity: .22;
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-dasharray: 8 6;
}
.bm-extent-dot { fill: var(--accent); stroke: var(--surface); stroke-width: 1.5; }

/* 导出区域框（只显示，不进导出） */
.exp-region-layer { pointer-events: none; }
.exp-region-rect {
  fill: none;
  stroke: var(--map-overlay-ink);
  filter: drop-shadow(0 0 2px var(--map-overlay-halo));
}
.exp-region-dot {
  fill: var(--map-overlay-ink);
  stroke: var(--map-overlay-halo);
  stroke-width: 1.5;
  pointer-events: none;
}
.exp-region-handle-hit {
  fill: transparent;
  stroke: none;
  pointer-events: all;
  cursor: pointer;
}
.exp-region-label {
  fill: var(--map-overlay-ink);
  font-size: 11px;
  font-weight: 600;
  paint-order: stroke;
  stroke: var(--map-overlay-halo);
  stroke-width: 3;
  stroke-linejoin: round;
  pointer-events: none;
}
#board.picking-export-region { cursor: crosshair; }

/* 左下角 HUD：不再是一整张卡片，而是“帮助按钮 + 比例/地形胶囊 + 比例尺”
   三块并排。容器本身透明、不吃事件；只有按钮和胶囊接收点击。 */
.legend {
  position: absolute;
  left: 14px;
  bottom: 14px;
  max-width: calc(100% - 28px);
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  font-size: 12px;
  color: var(--muted);
  pointer-events: none;
}
.legend b { color: var(--text); }
.legend ul {
  position: absolute;
  left: 0;
  bottom: calc(100% + 8px);
  width: min(320px, calc(100vw - 28px));
  margin: 0;
  padding: 8px 10px;
  list-style: none;
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: 9px;
  box-shadow: var(--shadow);
  backdrop-filter: blur(6px);
  pointer-events: auto;
}

/* 帮助按钮：单独一个圆角矩形 */
.legend-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}
.legend-min.legend-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 11px;
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: 9px;
  backdrop-filter: blur(6px);
  cursor: pointer;
  pointer-events: auto;
  white-space: nowrap;
}
.legend-min.legend-toggle:hover { background: var(--surface-2); border-color: var(--line-strong); }
#legend-caret { color: var(--muted); font-size: 10px; font-weight: 400; }

/* 画布百分比 + 地形选择：共享第二个圆角矩形 */
.legend-tools {
  display: flex;
  align-items: center;
  gap: 2px;
  height: 30px;
  padding: 2px;
  box-sizing: border-box;
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: 9px;
  backdrop-filter: blur(6px);
  pointer-events: auto;
}
.legend-tool {
  font: inherit;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--muted);
  background: transparent;
  border: 0;
  border-radius: 6px;
  padding: 0 7px;
  min-height: 24px;
  cursor: pointer;
  white-space: nowrap;
}
.legend-tool:hover { background: var(--surface-2); color: var(--text); }
.legend-tool.active,
.legend-tool[aria-pressed="true"] {
  background: var(--accent-soft);
  color: var(--accent);
}
.legend-tool.is-current {
  color: var(--accent);
  background: var(--accent-soft);
}
.legend.is-min ul { display: none; }
.legend li { margin: 3px 0; display: flex; align-items: center; gap: 6px; }
.dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; background: var(--surface); border: 2px solid var(--accent); }
.dot.origin { background: var(--accent); }
.dot.tip { background: var(--accent); }
.dot.ctrl { background: var(--surface); border-color: var(--accent); border-style: dotted; }
.dot.ellipse { border-radius: 2px; border-color: #7d8896; }
.dot.neck { border-radius: 50%; border-color: var(--accent); }
.dot.pan { border-radius: 50%; border-color: #7d8896; background: var(--surface-3); }

/* ---------------------------------------------------------------- 右侧面板 */

.panel {
  position: fixed;
  top: 12px;
  right: 12px;
  bottom: 12px;
  width: var(--panel-width, 300px);
  z-index: 44;
  flex: 0 0 auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow);
  overflow-y: auto;
  padding: 0 0 24px;
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) transparent;
  scrollbar-gutter: stable;
  transition: width .16s ease, height .16s ease, box-shadow .16s ease;
}

/* 没有选中元件时：收成右上角一个小方块，保留一个可点的入口。
   收起不是 display:none —— 用户仍能看见“属性栏在这里”。 */
.panel.is-collapsed {
  width: 44px;
  height: 44px;
  bottom: auto;
  padding: 0;
  overflow: hidden;
}
.panel.is-collapsed .focus,
.panel.is-collapsed .panel-body,
.panel.is-collapsed .panel-actions { display: none; }
.panel-rail {
  display: none;
  position: relative;
  width: 100%;
  height: 100%;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 11px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}
.panel.is-collapsed .panel-rail { display: flex; }
.panel-rail:hover { background: var(--accent-soft); color: var(--accent); }
.panel-rail:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.panel-rail svg { width: 19px; height: 19px; }
.panel-rail-dot {
  position: absolute;
  top: 8px; right: 8px;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0;
}
.panel.is-collapsed.has-target .panel-rail-dot { opacity: 1; }

/* 展开后的固定/收起按钮：浮在焦点卡片右上角，不额外占一行。 */
.panel-actions {
  position: absolute;
  top: 8px;
  right: 9px;
  z-index: 5;
  display: flex;
  gap: 3px;
}
.panel-icon {
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid transparent;
  border-radius: 5px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  padding: 0;
}
.panel-icon:hover { background: var(--surface-2); border-color: var(--line); color: var(--text); }
.panel-icon:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.panel-icon.is-on { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.panel-icon svg { width: 14px; height: 14px; }
.focus-row { padding-right: 56px; }
.focus-input { width: calc(100% - 56px); }
.panel::-webkit-scrollbar { width: 10px; }
.panel::-webkit-scrollbar-track {
  background: transparent;
  margin: 16px 0;
}
.panel::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: 999px;
}
.panel::-webkit-scrollbar-thumb:hover {
  background: var(--muted-faint);
  border: 3px solid transparent;
  background-clip: content-box;
}
.panel section { padding: 10px 14px; border-bottom: 1px solid var(--line); }
/* 各类“读数”统一放在面板最后，用一条更明显的横线跟参数区分开 */
.panel section.read-sec { border-top: 1px solid var(--line-strong); }

/* ------------------------------------------------ 当前焦点元素 / 重命名 */

.focus {
  position: sticky;
  top: 0;
  z-index: 3;
  padding: 11px 14px 10px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  border-radius: 11px 11px 0 0;
}
.focus-row {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  align-items: center;
  gap: 8px;
}
.focus-label { font-size: 11px; color: var(--muted); letter-spacing: .05em; }

.focus-name {
  margin: 0;
  padding: 2px 6px;
  font-size: 14px;
  font-weight: 600;
  border: 1px solid transparent;
  border-radius: 6px;
  cursor: text;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.focus-name:hover { background: var(--surface-2); border-color: var(--line); }
.focus-name.is-empty { color: var(--muted); font-weight: 400; cursor: default; }
.focus-name.is-empty:hover { background: none; border-color: transparent; }

/* 多选（待编组）：不是一个可重命名的元素，别给"可编辑"的光标与 hover 底色 */
.focus-name.is-multi { cursor: default; }
.focus-name.is-multi:hover { background: none; border-color: transparent; }

.focus-input {
  display: block;
  width: 100%;
  margin: 4px 0 0;
  height: 27px;
  padding: 0 6px;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--accent);
  border-radius: 6px;
  outline: none;
}
.focus-input[hidden] { display: none; }
.focus-input.invalid {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px rgba(200, 16, 46, .12);
}

.focus-sub { margin-top: 2px; font-size: 11.5px; color: var(--muted); }
.focus-sub:empty { display: none; }

.focus-err { margin-top: 5px; font-size: 11.5px; line-height: 1.4; color: var(--danger); }
.focus-err:empty { display: none; }

/* ---------------------------------------------------------------- 集合：成员列表 */

[hidden] { display: none !important; }

/* 板块标题行：标题在左，"解散"之类的小按钮右对齐 */
.sec-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 9px; }
.sec-head h3 { margin: 0; }

.member-list { display: flex; flex-direction: column; gap: 3px; }

.member-row {
  display: flex; align-items: center; gap: 4px;
  border: 1px solid transparent; border-radius: 6px;
  background: var(--surface-2);
}
.member-row:hover { background: var(--surface-3); border-color: var(--line); }
.member-row.is-current { background: var(--accent-soft); border-color: var(--accent); }

.member-name {
  display: flex; align-items: center; gap: 7px; flex: 1 1 auto; min-width: 0;
  padding: 4px 0 4px 7px;
  border: none; background: none;
  font: inherit; font-size: 12px; color: var(--text);
  text-align: left; cursor: pointer;
}
.member-name i {
  flex: 0 0 auto; width: 16px; height: 16px; line-height: 16px;
  border-radius: 50%; background: var(--surface); border: 1px solid var(--line);
  font-style: normal; font-size: 10px; text-align: center; color: var(--muted);
}
.member-row.is-current .member-name i { background: var(--accent); border-color: var(--accent); color: #fff; }
.member-name span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 每行的"移出"：常驻右对齐（不能藏起来，否则用户找不到）。
   平时收着颜色不抢戏，hover 到该行才提亮。 */
.member-out {
  flex: 0 0 auto; margin-right: 4px; padding: 2px 7px;
  border: 1px solid transparent; border-radius: 5px;
  background: none; font: inherit; font-size: 11px; color: var(--muted);
  cursor: pointer; opacity: .5; transition: opacity .1s, color .1s;
}
.member-row:hover .member-out { opacity: 1; }
.member-out:hover { background: var(--surface); border-color: var(--line); color: var(--danger); }

.mini {
  height: 24px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--surface); font: inherit; font-size: 12px; color: var(--text); cursor: pointer;
}
.mini:hover { background: var(--surface-2); border-color: var(--line-strong); }
.mini:disabled { opacity: .45; cursor: default; background: var(--surface); }

/* 焦点不在任何元素上：参数区变淡并禁用；右上角入口和固定/收起按钮仍可点。 */
.panel.is-locked .panel-body { opacity: .4; filter: grayscale(.75); }

/* 焦点卡片不能跟着降 opacity：它是 sticky 的，一旦半透明，
   下面的参数页会透上来跟它叠在一起。所以只去色 + 把文字调淡，背景保持不透明。 */
.panel.is-locked .focus {
  filter: grayscale(.6);
}
.panel.is-locked .focus-label { color: var(--muted-faint); }
.panel.is-locked .focus-name { color: var(--muted-faint); }
.panel.is-locked .focus-name:hover { background: none; border-color: transparent; }
.panel h3 {
  margin: 0 0 9px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--muted);
  text-transform: uppercase;
}
.panel .note { margin: -4px 0 9px; font-size: 11.5px; color: var(--muted); line-height: 1.45; }

.row {
  display: grid;
  grid-template-columns: 76px 1fr auto;
  align-items: center;
  gap: 8px;
  margin: 7px 0;
}

/* 右侧面板统一两列：参数名 | 参数值。
   滑条行把读数绝对贴到右边缘，视觉上仍是一列"值"。 */
.panel .row {
  position: relative;
  grid-template-columns: 72px minmax(0, 1fr);
  gap: 6px;
  margin: 5px 0;
}
.panel .row > output {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  min-width: 44px;
}
.panel .row > input[type=range] { width: calc(100% - 50px); }
.panel .row select,
.panel .row input[type=number],
.panel .row input[type=text],
.panel .row input[type=color],
.panel .row input[type=file] { grid-column: 2 / -1; }

/* 带关键帧开关的行有 4 列，读数留在行末，不绝对定位 */
.panel .row.row-key { grid-template-columns: 18px 62px minmax(0, 1fr) 44px; }
.panel .row.row-key > output { position: static; transform: none; }
.panel .row.row-key > input[type=range] { width: 100%; }

/* 描述：左列参数名，右列两行输入框；第二行右侧勾选框 */
.panel .row.desc-row {
  grid-template-columns: 72px minmax(0, 1fr);
  align-items: start;
  margin: 2px 0 4px;
}
.panel .row.desc-row .desc-input { grid-column: 2; }
.panel .row.desc-opt { margin-top: 4px; }
.panel .row.desc-opt .desc-check { grid-column: 2; }
.panel .row .btn-row {
  grid-column: 2 / -1;
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}
.panel .row .btn-row .mini { flex: 1 1 0; min-width: 0; padding: 0 6px; }
.row label { font-size: 12px; color: var(--muted); }
.row output {
  font-size: 11.5px; color: var(--muted); text-align: right;
  font-variant-numeric: tabular-nums;
  min-width: 50px; /* 容得下 "16 px" / "100%" */
}
.row input[type=range] { width: 100%; accent-color: var(--accent); }

.exp-size {
  grid-column: 2 / 4;
  display: flex;
  align-items: center;
  gap: 6px;
}
.exp-size input[type=number] {
  width: 76px;
  height: 24px;
  padding: 0 6px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 12px;
}
.exp-size span { color: var(--muted); font-size: 11.5px; }
.exp-size input:disabled { opacity: .55; cursor: not-allowed; }
.exp-check {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 8px 0;
  font-size: 11.5px;
  color: var(--muted);
}
.exp-preview {
  height: 170px;
  margin: 10px 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-3);
  border: 1px solid var(--line);
  border-radius: 7px;
  overflow: hidden;
}
.exp-frame {
  position: relative;
  overflow: hidden;   /* crop 模式下内容块会超出画布，必须裁掉 */
  border: 1px solid var(--accent);
  background: var(--surface);
  box-shadow: 0 0 0 1px var(--accent-soft);
}
.exp-content {
  position: absolute;
  border: 1px dashed var(--muted-faint);
  background: var(--accent-soft);
}
.exp-note {
  min-height: 2.6em;
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--muted);
}
.export-modal {
  width: 540px;
  max-width: calc(100vw - 24px);
  max-height: 88vh;
  display: flex;
  flex-direction: column;
}
.exp-modal-body {
  min-height: 0;
  overflow-y: auto;
  padding-right: 4px;
}
.exp-section {
  padding: 8px 0 10px;
  border-bottom: 1px solid var(--line);
}
.exp-section:last-of-type { border-bottom: 0; }
.exp-section h4 {
  margin: 0 0 7px;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: .02em;
}
.exp-seg {
  width: 100%;
  display: flex;
}
.exp-seg label {
  flex: 1 1 0;
  justify-content: center;
  height: 30px;
}
.exp-format-seg label { font-weight: 600; letter-spacing: .04em; }
.exp-cap {
  margin-top: 6px;
  font-size: 11px;
  color: var(--muted-faint);
}
.exp-presets {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
  margin-bottom: 8px;
}
.exp-preset {
  height: 28px;
  padding: 0 6px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  color: var(--muted);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}
.exp-preset:hover { background: var(--surface-2); color: var(--text); }
.exp-preset.is-active {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent);
}
.exp-preset:disabled {
  opacity: .4;
  cursor: not-allowed;
}
.exp-divider {
  height: 1px;
  background: var(--line);
  margin: 9px 0;
}
.exp-readout {
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.exp-readout b { color: var(--text); }
.exp-z-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 4px;
  font-size: 11.5px;
  color: var(--muted);
}
.exp-z-head b { color: var(--accent); font-size: 12px; }
#i-exp-z { width: 100%; accent-color: var(--accent); }
.exp-region {
  grid-column: 2 / 4;
  display: flex; align-items: center; gap: 6px;
  min-width: 0;
}
.exp-region .exp-region-val {
  flex: 1; min-width: 0;
  font-size: 11px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.exp-region .tb { flex: none; height: 24px; padding: 0 8px; font-size: 11px; }
.exp-region-row {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 7px;
  min-width: 0;
}
.exp-region-row[hidden] { display: none; }
.exp-region-val {
  flex: 1;
  min-width: 0;
  font-size: 11px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
.exp-region-row .tb {
  flex: none;
  height: 24px;
  padding: 0 8px;
  font-size: 11px;
}
.exp-anim-row[hidden], .exp-svg-row[hidden] { display: none; }
.exp-preview {
  position: relative;
  height: 190px;
  margin: 2px 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: var(--surface-3);
  border: 1px solid var(--line);
  border-radius: 7px;
}
#exp-preview-img {
  display: block;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
#exp-preview-img[hidden] { display: none; }
.exp-preview-msg {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 11.5px;
  color: var(--muted);
  background: var(--surface-3);
  pointer-events: none;
}
.exp-preview.has-image .exp-preview-msg { display: none; }
.exp-preview.is-loading #exp-preview-img { opacity: .55; }
.exp-region-editor {
  position: absolute;
  left: 50%;
  bottom: 44px;
  transform: translateX(-50%);
  z-index: 8;
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: calc(100% - 28px);
  padding: 7px 10px;
  background: var(--glass);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: var(--shadow);
  backdrop-filter: blur(6px);
  pointer-events: auto;
}
.exp-region-editor[hidden] { display: none; }
.exp-region-editor-readout {
  max-width: 340px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.exp-region-editor .tb {
  flex: none;
  height: 24px;
  padding: 0 8px;
  font-size: 11px;
}
.geo-overlay { pointer-events: none; }
.geo-tick { stroke: var(--map-overlay-ink); stroke-width: 1.2; filter: drop-shadow(0 0 1px var(--map-overlay-halo)); }
.geo-label {
  fill: var(--map-overlay-ink);
  font-size: 11px;
  font-weight: 600;
  paint-order: stroke;
  stroke: var(--map-overlay-halo);
  stroke-width: 3;
  stroke-linejoin: round;
  pointer-events: none;
}
.geo-cursor {
  position: absolute;
  left: 14px;
  bottom: 54px;
  z-index: 7;
  pointer-events: none;
  padding: 2px 6px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--glass);
  color: var(--text);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  box-shadow: 0 2px 8px rgba(0, 0, 0, .14);
}
.geo-cursor[hidden] { display: none; }
.row input[type=text] {
  grid-column: 2 / 4;
  width: 100%; height: 26px; padding: 0 7px;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--surface); font: inherit; color: var(--text);
}
#i-exp-credits, #i-exp-review { font-size: 11.5px; }

/* 参数前的关键帧开关 */
.row.row-key { grid-template-columns: 18px 62px 1fr auto; gap: 6px; }
.key-toggle {
  width: 18px; height: 18px; padding: 0;
  border: 0; border-radius: 3px;
  background: transparent; color: var(--accent);
  font: inherit; font-size: 13px; line-height: 1; cursor: pointer;
}
.key-toggle:hover { background: var(--surface-3); }
.key-toggle.is-on { color: var(--accent); }
.row input[type=color] {
  grid-column: 2 / 4;
  width: 100%; height: 24px; padding: 0; border: 1px solid var(--line);
  border-radius: 5px; background: none; cursor: pointer;
}
.row input[type=file] {
  grid-column: 2 / 4;
  width: 100%;
  font: inherit;
  font-size: 11px;
  color: var(--muted);
}
.row input[type=file]::file-selector-button {
  height: 24px; margin-right: 8px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--surface); font: inherit; font-size: 11.5px; cursor: pointer;
}
.row input[type=number], .row select {
  grid-column: 2 / 4;
  width: 100%; height: 26px; padding: 0 7px;
  border: 1px solid var(--line); border-radius: 6px;
  background: var(--surface); font: inherit; color: var(--text);
}
.grid2 {
  display: grid;
  grid-template-columns: 72px 1fr;
  gap: 3px 8px;
  align-items: center;
  margin-bottom: 4px;
}
.grid2 label { font-size: 12px; color: var(--muted); }
.grid2 output { font-size: 11.5px; font-variant-numeric: tabular-nums; }

.layer-card {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 5px 8px 6px;
  margin-bottom: 6px;
}
.layer-card .head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 1px;
}
.layer-card .head b { font-size: 11.5px; }
.layer-card .head select {
  height: 22px; padding: 0 5px; border: 1px solid var(--line);
  border-radius: 6px; background: var(--surface); font: inherit; font-size: 11.5px;
}
/* 三层填充：把行距和控件高度压平，三张卡不再占掉大半屏 */
.layer-card .row { margin: 2px 0; gap: 6px; }
.layer-card .row > output { font-size: 10.5px; min-width: 40px; }
.layer-card .row input[type=range] { height: 16px; }
.layer-card .row input[type=color] { height: 20px; }
.layer-card .p { display: contents; }
.layer-card.is-off .body { opacity: .35; pointer-events: none; }

/* ---------------------------------------------------------------- 画布：进攻箭头本体 */

/* 填充带只作视觉，不吃事件（悬停判定交给底色路径） */
.aa-band { pointer-events: none; }

/* 底色路径负责命中判定 */
.aa-fill { pointer-events: fill; cursor: inherit; }

.aa-body { transition: opacity .12s ease; }

/* 编辑某个集合时，集合以外的元件：去色 + 压暗，明确表达"锁住了、不能编辑"。
   只降透明度会被误读成"还能编辑"，所以必须去色。 */
.aa.is-out { filter: grayscale(1); opacity: .42; }

/* 已融合的集合：成员的单体填充让位给融合体。
   不然并集填充之上还叠着 N 份单支填充，交叠处会出现 alpha 叠加的色斑。
   骨架不受影响 —— 编辑依旧逐支进行。 */
.aa.is-fused .aa-body { display: none; }
.ag-body { transition: opacity .12s ease; }

/* ---------------------------------------------------------------- 画布：骨架 */

.aa-skeleton { pointer-events: none; }

/* 关键：用 visibility 隐藏，子元素才能单独把"椭圆旋转热区"重新点亮 */
.aa-skeleton.is-hidden { visibility: hidden; }
.aa-skeleton.is-hidden .sk-rot-hit { visibility: visible; }

.sk { pointer-events: none; }

.sk-axis { stroke: var(--skel); stroke-width: 1.5; stroke-dasharray: 7 5; opacity: .75; }
.sk-seg { stroke: var(--skel); stroke-width: 2; }
.sk-head { fill: var(--skel); }
.sk-cross { stroke: var(--skel); stroke-width: 2; }
.sk-ellipse { stroke: var(--skel); stroke-width: 2; }
.sk-ctrl { stroke: var(--accent); stroke-width: 1.2; stroke-dasharray: 4 3; opacity: .7; }
.sk-neck-ring { stroke: var(--accent); stroke-width: 1.2; stroke-dasharray: 5 4; opacity: .5; }
.sk-neck-base { stroke: var(--skel); stroke-width: 1.6; stroke-dasharray: 6 4; opacity: .85; }

/* 椭圆旋转热区：不可见，但始终可以命中（骨架隐藏时也生效） */
.sk-rot-hit {
  stroke: rgba(0, 0, 0, 0);
  stroke-width: 16;
  pointer-events: visibleStroke;
}

.sk-handle {
  fill: #fff;
  stroke: var(--accent);
  stroke-width: 1.8;
  pointer-events: visible;
  transition: r .1s;
}
.sk-handle:hover { r: 8; }
.h-origin, .h-tip { fill: var(--accent); stroke: #fff; stroke-width: 2; }
.h-ellipse { fill: #fff; stroke: #7d8896; stroke-width: 1.8; }
.h-ellipse:hover { stroke: var(--accent); }
.h-neck { fill: #fff; stroke: var(--accent); stroke-width: 1.8; }
/* 小箭头底边宽度的控制点：画得比颈部调节点更醒目一点 */
.h-head { fill: #fff; stroke: var(--accent); stroke-width: 2.6; }
/* 行进模式：当前可见尖端的进度手柄（沿完整路径前后拖） */
.h-progress { fill: var(--accent); stroke: #fff; stroke-width: 2.4; }

/* 颈部调节点：平时看不到，鼠标靠近颈部才出现 */
.aa-skeleton .h-neck { display: none; }
.aa-skeleton.neck-visible .h-neck { display: block; }

.sk-hit { fill: transparent; stroke: none; pointer-events: visible; }

/* 网格（由 app.js 插入） */
.grid-line { stroke: var(--grid); stroke-width: 1; }
/* app.js 插进 <defs> 的那张网格：pattern 里的 path 用类名着色，主题一换就跟着走 */
#grid line, #grid path { stroke: var(--grid); }

/* ---------------------------------------------------------------- 集合：成员虚线框 */

.member-box { pointer-events: none; }
.member-box use { animation: box-in .12s ease-out; }
@keyframes box-in {
  from { stroke-opacity: 0; }
  to { stroke-opacity: .95; }
}

/* ---- 多支箭头（大底曲线版） ---- */
.ma-band { pointer-events: none; }
.ma-fill { pointer-events: fill; cursor: inherit; }
.ma-body { transition: opacity .12s ease; }
/* .ma.is-out 已去掉（选中单支箭头不再让多支箭头变灰）*/
.ma-skeleton { pointer-events: none; }
.ma-skeleton.is-hidden { visibility: hidden; }
.ma-skeleton.is-hidden .sk-ma-curve { visibility: hidden; }
.sk-ma-curve { stroke: #7d8896; stroke-width: 1.4; stroke-dasharray: 6 4; }
.ma-skeleton .sk-hit { fill: transparent; stroke: none; pointer-events: visible; }

/* ---- 模态对话框（新增多支箭头） ---- */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 200;
  background: var(--scrim);
  display: flex; align-items: center; justify-content: center;
}
.modal {
  background: var(--panel); border-radius: 10px; padding: 16px 18px 14px;
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  min-width: 280px;
}
.modal h3 { margin: 0 0 12px; font-size: 14px; font-weight: 600; color: var(--text); }
.modal .row { grid-template-columns: 76px 1fr auto; }
.modal input[type="number"] {
  width: 100%; padding: 4px 6px; border: 1px solid var(--line);
  border-radius: 5px; font: inherit; font-size: 13px;
}
.modal input[type="number"].invalid { border-color: #c8102e; }
.modal-err { min-height: 16px; color: #c8102e; font-size: 11px; margin: 4px 0 2px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }

/* ---- 文件操作 / 分享弹窗 ---- */
.file-dialog {
  width: min(430px, calc(100vw - 32px));
  min-width: 0;
}
.file-dialog .row {
  grid-template-columns: 64px minmax(0, 1fr);
  align-items: center;
  gap: 8px;
  margin-top: 10px;
}
.file-dialog .row input[type="text"] {
  width: 100%;
  height: 30px;
  padding: 0 8px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
}
.file-dialog .row input[type="text"]:focus {
  outline: none;
  border-color: var(--accent);
}
.dialog-note {
  margin-top: 9px;
  font-size: 11.5px;
  line-height: 1.55;
  color: var(--muted);
}
.dialog-note b { color: var(--text); }
.save-dest {
  display: grid;
  gap: 8px;
  margin-top: 12px;
}
.save-choice {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  cursor: pointer;
}
.save-choice input { margin: 2px 0 0; accent-color: var(--accent); }
.save-choice span { display: flex; flex-direction: column; gap: 2px; }
.save-choice b { color: var(--text); font-size: 12.5px; font-weight: 600; }
.save-choice small { color: var(--muted); font-size: 11px; }
.save-choice input:checked + span b { color: var(--accent); }
.open-seg { margin-top: 10px; }
.open-pane { margin-top: 12px; }
.cloud-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-height: 240px;
  overflow-y: auto;
}
.cloud-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--surface);
}
.cloud-row-main { flex: 1 1 auto; min-width: 0; }
.cloud-row-name {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text);
  font-size: 12px;
}
.cloud-row-time { color: var(--muted-faint); font-size: 10.5px; }
.cloud-empty { color: var(--muted-faint); font-size: 11.5px; padding: 8px 0; }
.share-lead { margin-top: 8px; color: var(--muted); font-size: 12px; line-height: 1.6; }
.share-summary {
  margin-top: 10px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--text);
  font-size: 12px;
  line-height: 1.65;
}
.share-summary b { font-weight: 600; }
#sec-multi .note { color: var(--muted-faint); font-size: 11px; line-height: 1.5; margin-top: 6px; }

.ma-skeleton .sk-ma-axis { stroke: var(--skel); stroke-width: 1; stroke-dasharray: 3 4; fill: none; }
.ma-member.is-dim { opacity: .28; }
.ma-member.is-focus .sk-handle { stroke-width: 2.6; }
.ma-skeleton.is-editing .ma-curve-hint { display: block; }

.member-len { margin-left: auto; color: var(--muted-faint); font-size: 11px; padding-right: 2px; }
.sec-head.sub { padding-top: 10px; }
.sec-head.sub h3 { font-size: 12px; color: #6b7480; }

/* ================================================================
   标图符号（第 4 类对象）—— 从 ../symbol-editor 并进来的
   ================================================================
   ⚠ 三条与 arrow-editor 原有样式划清界限的地方：

   1) 孵化场的 `.sk` 是**组级**类（骨架组写作 class="rt-skeleton sk"），
      而 arrow-editor 的 `.sk` 是**元素级**类（class="sk sk-axis"）。
      所以那边 `.sk { fill: none }` 那句在这里**不能照抄** —— 它的权重与
      `.sk-head { fill: var(--skel) }` 相同、又排在后面，会把箭头的小三角
      标记填成透明。改成按符号骨架组逐个作用域给 fill:none。

   2) 那边 `.sk-handle, .sk-hit { cursor: move }` 也不能全局照抄：
      arrow-editor 的手柄光标是 updateHover → cursorFor 写在 <svg> 内联样式上靠继承的，
      一旦元素自身声明了 cursor:move，箭头手柄的缩放双向箭头就全被压成"移动"。
      改成 `.sk .sk-handle`（只有符号骨架组里那个 `sk` 祖先）。

   3) 同理 .h-knot / .h-rx / .h-ry 的光标规则一并带上 `.sk ` 前缀。
   ---------------------------------------------------------------- */

/* 符号骨架组：整组 fill:none，补上孵化场那句 .sk{fill:none} 的作用 */
.rt-skeleton, .rg-skeleton, .rr-skeleton, .sn-skeleton,
.bd-skeleton, .cf-skeleton, .sg-skeleton, .fm-skeleton { fill: none; }

/* 手柄与元件体的鼠标图标：符号这一族统一出四方箭头 */
.sk .sk-handle, .sk .sk-hit { cursor: move; }

/* 符号骨架用的手柄样式（arrow-editor 原来没有 h-ctrl） */
.h-ctrl { fill: #fff; stroke: var(--accent); stroke-width: 1.8; }
/* 撤退箭头骨架里的提示元素 */
.sk-diameter { stroke: #c98a2e; stroke-width: 1.4; stroke-dasharray: 5 4; opacity: .85; }
.sk-b { fill: none; stroke: #7d8896; stroke-width: 2; stroke-dasharray: 6 4; opacity: .8; }
.sk-fixed { fill: #fff; stroke: #c98a2e; stroke-width: 1.6; }

/* ---------------------------------------------------------------- 封闭环形 */

.rg-line { fill: none; stroke-linejoin: round; stroke-linecap: round; }
.rg-hit { fill: none; stroke: transparent; pointer-events: stroke; cursor: move; }
.rg-skeleton { pointer-events: none; }
.rg-skeleton .sk-hit { fill: transparent; stroke: none; pointer-events: visible; }

/* ---------------------------------------------------------------- 撤退箭头 */

.rr-body { pointer-events: none; }
.rr-b { stroke-linejoin: round; }
.rr-hit { fill: none; stroke: transparent; pointer-events: stroke; cursor: move; }
.rr-skeleton { pointer-events: none; }
.rr-skeleton .sk-hit { fill: transparent; stroke: none; pointer-events: visible; }

/* ---------------------------------------------------------------- 狙击阵地 */

/* 两条半带都是填充路径；命中判定交给沿轴线的那条透明粗线 */
.sn-body { pointer-events: none; }
.sn-solid { stroke: none; }
.sn-tooth { stroke: none; }
.sn-hit { fill: none; stroke: transparent; pointer-events: stroke; cursor: move; }
.sn-skeleton { pointer-events: none; }
.sn-skeleton .sk-hit { fill: transparent; stroke: none; pointer-events: visible; }

/* ---------------------------------------------------------------- 分界线 */

.bd-body { pointer-events: none; }
.bd-run { stroke: none; }
.bd-dot { stroke: none; }
/* 直线段上处处可点，命中判定交给沿 A→B 的那条透明粗线 */
.bd-hit { fill: none; stroke: transparent; pointer-events: stroke; cursor: move; }
.bd-skeleton { pointer-events: none; }
.bd-skeleton .sk-hit { fill: transparent; stroke: none; pointer-events: visible; }

/* 端点吸附触发区：以别的分界线的 A、B 点为心画一圈 */
.snap-band-ring { fill: #c98a2e; fill-opacity: .13; stroke: #c98a2e; stroke-opacity: .45; stroke-width: 1.2; }

/* ---------------------------------------------------------------- 对峙线 */

.cf-body { pointer-events: none; }
.cf-wall { stroke: none; }
.cf-merlon { stroke: none; }
.cf-hit { fill: none; stroke: transparent; pointer-events: stroke; cursor: move; }
.cf-skeleton { pointer-events: none; }
.cf-skeleton .sk-hit { fill: transparent; stroke: none; pointer-events: visible; }

/* 线中（内部）控制点只能沿轴线滑动 —— 左右箭头图标。
   ⚠ 要写成两类的复合选择器：.sk-handle/.sk-hit 上的 cursor:move 与它同权重，
   单写 .h-knot 会因源码顺序而败给前面那条。 */
.sk .sk-handle.h-knot, .sk .sk-hit.h-knot { cursor: ew-resize; }

/* ---------------------------------------------------------------- 围困 / 歼敌地点 */

.sg-body { pointer-events: none; }
.sg-ring { stroke: none; }
.sg-x { stroke: none; }
/* 环之间有透明空隙、中心还有洞 —— 命中判定交给外椭圆 + X 的并集 */
.sg-hit { fill: transparent; stroke: none; pointer-events: all; cursor: move; }
.sg-skeleton { pointer-events: none; }
.sg-skeleton .sk-hit { fill: transparent; stroke: none; pointer-events: visible; }
/* 两个抓手职责不同，光标也分开报：
   h-rx 只改椭圆度 ⇒ 左右双向箭头；h-ry 只改整体大小 ⇒ 上下双向箭头。
   复合选择器权重够高，不必操心与 .sk-handle{cursor:move} 的先后。 */
.sg-skeleton .sk-handle.h-rx, .sg-skeleton .sk-hit.h-rx { cursor: ew-resize; }
.sg-skeleton .sk-handle.h-ry, .sg-skeleton .sk-hit.h-ry { cursor: ns-resize; }

/* ---------------------------------------------------------------- 战线展开 */

.fm-body { pointer-events: none; }
.fm-wave { stroke: none; }
.fm-shaft { stroke: none; }
.fm-head { stroke: none; }
.fm-hit { fill: none; stroke: transparent; pointer-events: stroke; cursor: move; }
.fm-skeleton { pointer-events: none; }
.fm-skeleton .sk-hit { fill: transparent; stroke: none; pointer-events: visible; }
/* 骨架里点出三个波峰、两个波谷 —— 一眼看出「两个完整循环」 */
.fm-skeleton .sk-crest { fill: #c98a2e; stroke: none; }
.fm-skeleton .sk-crest.is-mid { fill: none; stroke: #c98a2e; stroke-width: 1.6; }
.fm-skeleton .sk-trough { fill: #fff; stroke: #8593a3; stroke-width: 1.6; }

/* ---------------------------------------------------------------- 吸附标记 */

.snap-mark { pointer-events: none; }
/* 触发区色带：描边宽度就是 2×触发区宽度，与判定条件逐字对应 */
.snap-bands { pointer-events: none; }
.snap-band { fill: none; stroke: #c98a2e; stroke-opacity: .13; }
.snap-dot { fill: #fff; stroke: #c98a2e; stroke-width: 2; }
.snap-dir { stroke: #c98a2e; stroke-width: 2; stroke-dasharray: 4 3; }

/* 面板里导出的无量纲参数：等宽、可选中复制 */
.vec-out {
  width: 100%;
  padding: 6px 7px;
  font: 11px/1.45 ui-monospace, Menlo, monospace;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 6px;
  resize: vertical;
  white-space: pre;
  overflow: auto;
}
.vec-out:focus { outline: none; border-color: var(--accent); background: var(--surface); }

/* 面板里的小按钮 */
.row .mini { width: 100%; }
.dot.snap { border-color: #c98a2e; background: var(--snap-soft); }

/* ---------------------------------------------------------------- 整体旋转控制点 */

/* 常驻在覆盖层里，只此一个，位置跟着当前选中的元素走 */
.rot-layer { pointer-events: none; }
.rot-knob { pointer-events: none; }
/* 命中圈：不可见但吃事件（指针悬上去就出旋转光标） */
.rot-hit {
  fill: transparent;
  stroke: none;
  pointer-events: all;
  cursor: grab;
}
.rot-dot {
  fill: var(--surface);
  stroke: var(--accent);
  stroke-width: 2;
  pointer-events: none;
}
.rot-arc {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.6;
  stroke-dasharray: 4 3;
  opacity: .85;
  pointer-events: none;
}

/* ---------------------------------------------------------------- 元件旁文字框（注记） */

.desc-layer { pointer-events: none; }
.desc-text {
  fill: var(--text);
  font-family: inherit;
  font-weight: 500;
  paint-order: stroke;
  /* 描一圈底色，压在别的元件上时也读得清 */
  stroke: var(--canvas);
  stroke-width: 3px;
  stroke-linejoin: round;
  pointer-events: none;
  user-select: none;
}

/* 面板里的描述输入框 */
.desc-input {
  width: 100%;
  min-height: 46px;
  padding: 6px 7px;
  font: inherit;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 6px;
  resize: vertical;
}
.desc-input:focus { outline: none; border-color: var(--accent); background: var(--surface); }
.desc-input:disabled { opacity: .45; }
/* 兼容旧的描述结构：现在由 .panel .row.desc-row 接管两列布局 */
.desc-check {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
}
.desc-check input { accent-color: var(--accent); }

/* ---------------------------------------------------------------- 二级菜单：队伍样式 */

.bar-team {
  align-items: flex-start;
  row-gap: 6px;
}
.team-list { display: flex; flex-wrap: wrap; gap: 8px; flex: 1 1 auto; }
/* 样式栏左侧的「＋」：只留一个方形按钮 */
#btn-team-add {
  width: 30px;
  padding: 0;
  justify-content: center;
  font-size: 16px;
  line-height: 1;
}
.team-list:empty::after {
  content: '还没有队伍样式 —— 点左侧的 + 新建一条';
  font-size: 11.5px;
  color: var(--muted-faint);
  padding: 6px 0;
}

/* 一行 = 名称（可改） + 样式 + 删除。色块不在这行 —— 颜色在样式卡片里定义 */
.team-row {
  display: flex;
  align-items: center;
  gap: 2px;
  height: 30px;
  padding: 0 3px 0 2px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--surface);
}
.team-row.is-open { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(47, 128, 237, .18); }
.team-name {
  /* 宽度由 JS 按文字实测设置（fitNameInput）—— 名字长短差很多时，
     固定宽度要么空一大截、要么把字截掉。所以这里只给上下限兜底。 */
  width: 64px;
  max-width: 220px;
  min-width: 40px;
  height: 24px;
  padding: 0 7px;
  border: 1px solid transparent;
  border-radius: 5px;
  background: transparent;
  color: var(--text);
  font: inherit;
  font-size: 12.5px;
}
.team-name:hover { background: var(--surface-2); border-color: var(--line); }
.team-name:focus { outline: none; background: var(--surface-2); border-color: var(--accent); }
.team-btn {
  height: 24px;
  padding: 0 9px;
  border: 1px solid transparent;
  border-radius: 5px;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}
.team-btn:hover { background: var(--surface-2); border-color: var(--line-strong); color: var(--text); }
.team-del {
  width: 24px;
  padding: 0;
  font-size: 14px;
  line-height: 1;
}
.team-del:hover { color: var(--danger); }

/* 元件面板里的「队伍样式」下拉 */
.team-pick { padding: 0; margin: 7px 0 0; grid-template-columns: 62px 1fr; }
.team-pick[hidden] { display: none; }
.team-pick select {
  grid-column: 2 / 3;
  height: 26px;
  padding: 0 7px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
}
.team-pick select:focus { outline: none; border-color: var(--accent); }

/* ---------------------------------------------------------------- 队伍样式卡片 */

.ts-modal { min-width: 340px; max-width: 460px; max-height: 82vh; display: flex; flex-direction: column; }
.ts-body { overflow-y: auto; margin: 0 -6px; padding: 0 6px; }
.ts-body section { padding: 9px 0; border-bottom: 1px solid var(--line); }
.ts-body section:last-child { border-bottom: none; }
.ts-body h4 {
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  letter-spacing: .04em;
}
.ts-body .note { margin: -2px 0 4px; font-size: 11px; color: var(--muted-faint); line-height: 1.5; }
.ts-duo { display: flex; gap: 18px; padding: 2px 0 6px; }
.ts-swatch { display: flex; flex-direction: column; align-items: center; gap: 4px; cursor: pointer; }
.ts-swatch input[type=color] {
  width: 46px;
  height: 30px;
  padding: 1px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--surface);
  cursor: pointer;
}
.ts-swatch span { font-size: 11px; color: var(--muted); }

/* 卡片里给控件加"别名/适用范围"的小注 —— 同一个字段在不同符号的面板里叫法不一样，
   不点明的话会以为"改了没反应" */
.ts-body .alias {
  margin-left: 5px;
  font-size: 10.5px;
  font-weight: 400;
  color: var(--muted-faint);
}

/* ---------------------------------------------------------------- 时间轴 */
/*
 * 控件与轨道放在同一块面板里（AE 式），面板本身仍是 #bar-timeline 这一行，
 * 由导航的 PANELS 开关控制收放。
 *
 * 结构：左边固定宽度的元件名，右边横向滚动的轨道区。
 * 播放头是 .tl-content 里的绝对定位元素，所以它和刻度用同一套像素坐标。
 */

.bar-timeline { align-items: flex-start; row-gap: 6px; }

/* 动画二级菜单分两行：第一行控制，第二行参数 */
.tl-row {
  flex: 0 0 100%;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  min-width: 0;
}
.tl-settings-wrap { flex: 0 0 auto; }
.tl-settings-card {
  min-width: 280px;
  padding: 8px;
  gap: 6px;
}
.tl-set-row {
  display: grid;
  grid-template-columns: 58px auto 1fr;
  align-items: center;
  gap: 6px;
}
.tl-set-label {
  font-size: 11.5px;
  color: var(--muted);
  white-space: nowrap;
}
.tl-set-row input[type=number],
.tl-set-row input[type=datetime-local],
.tl-set-row select {
  height: 24px;
  padding: 0 5px;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: 11.5px;
  justify-self: start;
}
.tl-set-row input[type=number] { width: 4.6em; }
.tl-set-row.tl-set-wide input[type=datetime-local] {
  width: 13.5em;
  grid-column: 2 / span 2;
}
.tl-set-row.tl-set-wide select {
  width: 9em;
  grid-column: 2 / span 2;
}
.tl-set-unit {
  font-size: 11px;
  color: var(--muted-faint);
}
/* 缩放滑条右侧的一组读数 */
.tl-readouts {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  flex: 0 0 auto;
}
.tl-readout {
  font-size: 11.5px;
  color: var(--muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.tl-readout + .tl-readout::before {
  content: '·';
  margin-right: 8px;
  color: var(--muted-faint);
}
#o-tl-zoom { min-width: 1.8em; }

.tl-clock {
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  color: var(--text);
  padding: 0 4px;
  min-width: 4.6em;
}

.tl-body {
  flex: 0 0 100%;
  display: flex;
  margin-top: 6px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--surface);
  overflow: hidden;
  max-height: 220px;
}

.tl-left {
  flex: 0 0 132px;
  border-right: 1px solid var(--line);
  background: var(--surface-2);
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.tl-corner {
  height: 34px;
  line-height: 24px;
  padding: 0 8px;
  font-size: 10.5px;
  color: var(--muted-faint);
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}

.tl-names {
  overflow-y: auto;
  flex: 1 1 auto;
  /* 只保留右侧轨道区的一根纵向滚动条；左侧仍可滚，但滚动条隐藏 */
  scrollbar-width: none;
}
.tl-names::-webkit-scrollbar { width: 0; height: 0; }

.tl-name {
  display: flex;
  align-items: center;
  gap: 1px;
  height: 24px;
  padding: 0 5px;
  font-size: 11.5px;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
  cursor: pointer;
}
.tl-name:hover { background: var(--surface-3); color: var(--text); }
.tl-name.is-current { background: var(--accent-soft); color: var(--text); }

.tl-name-text {
  flex: 1 1 auto;
  min-width: 0;
  padding-left: 3px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ‹ ◆ ›：跳上一个 / 加删关键帧 / 跳下一个 */
.tl-nav, .tl-diamond {
  flex: 0 0 auto;
  width: 15px;
  height: 18px;
  padding: 0;
  border: 0;
  border-radius: 3px;
  background: transparent;
  color: var(--muted-faint);
  font: inherit;
  line-height: 1;
  cursor: pointer;
}
.tl-nav:hover, .tl-diamond:hover { background: var(--surface-3); color: var(--text); }
.tl-nav:disabled { opacity: .28; cursor: default; }
/* 关键帧开关：空心 ◇ / 播放头正好在帧上时实心 ◆（都是蓝色） */
.tl-diamond { font-size: 12px; line-height: 1; color: var(--accent); }
.tl-diamond.is-on { color: var(--accent); }

/* 元件行最前的小三角：展开/收起运动参数 */
.tl-expander {
  flex: 0 0 auto;
  width: 12px; height: 18px;
  padding: 0; border: 0; border-radius: 3px;
  background: transparent; color: var(--muted-faint);
  font: inherit; font-size: 9px; line-height: 1;
  cursor: pointer;
}
.tl-expander:hover { background: var(--surface-3); color: var(--text); }

/* 参数行：比元件行矮一点，与右侧参数轨道同高 */
.tl-name.tl-param {
  height: 20px;
  padding-left: 18px;
  font-size: 10.5px;
}
.tl-param-label {
  flex: 1 1 auto;
  min-width: 0;
  padding-left: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tl-param-diamond { font-size: 11px; }

.tl-right {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* 刻度固定在轨道区顶部，不参与纵向滚动 */
.tl-ruler-clip {
  flex: 0 0 34px;
  overflow: hidden;
  border-bottom: 1px solid var(--line);
  background: var(--surface-2);
}

.tl-scroll {
  flex: 1 1 auto;
  overflow-x: hidden;   /* 横向只走自绘滑槽，避免再冒出一根原生横条 */
  overflow-y: auto;
  min-width: 0;
  min-height: 0;
  scrollbar-width: thin;
  scrollbar-color: var(--line-strong) var(--surface-2);
}
/* 纵向保留原生滚动条，横向彻底隐藏（仍可用 scrollLeft 程序化滚动） */
.tl-scroll::-webkit-scrollbar { width: 10px; height: 0; }
.tl-scroll::-webkit-scrollbar-track { background: var(--surface-2); }
.tl-scroll::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border-radius: 5px;
}
.tl-scroll::-webkit-scrollbar-thumb:hover { background: var(--muted-faint); }
.tl-scroll::-webkit-scrollbar:horizontal { display: none; }
.tl-scroll::-webkit-scrollbar-corner { background: var(--surface-2); }

/* 自绘横槽占 10px；左列补同样的底边，避免滚到底时左右行错位 */
.tl-body.has-hscroll .tl-left { padding-bottom: 10px; }

/* 自定义横向滚动条：轨道区装不下整条时长时常显，任何平台都看得见 */
.tl-hscroll {
  flex: 0 0 10px;
  position: relative;
  background: var(--surface-2);
  border-top: 1px solid var(--line);
  cursor: pointer;
}
.tl-hscroll[hidden] { display: none; }
.tl-hthumb {
  position: absolute;
  top: 2px;
  bottom: 2px;
  min-width: 24px;
  border-radius: 3px;
  background: var(--line-strong);
  cursor: grab;
}
.tl-hthumb:hover { background: var(--muted-faint); }
.tl-hthumb.is-dragging { background: var(--muted); cursor: grabbing; }

.tl-content {
  position: relative;
  min-height: 100%;
}

.tl-ruler {
  position: relative;
  /* 上面放刻度时间，下面放标记名称 —— 两行才不会叠在一起 */
  height: 34px;
}

.tl-tick {
  position: absolute;
  top: 0;
  bottom: 0;
  border-left: 1px solid var(--line);
  pointer-events: none;
}
.tl-tick span {
  position: absolute;
  left: 4px;
  top: 3px;
  font-size: 10px;
  color: var(--muted-faint);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.tl-mark {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0;
  border-left: 1px dashed var(--accent);
  pointer-events: none;
}
.tl-mark span {
  position: absolute;
  left: 3px;
  bottom: 2px;
  font-size: 10px;
  color: var(--accent);
  white-space: nowrap;
}

.tl-lane {
  position: relative;
  height: 24px;
  border-bottom: 1px solid var(--line);
}
.tl-lane.is-current { background: var(--accent-soft); }

/* 元件行的出入点长条：两端拖 in/out，条身拖整体（关键帧跟随） */
.tl-bar {
  position: absolute;
  top: 50%;
  height: 12px;
  margin-top: -6px;
  box-sizing: border-box;
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: 3px;
  overflow: hidden;
  cursor: grab;
  z-index: 0;
}
.tl-bar:active { cursor: grabbing; }
.tl-bar-fade {
  position: absolute;
  top: 0;
  bottom: 0;
  pointer-events: none;
  opacity: .7;
}
.tl-bar-fade-in {
  left: 0;
  background: repeating-linear-gradient(135deg,
    transparent 0 3px, var(--surface) 3px 4px);
}
.tl-bar-fade-out {
  right: 0;
  background: repeating-linear-gradient(45deg,
    transparent 0 3px, var(--surface) 3px 4px);
}
.tl-bar-edge {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 7px;
  cursor: ew-resize;
  z-index: 2;
}
.tl-bar-edge::before {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 3px;
  width: 1px;
  background: var(--accent);
}
.tl-bar-edge:hover::before { left: 2px; width: 3px; }
.tl-bar-edge-in { left: 0; }
.tl-bar-edge-out { right: 0; }

.tl-key {
  position: absolute;
  z-index: 1;
  top: 50%;
  width: 10px;
  height: 10px;
  margin-left: -5px;
  margin-top: -5px;
  background: var(--accent);
  border: 1px solid var(--surface);
  transform: rotate(45deg);
  cursor: ew-resize;
  box-sizing: border-box;
}
.tl-key:hover { background: var(--accent); }
/* 关键帧：实心蓝色菱形；当前时刻/选中用蓝色描边强调 */
.tl-key.is-current { background: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.tl-key.is-picked { background: var(--accent); box-shadow: 0 0 0 2px var(--accent); }
/* 多选时再叠一圈外环，和单选的 2px 区分开 */
.tl-key.is-picked.is-current,
.tl-key.is-picked { box-shadow: 0 0 0 2px var(--accent), 0 0 0 4px var(--accent-soft); }

/* 框选：固定在视口上的半透明矩形 */
.tl-marquee {
  position: fixed;
  z-index: 95;
  border: 1px solid var(--accent);
  background: rgba(47, 128, 237, .12);
  pointer-events: none;
}
/* 吸附参考线：贯穿轨道区的一条竖虚线 */
.tl-snapline {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0;
  border-left: 1px dashed var(--accent);
  pointer-events: none;
  z-index: 4;
}

.tl-lane.tl-param-lane { height: 20px; }
.tl-param-key {
  width: 8px; height: 8px;
  margin-left: -4px; margin-top: -4px;
}

.tl-playhead {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0;
  border-left: 1px solid var(--danger);
  pointer-events: none;
  z-index: 2;
}
.tl-playhead::before {
  content: '';
  position: absolute;
  top: 0;
  left: -4px;
  border: 4px solid transparent;
  border-top-color: var(--danger);
}

/* ---------------------------------------------------------------- 创建符号：兵种缩略图 */

#bar-unit { align-items: flex-start; }
.unit-palette {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(64px, 1fr));
  gap: 6px;
  width: 100%;
  max-width: 100%;
}
.unit-chip {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  min-width: 0; padding: 5px 3px 4px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
.unit-chip:hover { border-color: var(--accent); background: var(--accent-soft); }
.unit-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.unit-chip-art {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 36px;
}
.unit-chip-art img { display: block; max-width: 54px; max-height: 34px; }
.unit-chip-name {
  display: block; width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 10.5px; line-height: 1.25; text-align: center; color: var(--muted);
}
.unit-chip:hover .unit-chip-name { color: var(--accent); }
.unit-palette-note {
  flex: 0 0 auto;
  width: 100%;
  margin-top: 2px;
  font-size: 10.5px; line-height: 1.35; color: var(--muted-faint);
}

/* ---------------------------------------------------------------- 单位符号：面板与画布 */

#sec-unit .unit-sidc {
  font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 10px; color: var(--muted-faint);
  cursor: help;
}
#sec-unit .unit-preview-row { align-items: start; }
.unit-preview {
  grid-column: 2;
  display: flex; align-items: center; justify-content: center;
  min-height: 68px; padding: 6px;
  border: 1px solid var(--line);
  border-radius: 7px;
  /* milsymbol 的标准符号按白底黑字绘制；预览固定浅底，深色面板下也看得清。 */
  background: #fbfcfe;
  overflow: hidden;
}
.unit-preview img {
  display: block; max-width: 100%; max-height: 96px;
}
.unit-preview img[hidden] { display: none; }
.unit-preview-empty { font-size: 11px; color: var(--muted); }
.unit-checks {
  grid-column: 2;
  display: flex; flex-wrap: wrap; gap: 3px 11px;
}
.unit-checks label {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11.5px; color: var(--muted);
}
#sec-unit .note { margin: 7px 0 0; }

.us-art { pointer-events: none; }
/* 画布上的文字按明暗主题换色；导出克隆不加载这段 CSS，仍保留 milsymbol 的黑字。 */
.us-art text {
  fill: var(--text);
  stroke: var(--panel);
  stroke-width: 3px;
  stroke-linejoin: round;
  paint-order: stroke;
}
.us-hit { pointer-events: all; cursor: move; }
.us-skeleton { pointer-events: none; fill: none; }
.us-sk-box {
  fill: none; stroke: var(--accent); stroke-width: 1.4;
  stroke-dasharray: 5 4; opacity: .9;
}
.us-sk-anchor { fill: #fff; stroke: var(--accent); stroke-width: 1.6; }
