/* ============================================================================
 * XBAOS海上空战模拟 样式表
 *
 * 视觉基调：仪表板，而不是"霓虹 Cyber 面板"。
 * 上一版大厅用了高饱和荧光绿 + 发光描边 + 到处是边框小盒子，
 * 观感上"AI 味"很重 —— 密集的荧光描边与阴影会把界面推向"合成感"。
 * 本轮改成一套更接近真实航空仪表的配色：
 *   · 底色是冷灰墨绿（哑光仪表外壳），不是纯黑；
 *   · 文字是暖白（#d6dcd6），不是发光绿；
 *   · 强调色是**黄铜色**（#d9b166），只用在"开始任务"这一个动作上；
 *   · 取消绝大多数 text-shadow / box-shadow 光晕，靠间距与层次分信息，
 *     而不是靠发光 —— 这是"看起来像人做的"最关键的一条。
 * 设计约束（沿用，都是明确要求）：
 *   1) 全站不使用圆角 —— 任何 border-radius 都为 0，直角是这套 UI 的语言；
 *   2) 字体优先思源黑体 "Noto Sans SC"，且**只声明字体栈、不嵌入字体文件**；
 *   3) 界面文案全部中文，间隔符一律用空格，不使用 "·"；
 *   4) 大厅：标题在顶部正中，功能按钮全部排在页面底部一行，
 *      具体数据与说明一律收进二级菜单（抽屉），"开始任务"在最右侧，
 *      所有底部按钮等高。
 *
 * 注意：#hud 是 Canvas2D，全部飞行仪表都画在那里，本文件只负责菜单/结算层。
 * ========================================================================== */

:root {
  /* ---- 通用语义色（HUD 与菜单共用） ---- */
  --green: #8dff9f;             /* 座舱荧光绿：保留给飞行 HUD 与告警 */
  --green-dim: rgba(141, 255, 159, 0.56);
  --green-line: rgba(141, 255, 159, 0.22);
  --amber: #ffc247;
  --red: #ff5b46;
  --ally: #7fe6ff;

  /* ---- 大厅 / 菜单的第二套色（哑光仪表） ---- */
  --ink: #0b0f10;               /* 冷灰墨绿底 */
  --ink-2: #111617;
  --panel: rgba(17, 22, 23, 0.92);
  --text: #d6dcd6;              /* 暖白正文 */
  --muted: rgba(168, 180, 172, 0.62);
  --line: rgba(196, 208, 198, 0.14);
  --line-2: rgba(196, 208, 198, 0.26);
  --brass: #d9b166;             /* 黄铜：只给"开始任务" */
  --brass-dim: rgba(217, 177, 102, 0.42);
  --steel: #8fb0a8;             /* 冷钢绿：次级强调 */
  --edge: 40px;                 /* 大厅四周安全内缩 */

  --sans: "Noto Sans SC", "Source Han Sans SC", "思源黑体", "PingFang SC",
          "HarmonyOS Sans SC", "Microsoft YaHei", "Hiragino Sans GB",
          system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Noto Sans SC", "Roboto Mono", Consolas, "SF Mono", Menlo,
          ui-monospace, monospace;
}

* { box-sizing: border-box; border-radius: 0; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  background: var(--ink);
  color: var(--text);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
}

#app {
  position: fixed;
  inset: 0;
  overflow: hidden;
  background: #060a10;
}

#gl, #hud {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
/* touch-action:none：空白处按下画布 = 浮动摇杆入口。
   不禁掉的话，Android WebView 的手势识别会在按下后立刻接管这次触摸
   并对指针发 pointercancel —— 浮动摇杆刚搬家就被"松手"重置回原位。
   画布上的所有手势本来都由游戏逻辑接管，浏览器手势没有存在价值。 */
#gl { z-index: 1; touch-action: none; }
#hud { z-index: 2; pointer-events: none; }

/* 关键：#ui 必须是定位元素，z-index 才生效。
   若把它留成 static，z-index 会被忽略，两块 canvas（z-index 1/2）
   会盖在整个 UI 层之上 —— 表现为「菜单看得见但按钮点不到」。 */
#ui {
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;      /* 空白处不拦截，让点击穿透到画布（用于锁定鼠标） */
}

.hidden { display: none !important; }

/* ========================================================== 遮罩面板 */
.panel {
  position: absolute;
  inset: 0;
  pointer-events: auto;      /* 面板本身要能接收点击（父层 #ui 已设为 none） */
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  padding: 28px 20px;
  background:
    radial-gradient(ellipse 120% 80% at 50% 0%, rgba(120, 140, 130, 0.10), transparent 62%),
    rgba(8, 11, 12, 0.78);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  animation: panelIn 0.24s cubic-bezier(.2, .8, .3, 1);
}

/* 入场动效只用位移与缩放，**刻意不碰 opacity**：
   一旦某些环境（动效节流、合成器未启动、reduced-motion 强制）不推进关键帧，
   用 opacity 做的入场就会把面板永久留在 opacity:0 —— 表现为「点了没反应」。
   位移类动画即使停在第 0 帧，元素依然完全可见可点。 */
@keyframes panelIn {
  from { transform: translateY(12px) scale(0.995); }
  to   { transform: none; }
}

.panel-inner {
  width: min(1020px, 100%);
  margin: auto;
  padding: 34px 38px 30px;
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 56px);
  max-height: calc(100dvh - 56px);
  /* 内容超出（手机横屏的结算页等）时在框内滚动，不再溢出边框外 */
  overflow-y: auto;
  overscroll-behavior: contain;
  border: 1px solid var(--line);
  background: var(--panel);
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.66);
  position: relative;
}
.panel-inner.narrow { width: min(520px, 100%); }

/* 面板顶部一条黄铜细线，取代上一版的"四角准星"装饰：
   装饰元素越少、越克制，界面越不像自动生成的。 */
.panel-inner::before {
  content: '';
  position: absolute;
  left: 38px; right: 38px; top: 0;
  height: 2px;
  background: var(--brass-dim);
  pointer-events: none;
}

h1 {
  margin: 0 0 6px;
  font-size: clamp(26px, 4.1vw, 42px);
  font-weight: 700;
  letter-spacing: 0.03em;
  color: #eef3ec;
}
h1 .accent { color: var(--brass); }

h2 {
  margin: 0 0 12px;
  font-size: 12px;
  font-family: var(--mono);
  letter-spacing: 0.22em;
  font-weight: 600;
  color: var(--steel);
}
h3 {
  margin: 18px 0 10px;
  font-size: 12px;
  letter-spacing: 0.18em;
  color: var(--steel);
  font-weight: 600;
}

.subtitle {
  margin: 0;
  font-size: 12.5px;
  letter-spacing: 0.16em;
  color: var(--muted);
}
.accent { color: var(--brass); }

/* ==========================================================================
 * 入场大厅
 * 布局（本轮明确要求）：
 *   · 标题在顶部正中 —— 品牌小字 / 主标题 / 副标题，居中对齐，不加外框；
 *   · 中间整块留给 3D 巡航画面；
 *   · 底部一行按钮：任务简报 / 键位操作 / 战绩记录 / 系统设置 / 开始任务，
 *     **全部等高**，"开始任务"在最右侧并作为唯一的实心主按钮；
 *   · 兵力编成、交战要点、历史战绩等"具体数据与说明"一律收进二级菜单
 *     （抽屉），主页只留标题和一行按钮。
 * ========================================================================== */

.panel.lobby {
  display: block;
  padding: 0;
  overflow: hidden;
  /* 上下压暗、中间通透：让标题与按钮条"浮"在 3D 画面上，
     而不是再盖一层半透明黑玻璃（那会让画面发灰、更显合成感）。 */
  background:
    linear-gradient(180deg,
      rgba(6, 9, 10, 0.86) 0%,
      rgba(6, 9, 10, 0.60) 13%,
      rgba(6, 9, 10, 0.20) 27%,
      rgba(6, 9, 10, 0.00) 42%,
      rgba(6, 9, 10, 0.00) 50%,
      rgba(6, 9, 10, 0.66) 76%,
      rgba(6, 9, 10, 0.92) 100%);
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.lobby-inner {
  position: relative;
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  box-shadow: none;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: stretch;
}
.lobby-inner::before,
.lobby-inner::after { display: none; }

/* -------------------------------------------------------- 顶部：标题 */
.lb-head {
  flex: 0 0 auto;
  padding: calc(var(--edge) + 16px) 20px 0;
  text-align: center;
  pointer-events: none;
}
.lb-brand {
  margin: 0 0 18px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.54em;
  text-indent: 0.54em;        /* 补掉末字字距，视觉上才是真居中 */
  color: var(--steel);
}
.lb-title {
  margin: 0;
  font-size: clamp(30px, 4.4vw, 52px);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-indent: 0.12em;
  color: #eef3ec;
  /* 刻意不加 text-shadow：发光描边是"合成感"的头号来源，
     真实仪表的面板字是印上去的，不会自己发光。 */
  text-shadow: none;
}
.lb-sub {
  /* 副标题「座舱第一视角 制空权争夺」已按要求删除；保留类定义只是为了让
     旧缓存页面/历史备份里的同一份 DOM 不至于变成裸文本，实际已无节点使用。 */
  display: none;
}
/* 标题下方一小段黄铜分隔线：唯一的装饰，替代上一版满屏的装饰框 */
.lb-rule {
  display: block;
  width: 44px;
  height: 2px;
  margin: 22px auto 0;
  background: var(--brass-dim);
}

/* ---------------------------------------------------- 底部：按钮一条 */
.lb-bottom {
  flex: 0 0 auto;
  /* 底部安全区：--edge-16 可能算出负值，用 max 兜底；再叠加全面屏安全边距，
     避免沉浸式 WebView 里最后一行按钮被手势条/屏幕圆角压住（表现为"按不到"）。 */
  padding: 0 0
    calc(max(var(--edge) - 16px, 8px) + env(safe-area-inset-bottom, 0px));
}

.lb-dock {
  display: flex;
  align-items: stretch;            /* 关键：靠拉伸保证所有按钮绝对等高 */
  gap: 1px;                        /* 1px 缝代替各自描边，避免"一排小盒子" */
  /* 高度随视口连续缩放：84px 是桌面基准，矮视口（手机横屏/小窗）自动压到 54px 下限 */
  height: clamp(54px, 12vh, 84px);
  margin: 0 var(--edge);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  background: rgba(9, 13, 14, 0.62);
}

.lb-btn {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  height: 100%;                    /* 等高（由 align-items:stretch 兜底） */
  padding: 0 22px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 6px;
  cursor: pointer;
  border: none;
  border-left: 1px solid var(--line);
  background: transparent;
  color: var(--text);
  font-family: var(--sans);
  text-align: left;
  outline: none;
  transition: background .15s;
}
.lb-btn:first-child { border-left: none; }
.lb-btn:hover { background: rgba(196, 208, 198, 0.07); }
.lb-btn:active { background: rgba(196, 208, 198, 0.13); }

/* 悬停时左侧亮起一条 2px 黄铜细线 —— 全站仅此一处动效 */
.lb-btn::after {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 2px;
  background: var(--brass);
  transform: scaleY(0);
  transform-origin: 50% 50%;
  transition: transform .18s cubic-bezier(.2, .8, .3, 1);
}
.lb-btn:hover::after { transform: scaleY(1); }

.lb-btn .lb-t {
  display: block;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.10em;
  color: #e6ece6;
}
.lb-btn .lb-d {
  display: block;
  max-width: 100%;
  font-size: 11px;
  letter-spacing: 0.03em;
  color: rgba(158, 172, 164, 0.62);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 「开始任务」：最右侧，唯一的实心主按钮（黄铜底 + 深色字） */
.lb-btn.lb-go {
  flex: 0 0 auto;
  min-width: 218px;
  align-items: center;
  text-align: center;
  background: var(--brass);
  border-left: none;
}
.lb-btn.lb-go .lb-t {
  font-size: 17px;
  letter-spacing: 0.26em;
  text-indent: 0.26em;
  color: #17130a;
}
.lb-btn.lb-go .lb-d { color: rgba(23, 19, 10, 0.60); }
.lb-btn.lb-go:hover { background: #e5c079; }
.lb-btn.lb-go:active { background: #c8a259; }
.lb-btn.lb-go::after { display: none; }

.lb-hint {
  margin: 14px var(--edge) 0;
  text-align: center;
  font-size: 12px;
  letter-spacing: 0.05em;
  color: rgba(148, 162, 154, 0.66);
}
.lb-hint kbd {
  font-family: var(--mono);
  font-size: 11px;
  padding: 1.5px 6px;
  border: 1px solid var(--line);
  color: rgba(200, 216, 206, 0.80);
  background: rgba(196, 208, 198, 0.05);
  margin: 0 2px;
}

/* 页脚：品牌署名 + 官网外链（左对齐 / 右对齐各一） */
.lb-foot {
  margin: 12px var(--edge) 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  font-size: 11px;
  letter-spacing: 0.10em;
  color: rgba(138, 150, 144, 0.55);
}
.lb-foot a {
  color: rgba(168, 188, 178, 0.70);
  text-decoration: none;
  border-bottom: 1px solid var(--line);
  padding-bottom: 1px;
}
.lb-foot a:hover { color: var(--brass); border-color: var(--brass-dim); }

/* ----------------------------------------------- 抽屉里的数据块 */
.force-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  line-height: 1.9;
}
.force-k {
  font-size: 12.5px;
  letter-spacing: 0.12em;
  min-width: 48px;
}
.force-k.ally { color: var(--steel); }
.force-k.foe  { color: #d98a72; }
.force-v {
  font-size: 20px;
  font-weight: 700;
  color: #eef3ec;
}
.force-u { font-size: 11px; color: var(--muted); }
.force-note {
  margin: 10px 0 0;
  font-size: 11.5px;
  line-height: 1.65;
  color: var(--muted);
  border-top: 1px solid var(--line);
  padding-top: 9px;
}

/* ============================================================== 按钮 */
.actions {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}
.actions .btn { flex: 1 1 auto; }

.btn {
  font-family: var(--sans);
  font-size: 14.5px;
  font-weight: 600;
  letter-spacing: 0.10em;
  padding: 13px 32px;
  border: 1px solid var(--line-2);
  background: rgba(196, 208, 198, 0.05);
  color: #dbe2db;
  cursor: pointer;
  transition: background .16s, border-color .16s;
  outline: none;
}
.btn:hover {
  background: rgba(196, 208, 198, 0.12);
  border-color: rgba(196, 208, 198, 0.42);
}
.btn:active { background: rgba(196, 208, 198, 0.18); }

/* 主按钮 = 黄铜实心（与大厅的「开始任务」同一套语言） */
.btn.primary {
  background: var(--brass);
  border-color: var(--brass);
  color: #17130a;
  font-weight: 700;
}
.btn.primary:hover { background: #e5c079; border-color: #e5c079; }

.btn.ghost {
  border-color: var(--line);
  color: rgba(180, 194, 186, 0.72);
  background: transparent;
}
.btn.ghost:hover {
  border-color: var(--line-2);
  color: #e0e8e1;
}

.btn.big {
  font-size: 20px;
  letter-spacing: 0.30em;
  padding: 16px 62px 16px 66px;   /* 左侧多留，抵消末端字距 */
  min-width: 260px;
}

.hint {
  font-size: 12px;
  color: var(--muted);
  font-family: var(--mono);
  letter-spacing: 0.02em;
}
.hint kbd, .lb-list kbd {
  font-family: var(--mono);
  font-size: 11px;
  padding: 1.5px 6px;
  border: 1px solid var(--line);
  color: rgba(200, 216, 206, 0.80);
  background: rgba(196, 208, 198, 0.05);
  margin: 0 2px;
}

/* ============================================================== 抽屉 */
.sheet-layer {
  position: absolute;
  inset: 0;
  z-index: 20;
  /* 抽屉层挂在 pointer-events:none 的 #ui 直属下（暂停页也要能开设置），
     必须自己把点击接回来，否则"看得见但点不到"。
     关闭按钮 / 表单控件在层内，随层一起恢复可点。 */
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 24px;
  background: rgba(2, 6, 10, 0.74);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  animation: panelIn 0.18s ease-out;
}

.sheet {
  display: none;
  width: min(760px, 100%);
  max-height: min(80vh, 760px);
  flex-direction: column;
  border: 1px solid var(--line);
  background: var(--panel);
  box-shadow: 0 22px 70px rgba(0, 0, 0, 0.7);
}
.sheet.open { display: flex; }

.sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--line);
  background: rgba(196, 208, 198, 0.035);
}
.sheet-head h2 {
  margin: 0;
  font-size: 14px;
  letter-spacing: 0.22em;
  color: #e6ece6;
  /* 标题不可选中：开发者模式要在 3 秒内连点 5 次，双击会带出选中高亮 */
  user-select: none;
}
.sheet-close {
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0.14em;
  padding: 7px 16px;
  cursor: pointer;
  border: 1px solid var(--line-2);
  background: transparent;
  color: #dbe2db;
  outline: none;
}
.sheet-close:hover {
  background: rgba(196, 208, 198, 0.12);
  border-color: rgba(196, 208, 198, 0.46);
}

.sheet-body {
  padding: 18px 22px 22px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.sheet-body h3:first-child { margin-top: 0; }
/* 键位表有三段、共 14 行：把段间距和行距收紧一点，
   720p 下才不用滚动就能一眼看全（低于这个高度仍然可滚动）。 */
.sheet-body h3 { margin: 14px 0 8px; }
.sheet-body .keys { gap: 6px 16px; }
.sheet-lead {
  margin: 0 0 6px;
  font-size: 13px;
  line-height: 1.75;
  color: rgba(220, 228, 221, 0.88);
  border-left: 2px solid var(--brass-dim);
  padding-left: 12px;
}
.sheet-note {
  margin: 16px 0 0;
  font-size: 11.5px;
  line-height: 1.7;
  color: var(--muted);
}
.sheet-actions {
  display: flex;
  gap: 12px;
  margin-top: 16px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
}
.sheet-actions .btn { padding: 10px 22px; font-size: 13px; }

/* 抽屉里的键位表 */
.keys {
  margin: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 7px 16px;
  font-size: 13px;
  align-items: baseline;
}
.keys dt {
  font-family: var(--mono);
  font-size: 11.5px;
  color: #e2e9e1;
  white-space: nowrap;
  padding: 2px 7px;
  border: 1px solid var(--line);
  background: rgba(196, 208, 198, 0.06);
  text-align: center;
}
.keys dd {
  margin: 0;
  color: rgba(206, 216, 208, 0.82);
  font-size: 12.5px;
  line-height: 1.45;
}

/* 设置项 */
.set-row {
  display: grid;
  grid-template-columns: 110px 1fr 62px;
  align-items: center;
  gap: 14px;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
}
.set-row > label:first-child {
  font-size: 12.5px;
  letter-spacing: 0.10em;
  color: rgba(206, 216, 208, 0.88);
}
.set-row output {
  font-family: var(--mono);
  font-size: 12.5px;
  color: var(--steel);
  text-align: right;
}
.set-row input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 3px;
  background: rgba(196, 208, 198, 0.22);
  outline: none;
  cursor: pointer;
}
.set-row input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 14px; height: 14px;
  background: var(--brass);
}
.set-row input[type="range"]::-moz-range-thumb {
  width: 14px; height: 14px;
  border: none;
  background: var(--brass);
}
.set-row select {
  width: 100%;
  font-family: var(--sans);
  font-size: 12.5px;
  padding: 8px 10px;
  color: #e4eae3;
  background: rgba(18, 23, 24, 0.95);
  border: 1px solid var(--line);
  outline: none;
  cursor: pointer;
}
.sw {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: 12.5px;
  color: rgba(206, 216, 208, 0.84);
  cursor: pointer;
}
.sw input[type="checkbox"] {
  -webkit-appearance: none;
  appearance: none;
  width: 15px; height: 15px;
  border: 1px solid rgba(196, 208, 198, 0.42);
  background: rgba(18, 23, 24, 0.95);
  cursor: pointer;
  position: relative;
  flex: 0 0 auto;
}
.sw input[type="checkbox"]:checked { background: var(--brass); }
.sw input[type="checkbox"]:checked::after {
  content: '';
  position: absolute;
  left: 4px; top: 1px;
  width: 5px; height: 9px;
  border: solid #04140a;
  border-width: 0 2px 2px 0;
  transform: rotate(42deg);
}
/* 设置项在窄屏改为两行 */
@media (max-width: 620px) {
  .set-row { grid-template-columns: 1fr; gap: 8px; }
  .set-row output { text-align: left; }
}

/* ====================================================== 设置分组（折叠）
   每个大类是一整行按钮，点开才露出组内设置。展开动画由 13-lobby 写
   max-height 驱动（CSS 没法按内容高度做过渡），这里只负责"高度可动"。
   组头用左侧 3px 黄铜竖条表示展开态，与仪表盘的"选中"灯语一致。 */
.set-group {
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.018);
  margin-bottom: 10px;
}
.set-group:last-of-type { margin-bottom: 0; }
.set-group-head {
  display: flex; align-items: center; gap: 12px;
  width: 100%;
  padding: 13px 14px;
  background: linear-gradient(#232a30, #191f24);
  border: 0;
  border-left: 3px solid transparent;
  color: #dfe7ee;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background .18s ease, border-color .18s ease;
}
.set-group-head:hover { background: linear-gradient(#2b333a, #1d242a); }
.set-group.is-open > .set-group-head {
  border-left-color: var(--brass);
  background: linear-gradient(#2c343b, #1f262c);
}
.set-group-name {
  font-size: 14px; font-weight: 600; letter-spacing: 3px;
  color: #e6eef5;
}
.set-group-hint {
  flex: 1; min-width: 0;
  font-size: 11px; letter-spacing: 0.5px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.set-caret {
  flex: none;
  width: 7px; height: 7px;
  margin-right: 4px;
  border-right: 1.5px solid var(--brass-dim);
  border-bottom: 1.5px solid var(--brass-dim);
  transform: rotate(45deg);          /* 收起：箭头朝下 */
  transition: transform .28s cubic-bezier(.4, 0, .2, 1);
}
.set-group.is-open .set-caret {
  transform: rotate(-135deg);        /* 展开：箭头朝上 */
}
.set-group-body {
  overflow: hidden;
  max-height: 0;
  transition: max-height .34s cubic-bezier(.4, 0, .2, 1);
}
.set-group-inner { padding: 0 14px; }
/* 组内最后一行不再画下边框：否则会和组框底边叠成两条线 */
.set-group-inner .set-row:last-child { border-bottom: 0; }
/* 已隐去的设置项：DOM 与功能代码都留着，只是不显示 */
.set-row.is-hidden { display: none !important; }
@media (max-width: 560px) {
  .set-group-hint { display: none; }   /* 窄屏只留组名，避免挤成省略号 */
}

/* ============================================================ 结算表 */
.result {
  width: 100%;
  border-collapse: collapse;
  margin: 4px 0 6px;
  font-family: var(--mono);
  font-size: 13.5px;
}
.result tr { border-bottom: 1px solid var(--line); }
.result tr:last-child { border-bottom: none; }
.result th {
  text-align: left;
  font-weight: 400;
  padding: 9px 0;
  color: var(--muted);
  letter-spacing: 0.06em;
}
.result td {
  text-align: right;
  padding: 9px 0;
  color: #e4eae3;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.result td.accent { color: var(--brass); }

.best {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 7px;
  font-size: 10.5px;
  letter-spacing: 0.14em;
  color: #05120a;
  background: var(--amber);
  vertical-align: 1px;
  font-weight: 700;
}

/* ============================================================== 飘字 */
#toast {
  position: absolute;
  left: 50%;
  top: 63%;
  z-index: 4;
  transform: translateX(-50%);
  text-align: center;
  pointer-events: none;
  animation: toastIn 0.26s cubic-bezier(.2, .9, .3, 1);
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.85);
}
/* 同样只用位移，不用 opacity —— 保证任何环境下提示文字都能被看见 */
@keyframes toastIn {
  from { transform: translateX(-50%) translateY(14px) scale(0.96); }
  to   { transform: translateX(-50%); }
}
.toast-title {
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 0.20em;
  color: var(--green);
  text-shadow: 0 0 18px rgba(110, 255, 150, 0.6), 0 2px 12px rgba(0, 0, 0, 0.9);
}
.toast-sub {
  margin-top: 5px;
  font-size: 12px;
  letter-spacing: 0.10em;
  color: rgba(200, 226, 212, 0.78);
}
.toast-wave .toast-title  { font-size: 26px; color: var(--green); }
.toast-clear .toast-title { color: #b8ffd0; }
.toast-kill .toast-title  { color: var(--amber); text-shadow: 0 0 18px rgba(255, 194, 71, 0.6); }
.toast-warn .toast-title  { color: var(--red); text-shadow: 0 0 18px rgba(255, 91, 70, 0.6); }
.toast-info .toast-title  { font-size: 16px; letter-spacing: 0.14em; color: rgba(190, 235, 210, 0.92); }

/* ========================================================== 致命错误 */
#fatal {
  position: fixed;
  inset: 0;
  z-index: 99;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(3, 7, 11, 0.96);
}
.fatal-box {
  max-width: 560px;
  padding: 30px 34px;
  border: 1px solid rgba(255, 91, 70, 0.4);
  border-left: 3px solid var(--red);
  background: rgba(20, 8, 8, 0.75);
}
.fatal-box h2 {
  margin: 0 0 12px;
  color: var(--red);
  font-size: 15px;
  letter-spacing: 0.18em;
}
.fatal-box p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.72;
  color: rgba(230, 205, 200, 0.88);
}
.fatal-box code {
  font-family: var(--mono);
  font-size: 12.5px;
  padding: 1px 6px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--amber);
}
.fatal-box .small { font-size: 12px; opacity: 0.72; }

/* 滚动条（深色主题下默认太扎眼）—— 直角，与全站一致 */
.panel::-webkit-scrollbar,
.sheet-body::-webkit-scrollbar { width: 9px; }
.panel::-webkit-scrollbar-track,
.sheet-body::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.3); }
.panel::-webkit-scrollbar-thumb,
.sheet-body::-webkit-scrollbar-thumb { background: rgba(196, 208, 198, 0.20); }
.panel::-webkit-scrollbar-thumb:hover,
.sheet-body::-webkit-scrollbar-thumb:hover { background: rgba(196, 208, 198, 0.34); }

/* ==========================================================================
 * 响应式
 * 大厅的按钮条是"一行等高按钮"，窄屏下自然退化为两行 / 多行，
 * 但**高度仍然一致**（靠 min-height 而不是靠内容撑开）。
 * ========================================================================== */
@media (max-width: 1180px) {
  :root { --edge: 24px; }
  .lb-dock { height: clamp(52px, 12vh, 78px); }
  .lb-btn { padding: 0 14px; }
  .lb-btn.lb-go { min-width: 168px; }
  .lb-btn .lb-d { display: none; }      /* 窄一点就只留标题，避免挤成两行 */
}

@media (max-width: 860px) {
  :root { --edge: 14px; }
  .lb-head { padding-top: calc(var(--edge) + 10px); }
  .lb-title { font-size: 30px; letter-spacing: 0.08em; }
  .lb-rule { margin-top: 14px; }
  /* 退化为两行：前四个功能按钮 2×2，「开始任务」独占一行放在最下面 */
  .lb-dock {
    flex-wrap: wrap;
    height: auto;
    align-items: stretch;
  }
  .lb-btn {
    flex: 1 1 46%;
    height: auto;
    min-height: 64px;
    padding: 10px 14px;
    border-top: 1px solid var(--line);
  }
  .lb-btn:nth-child(1), .lb-btn:nth-child(2) { border-top: none; }
  .lb-btn:nth-child(odd) { border-left: none; }
  .lb-btn.lb-go {
    flex: 1 1 100%;
    min-width: 0;
    min-height: 60px;
    border-top: none;
  }
  .lb-hint { font-size: 11px; }
  .lb-foot { font-size: 10px; letter-spacing: 0.04em; }
}

@media (max-width: 560px) {
  :root { --edge: 10px; }
  .lb-title { font-size: 25px; }
  .lb-brand { margin-bottom: 12px; letter-spacing: 0.36em; }
  /* 竖屏窄屏沿用 860 块的「2×2 + 开始任务整行」布局（不再覆盖成单列 5 行），
     只把按钮压矮一档：头部 + 按钮区 + 页脚在任意竖屏高度下都装得下
     （.lobby-inner 满屏不滚动，超高即裁切 —— 按钮区必须留足余量）。 */
  .lb-btn { min-height: 56px; }
  .panel-inner { padding: 24px 18px 20px; }
  .btn { padding: 12px 22px; font-size: 13.5px; }
  .btn.big { font-size: 17px; letter-spacing: 0.20em; padding: 13px 28px; min-width: 0; width: 100%; }
  .actions { gap: 10px; }
  .sheet-layer { padding: 16px 10px; }
  .sheet-body { padding: 14px 14px 18px; }
  .lb-list li { font-size: 12.5px; }
}

@media (max-height: 660px) {
  .lb-head { padding-top: 18px; }
  .lb-title { font-size: 30px; }
  .lb-rule { margin-top: 12px; }
  /* 注意：这里不能再给 .lb-dock 设固定高度 —— 本块在宽度断点之后声明，
     固定高度会覆盖 ≤860px 宽块里的 height:auto + flex-wrap，
     手机竖屏（如 360×640 同时命中 ≤560/860 宽与 ≤660 高）下 3 行按钮
     会被钉进 68px 的容器里溢出下排，「开始任务」被裁出屏幕外。
     单行/换行的高度都由各宽度断点自己的规则（clamp 或 auto）管理。 */
  .lb-bottom { padding-bottom: 10px; }
  .lb-foot { margin-top: 8px; }
}

/* ---- 手机横屏 / 小窗 WebView（矮视口）：大厅整版收紧 ----
   矮视口下 2×2 堆叠（≤860px 宽的那套）总高约 190px+，叠加头部/提示/页脚
   会超过 360px 视口，.lobby-inner overflow:hidden 会把底部按钮整排裁出屏外
   —— 表现为「开始任务按不到」。这里强制按钮条回到一行、只留标题，
   并把头部压扁。放在所有媒体块之后，同权重选择器靠顺序覆盖。 */
@media (max-height: 560px) {
  .lb-head { padding-top: calc(var(--edge) + 4px); }
  .lb-brand { margin-bottom: 6px; }
  .lb-title { font-size: clamp(20px, 5.4vh, 30px); letter-spacing: 0.08em; }
  .lb-rule { margin-top: 8px; }
  .lb-dock {
    flex-wrap: nowrap;
    height: clamp(46px, 14vh, 60px);
  }
  .lb-btn {
    flex: 1 1 0;
    height: 100%;
    min-height: 0;
    padding: 0 12px;
  }
  /* 抵消窄屏块的 nth-child 去边/加边规则（同特异性，靠顺序覆盖）：
     单行时去掉顶部补线、恢复按钮间分隔线 */
  .lb-btn:nth-child(n) {
    border-top: none;
    border-left: 1px solid var(--line);
  }
  .lb-btn:first-child { border-left: none; }
  .lb-btn.lb-go { border-left: none; }   /* 黄铜实心主按钮左侧不加分隔线 */
  .lb-btn .lb-t { font-size: 13px; }
  .lb-btn.lb-go {
    flex: 0 0 clamp(110px, 18vw, 150px);
    min-width: 0;
    min-height: 0;
  }
  .lb-btn.lb-go .lb-t { font-size: 14px; }
  .lb-hint { display: none; }      /* 触屏/小窗下键位提示无意义，让位给按钮 */
  .lb-foot { margin-top: 6px; font-size: 10px; }
}


/* ====================================================================
 * 触控操作层（移动端，15-touch.js 控制显隐）
 * 布局原则：全部控件贴边落角，中央完全让给座舱仪表盘与 HUD 玻璃；
 * 按钮做的是"哑光仪表"延续：深色底 + 细描边 + 黄铜只给主武器（机炮）。
 * ==================================================================== */
#touchLayer {
  position: absolute;
  inset: 0;
  z-index: 15;                    /* 低于抽屉(20) 高于画布 */
  pointer-events: none;           /* 容器放行，控件各自接回 */
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;

  /* 摇杆家位（供摇杆与方向舵共用：舵始终位于摇杆正下方对齐）。
     --stick-y 是摇杆底边到屏幕底边的距离：上移腾出一行给方向舵。 */
  --stick-x: calc(max(7vw, env(safe-area-inset-left, 0px) + 26px));
  --stick-y: calc(max(11vh, 58px) + env(safe-area-inset-bottom, 0px));

  /* 摇杆边长 —— 两套布局共用同一个值（ergo 只挪位置，不改尺寸）。
     取「屏宽 17% / 屏高 36%」的较小者，上限 190px。
     上限不是随手取的：主仪表板是 3D 投在画面底部的（1.34×0.52 的斜板，
     落在眼前 1.05m 处），它的左缘最窄在屏宽的 25%（16:9 机型）、
     30%（20:9 机型）—— 实测见 tests/diag-stick-clear.js。
     摇杆右边缘必须留在它外面，否则会盖住「机体完好度」那一块读数。 */
  --stk-sz: min(17vw, 36vh, 190px);

  /* ---- 左上角两个系统键的**对齐基准** ----
     暂停与指挥原先各自写了一套 inset：暂停用 max(3vw, 10px)、指挥用
     max(1.5vw, 6px)，宽度 86 对 64、高度 40 对 34 —— 于是指挥键既不在
     暂停键正下方，左边缘也对不齐（用户反馈"看起来特别难受"）。
     现在三个值（左 / 上 / 尺寸）由这里单点定义，两个按钮都引用同一组变量，
     从结构上不可能再错位。矮屏的收缩也改成只改这三个变量。 */
  --tc-l: max(3vw, env(safe-area-inset-left, 0px) + 10px);
  --tc-r: max(3vw, env(safe-area-inset-right, 0px) + 10px);
  --tc-t: max(3vh, env(safe-area-inset-top, 0px) + 10px);
  --tc-pw: 86px;                  /* 两个键同宽 */
  --tc-ph: 40px;                  /* 暂停键高度（指挥键的 top 由它推） */
  --tc-gap: 8px;                  /* 指挥键与暂停键的间距 */
}
#touchLayer.hidden { display: none; }
#touchLayer > * { pointer-events: auto; }

/* 全面屏（宽高比 ≥2:1 —— 20:9 的现代手机都在这里）仪表板被挤到屏宽 30% 以外，
   摇杆可以再放大一圈。杆面越大、行程 R 越长，同样的手指位移对应的舵量越小 ——
   这就是"精细操作"最直接的来源（再往上叠 CFG.touch.curveExp 的中心曲线）。 */
@media (min-aspect-ratio: 2/1) {
  #touchLayer { --stk-sz: min(20vw, 40vh, 190px); }
}

/* ---- 左下：虚拟摇杆（也是浮动摇杆的"本体"） ----
   尺寸由 --stk-sz 统一控制（见 #touchLayer 里的说明）：
   杆面越大 → 行程 R = 0.42×边长 越长 → 同样的手指位移对应更小的舵量，
   精细操作的上限就直接抬高了一档（原先 360px 高的机型只有 86px 边长、
   R 仅 36px，一根手指抖一下就满舵）。 */
.tc-stick {
  position: absolute;
  left: var(--stick-x);
  bottom: var(--stick-y);
  width: var(--stk-sz);
  aspect-ratio: 1 / 1;
  border: 1px solid rgba(196, 208, 198, 0.28);
  background: rgba(9, 13, 14, 0.30);
  touch-action: none;
}
#tcStickKnob {
  position: absolute;
  left: 50%; top: 50%;
  width: 44%; height: 44%;
  transform: translate(-50%,-50%);
  border: 1px solid rgba(196, 208, 198, 0.55);
  background: rgba(196, 208, 198, 0.16);
  pointer-events: none;
}
#tcStickPow {                     /* 舵量可视化：中心向外扩的输出强度环（A3） */
  position: absolute;
  left: 50%; top: 50%;
  width: 88%; height: 88%;
  transform: translate(-50%,-50%) scale(0.12);
  border: 1px solid rgba(214, 178, 96, 0.75);   /* 黄铜强调色 */
  background: rgba(214, 178, 96, 0.10);
  opacity: 0;
  pointer-events: none;
}
.tc-stick::before {               /* 十字基准线：一眼读出中位 */
  content: '';
  position: absolute;
  left: 50%; top: 6%; bottom: 6%; width: 1px;
  background: rgba(196, 208, 198, 0.14);
}
.tc-stick::after {
  content: '';
  position: absolute;
  top: 50%; left: 6%; right: 6%; height: 1px;
  background: rgba(196, 208, 198, 0.14);
}

/* ---- 右缘：垂直油门滑条 ---- */
.tc-throttle {
  position: absolute;
  right: max(3vw, env(safe-area-inset-right, 0px) + 10px);
  bottom: max(9vh, env(safe-area-inset-bottom, 0px) + 16px);
  width: 44px;
  height: min(38vh, 300px);
  display: flex;
  align-items: center;
  justify-content: center;
  touch-action: none;
}
.tc-th-track {
  position: relative;
  width: 12px;
  height: 100%;
  border: 1px solid rgba(196, 208, 198, 0.30);
  background: rgba(9, 13, 14, 0.35);
  overflow: hidden;
}
#tcThFill {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 68%;
  background: rgba(143, 176, 168, 0.40);   /* 冷钢绿 */
}
#tcThKnob {
  position: absolute;
  right: -8px;
  bottom: calc(68% - 14px);
  width: 28px; height: 28px;
  transform: none;
  border: 1px solid rgba(196, 208, 198, 0.60);
  background: rgba(17, 22, 23, 0.92);
  pointer-events: none;
}
.tc-th-label {
  position: absolute;
  right: 40px; bottom: 0;
  font-size: 11px;
  letter-spacing: 0.2em;
  color: var(--muted);
  writing-mode: vertical-rl;
}

/* ---- 按钮（机炮/导弹/干扰/加力/后视/舵/暂停） ---- */
.tc-btn {
  position: relative;             /* 灯语子元素（余量角标/过热条）的定位上下文 */
  border: 1px solid rgba(196, 208, 198, 0.34);
  background: rgba(9, 13, 14, 0.42);
  color: var(--text);
  font-family: var(--sans);
  letter-spacing: 0.12em;
  outline: none;
  touch-action: none;
  transition: background .1s;
}
.tc-btn.on { background: rgba(196, 208, 198, 0.22); }

/* ---- 热区扩张：只向左右各扩 8px，不向上（按钮竖排，纵向扩会互相压盖） ----
   矮屏档的小按钮只有 32px 高，低于 48dp 最小触控目标，靠横向扩张补命中率。 */
.tc-btn::before {
  content: '';
  position: absolute;
  left: -8px; right: -8px; top: 0; bottom: 0;
}

/* ---- 灯语子元素（由 15-touch.js updateCues 写入） ---- */
.tc-ammo {                        /* 余量角标：导弹/干扰弹剩余发数 */
  position: absolute;
  right: 3px; bottom: 2px;
  font-size: 11px;
  letter-spacing: 0;
  line-height: 1;
  color: var(--muted);
  pointer-events: none;
}
.tc-btn.cue-empty .tc-ammo { color: rgba(226, 75, 74, 0.85); }
.tc-heat {                        /* 机炮过热条：底部内嵌，随热量增长 */
  position: absolute;
  left: 0; bottom: 0;
  height: 3px; width: 0;
  background: rgba(214, 178, 96, 0.85);
  pointer-events: none;
}
.tc-heat.over { background: rgba(226, 75, 74, 0.95); }

/* ---- 灯语动画：锁定 / 可发射 / 危险 / 枯竭 ---- */
@keyframes tcLock {
  from { border-color: rgba(214, 178, 96, 0.45); background: rgba(9, 13, 14, 0.42); }
  to   { border-color: rgba(214, 178, 96, 1);    background: rgba(214, 178, 96, 0.16); }
}
@keyframes tcReady {
  from { border-color: rgba(214, 178, 96, 0.55); background: rgba(9, 13, 14, 0.42); }
  to   { border-color: rgba(232, 200, 135, 1);   background: rgba(214, 178, 96, 0.26); }
}
@keyframes tcDanger {
  from { border-color: rgba(226, 75, 74, 0.45);  background: rgba(9, 13, 14, 0.42); }
  to   { border-color: rgba(226, 75, 74, 1);     background: rgba(226, 75, 74, 0.32); }
}
.tc-btn.cue-lock   { animation: tcLock 1.2s ease-in-out infinite alternate; }
.tc-btn.cue-ready  { animation: tcReady 0.6s ease-in-out infinite alternate; }
.tc-btn.cue-danger { animation: tcDanger 0.34s ease-in-out infinite alternate; }
.tc-btn.cue-empty  { opacity: 0.42; }

/* 右下武器簇：机炮最大放最右下（拇指最顺的位置） */
.tc-actions {
  position: absolute;
  right: calc(max(3vw, env(safe-area-inset-right, 0px) + 10px) + 58px);
  bottom: max(5vh, env(safe-area-inset-bottom, 0px) + 12px);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
}
#tcGun {
  width: 108px; height: 74px;
  font-size: 17px;
  border-color: rgba(217, 177, 102, 0.55);
  color: #e8c887;
}
#tcMissile { width: 84px; height: 54px; font-size: 14px; }
.tc-actions .tc-sm { width: 72px; height: 40px; font-size: 12px; }
/* 雷达量程键在**经典布局**里用 order 提到簇顶：
   经典布局是保留下来的回退路径（设置项已隐去、强制 ergo，实际进不去），
   但它靠 flex 竖排、机炮是最后一个 → 新键若留在机炮后面，会把机炮
   顶离底边（实测 57px → 107px），拇指落点就全错了。ergo 下是绝对定位，
   order 对它没有影响。 */
#touchLayer.lay-classic #tcRadar { order: -1; }

/* 中下偏左：方向舵（移到摇杆正下方，与摇杆左缘对齐） */
.tc-rudder {
  position: absolute;
  left: var(--stick-x);
  bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  display: flex;
  gap: 12px;
}
.tc-rudder .tc-sm { width: 64px; height: 44px; font-size: 13px; }

/* 左上：暂停 */
.tc-pause {
  position: absolute;
  /* 左 / 上一律走 #touchLayer 的基准变量，指挥键按同一组值往下排 */
  left: var(--tc-l);
  top: var(--tc-t);
  width: var(--tc-pw); height: var(--tc-ph);
  font-size: 12px;
}

/* 小屏进一步收敛：控件按 12px 网格内缩，避免挤占 HUD */
@media (max-width: 760px) {
  .tc-actions { right: calc(max(3vw, 10px) + 50px); gap: 8px; }
  #tcGun { width: 92px; height: 64px; font-size: 15px; }
  #tcMissile { width: 72px; height: 46px; }
  .tc-actions .tc-sm { width: 62px; height: 36px; }
  /* 大厅按钮的窄屏规则统一由 860/560 宽度块与「矮视口」块负责，
     这里不再重复（重复会因声明顺序不同而互相覆盖）。 */
  .panel-inner { padding: 16px; }
}

/* ---- 触控控件：矮视口（手机横屏 / 小窗 WebView）整体收缩一档 ----
   固定 px 尺寸（机炮 108×74 等）是按 1080p 手机横屏定的，
   落到 360px 高的 WebView 上会占掉近半屏、盖住仪表盘。
   简化为短边比例：高度 < 560px 时全部缩一档，摇杆/油门同步缩小。 */
@media (max-height: 560px) {
  /* 摇杆尺寸不在这里改：--stk-sz 里的 36vh 这一项本身就是"矮屏自动缩"，
     这里再覆盖一遍会两边打架 —— ergo 的变量优先级更高，写了也白写。 */
  .tc-throttle { width: 38px; height: min(30vh, 220px); }
  #tcThKnob { width: 24px; height: 24px; }
  .tc-actions {
    right: calc(max(3vw, env(safe-area-inset-right, 0px) + 10px) + 48px);
    gap: 7px;
  }
  #tcGun { width: 84px; height: 56px; font-size: 14px; }
  #tcMissile { width: 66px; height: 44px; font-size: 12px; }
  .tc-actions .tc-sm { width: 56px; height: 32px; font-size: 11px; }
  .tc-rudder .tc-sm { width: 52px; height: 38px; font-size: 12px; }
  .tc-rudder { gap: 8px; }
  /* 矮屏收缩：只改**基准变量**，暂停与指挥仍按同一组值对齐 */
  #touchLayer { --tc-pw: 72px; --tc-ph: 34px; }
  .tc-pause { font-size: 11px; }
}

/* ====================================================================
 * 布局 B：人体工学（默认，settings.touchLayout = 'ergo'）
 *   · 右手区：机炮 / 干扰弹 / 导弹 三键 —— 以右下角为圆心的拇指弧，
 *     中心间距 90~107px，全落在拇指自然落点内；
 *   · 右手区顶端：加力 / 后视横排 —— 落在武器簇正上方，
 *     拇指从机炮上抬即可够到（原先放在左手区，右手要跨过半个屏幕）；
 *   · 左手区：只有摇杆，拇指不离杆；
 *   · 油门：右缘中下部；
 *   · 所有控件距屏幕底 ≥ 58px —— 避开安卓手势导航保留区
 *     （经典布局的机炮距底只有 18px，边缘滑动会被系统抢走）。
 *   实现：.tc-actions 铺满触控层并交出 pointer-events，五个按钮各自绝对定位；
 *         DOM 结构不变，经典布局仍用它的 flex 竖排。整块删掉即回退经典。
 * ==================================================================== */
#touchLayer.lay-ergo {
  --stk-l: max(7vw, 40px);                            /* 摇杆左边距：比经典布局更内缩 ——
       拇指落在杆面中央而不是贴着屏边，配合放大的杆面一起解决
       "太小、太靠边、捏不住精度"三个问题 */
  --stk-b: max(15vh, 62px);                           /* 摇杆底边距（安全区之上） */
  --aux-b: 240px;                                     /* 加力/后视底边：
       武器簇顶端 = 导弹 bottom 158 + 高 68 = 226，再留 14px 间距 → 240。
       与武器簇同列（right 76 / 154），拇指上抬即可够到。矮屏档另有收缩值。 */
}
#touchLayer.lay-ergo .tc-stick {
  left: var(--stk-l);
  bottom: var(--stk-b);
  width: var(--stk-sz);
}
#touchLayer.lay-ergo .tc-actions {
  left: 0; right: 0; top: 0; bottom: 0;               /* 铺满：子按钮改用屏幕坐标 */
  display: block;
  gap: 0;
  pointer-events: none;                               /* 铺满后不得吃掉空白处手势 */
}
#touchLayer.lay-ergo .tc-actions > .tc-btn {
  position: absolute;
  pointer-events: auto;
}
/* 右手武器弧：三键聚在右下角成"品"字 —— 机炮在拇指主落点，
   干扰弹在其正左（导弹来袭时向左平移即可按，比往上方抬更顺），
   导弹在其左上方。三键中心两两 77~107px，整体不越过屏幕中线。 */
#touchLayer.lay-ergo #tcGun {
  left: auto; right: 76px; bottom: 84px;
  width: 84px; height: 84px; font-size: 15px;
}
#touchLayer.lay-ergo #tcFlare {
  left: auto; right: 168px; bottom: 84px;
  width: 62px; height: 62px; font-size: 12px;
}
#touchLayer.lay-ergo #tcMissile {
  left: auto; right: 168px; bottom: 158px;
  width: 68px; height: 68px; font-size: 13px;
}
/* 瞄准（29 轮）：机炮正上方（与机炮同列、水平居中对齐），点按在
   1 倍 ↔ 1.72 倍视场间切换。占 176~228px，与机炮顶（168）、
   辅助键底（240）各留 8/12px —— 不挤占武器簇。 */
#touchLayer.lay-ergo #tcAim {
  left: auto; right: 84px; bottom: 176px;
  width: 68px; height: 52px; font-size: 12px;
}
/* 雷达量程（本轮）：**机炮正下方**，与机炮同列居中
   （机炮中心 = right 76+42 = 118，按钮宽 60 ⇒ right 88）。
   底边 36、高 44：占 36~80，离机炮底边 84 还有 4px 净空。
   ⚠ 这是唯一一个低于"距底 84px"基准的键 —— 按需求放在机炮下面，
     碰不到更下面没有别的位置；44px 仍是可点面积的下限。 */
#touchLayer.lay-ergo #tcRadar {
  left: auto; right: 88px; bottom: 36px;
  width: 60px; height: 44px; font-size: 12px;
}
/* 武器簇顶端的辅助键：加力在外（贴屏幕右缘一侧）、后视在内，横排。
   底边 212px 落在导弹顶边（198）上方 14px，与武器三键不重叠；
   与机炮/导弹同列，所以拇指从机炮往上一抬就是加力，不用横向找。 */
#touchLayer.lay-ergo #tcBurner {
  left: auto; right: 76px; bottom: var(--aux-b);
  width: 68px; height: 44px; font-size: 12px;
}
#touchLayer.lay-ergo #tcRear {
  left: auto; right: 154px; bottom: var(--aux-b);
  width: 62px; height: 44px; font-size: 12px;
}
/* 油门：最右缘中下部（触控带宽 56px，够 48dp 最小目标），与机炮横向错开。
   底边与武器簇齐平（84px，低于安卓手势保留区），终点比机炮簇更高 ——
   行程越长，同样的手指位移对应的油门变化越小，油门调节精度越高。 */
#touchLayer.lay-ergo .tc-throttle {
  right: max(1.5vw, 6px);
  bottom: 84px; top: auto;
  transform: none;
  width: 56px;
  height: min(40vh, 300px);
}

/* 布局 B 的矮屏再收缩（320~340px 高的小屏 WebView）。
   注意：360px 高的主流手机横屏走标准值 —— 断点不要设到 380，
   否则最常见的机型会吃到这套缩小尺寸。 */
@media (max-height: 340px) {
  #touchLayer.lay-ergo #tcGun {
    width: 74px; height: 74px; right: 66px; bottom: 70px;
  }
  #touchLayer.lay-ergo #tcFlare {
    width: 56px; height: 56px; right: 148px; bottom: 70px;
  }
  #touchLayer.lay-ergo #tcMissile {
    width: 60px; height: 60px; right: 148px; bottom: 136px;
  }
  /* 矮屏：瞄准同样缩一档（机炮顶 144，辅助键底 210，占 152~196） */
  #touchLayer.lay-ergo #tcAim {
    width: 60px; height: 44px; right: 73px; bottom: 152px;
  }
  /* 矮屏：雷达键跟着机炮缩一档（机炮 right 66 / 宽 74 ⇒ 中心 103；
     按钮宽 54 ⇒ right 76；机炮底 70，雷达占 22~60，净空 10px） */
  #touchLayer.lay-ergo #tcRadar {
    right: 76px; bottom: 22px;
    width: 54px; height: 38px; font-size: 11px;
  }
  /* 矮屏：武器簇缩小后导弹顶边 = 136 + 60 = 196，辅助键底边 210 */
  #touchLayer.lay-ergo #tcBurner {
    right: 66px; bottom: 210px;
    width: 62px; height: 40px;
  }
  #touchLayer.lay-ergo #tcRear {
    right: 138px; bottom: 210px;
    width: 56px; height: 40px;
  }
  #touchLayer.lay-ergo .tc-throttle {
    width: 48px; height: min(38vh, 240px);
    right: max(1vw, 4px); bottom: 68px;
  }
}

/* ====================================================================
 * 镜像操控（settings.leftHanded，设置面板上的「镜像操控」）—— 整套左右互换：
 *   摇杆与加力/后视移到右侧，武器三键与油门移到左侧，暂停移到右上。
 *   ergo 与 classic 两套布局都支持。
 * ==================================================================== */
#touchLayer.lay-lh #tcPause {
  left: auto;
  right: var(--tc-r);
}
#touchLayer.lay-lh.lay-ergo .tc-stick {
  left: auto; right: var(--stk-l);
}
#touchLayer.lay-lh.lay-ergo #tcBurner { left: 76px; right: auto; }
#touchLayer.lay-lh.lay-ergo #tcRear { left: 154px; right: auto; }
#touchLayer.lay-lh.lay-ergo #tcGun { left: 76px; right: auto; }
#touchLayer.lay-lh.lay-ergo #tcFlare { left: 168px; right: auto; }
#touchLayer.lay-lh.lay-ergo #tcMissile { left: 168px; right: auto; }
#touchLayer.lay-lh.lay-ergo #tcAim { left: 84px; right: auto; }
#touchLayer.lay-lh.lay-ergo #tcRadar { left: 88px; right: auto; }
#touchLayer.lay-lh.lay-ergo .tc-throttle {
  right: auto; left: max(1.5vw, 6px);
}
/* 经典布局的镜像（回退路径） */
#touchLayer.lay-lh.lay-classic .tc-stick {
  left: auto; right: var(--stick-x);
}
#touchLayer.lay-lh.lay-classic .tc-actions {
  right: auto;
  left: calc(max(3vw, env(safe-area-inset-left, 0px) + 10px) + 58px);
  align-items: flex-start;
}
#touchLayer.lay-lh.lay-classic .tc-throttle {
  right: auto;
  left: max(3vw, env(safe-area-inset-left, 0px) + 10px);
}
#touchLayer.lay-lh.lay-classic .tc-th-label { right: auto; left: 40px; }

/* 镜像 + 矮屏：辅助键的镜像定位要与矮屏收缩值对齐（left 覆盖 right，
   所以这条必须排在矮屏媒体查询之后、且特异性更高）。 */
@media (max-height: 340px) {
  #touchLayer.lay-lh.lay-ergo #tcBurner { left: 66px; }
  #touchLayer.lay-lh.lay-ergo #tcRear { left: 138px; }
  #touchLayer.lay-lh.lay-ergo #tcRadar { left: 76px; right: auto; }
}

/* ====================================================================
 * 横屏提示（触控 + 竖屏时显示）
 * ==================================================================== */
#rotateOverlay {
  position: fixed;
  inset: 0;
  z-index: 90;                    /* 压过所有面板与触控层 */
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(4, 8, 9, 0.96);
  touch-action: pan-y;
}
#rotateOverlay.hidden { display: none; }
.rot-box { text-align: center; padding: 24px; }
.rot-icon {
  font-size: 52px;
  color: var(--brass);
  animation: rotSpin 2.4s ease-in-out infinite;
}
@keyframes rotSpin {
  0%, 100% { transform: rotate(0deg); }
  50% { transform: rotate(90deg); }
}
.rot-box h2 {
  margin: 14px 0 10px;
  font-size: 18px;
  letter-spacing: 0.2em;
  color: #e6ece6;
}
.rot-box p { margin: 4px 0; font-size: 13px; color: var(--muted); }
.rot-box .rot-sub { font-size: 11px; opacity: 0.7; }

/* ====================================================================
 * 排行榜抽屉（限高 + 列表内部滚动 + pan-y：防 body touch-action:none 卡死滚动）
 * ==================================================================== */
.sheet[data-sheet="ranks"] { touch-action: pan-y; }
.rank-tabs {
  display: flex;
  gap: 1px;
  margin: 0 0 12px;
  border: 1px solid var(--line);
  background: rgba(9, 13, 14, 0.6);
}
.rank-tabs .rt {
  flex: 1 1 0;
  padding: 10px 0;
  font-family: var(--sans);
  font-size: 13px;
  letter-spacing: 0.18em;
  border: none;
  border-left: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  outline: none;
}
.rank-tabs .rt:first-child { border-left: none; }
.rank-tabs .rt.on {
  background: rgba(217, 177, 102, 0.14);
  color: #e8c887;
}
.rank-list {
  height: 300px;                  /* 固定高：条目变多在列表内滚 */
  overflow-y: auto;
  overscroll-behavior: contain;
  touch-action: pan-y;
  border: 1px solid var(--line);
  background: rgba(6, 10, 11, 0.5);
}
.rank-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
  font-size: 13px;
}
.rank-row:last-child { border-bottom: none; }
.rank-no {
  flex: 0 0 34px;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 12px;
}
.rank-no.top { color: var(--brass); }
.rank-av {
  flex: 0 0 22px;
  width: 22px; height: 22px;
  object-fit: cover;
  background: rgba(196, 208, 198, 0.10);
}
.rank-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text);
}
.rank-score { flex: 0 0 auto; color: #e6ece6; font-family: var(--mono); }
.rank-empty {
  margin: 0;
  padding: 26px 12px;
  text-align: center;
  font-size: 12px;
  color: var(--muted);
}
.rank-mine {
  margin: 10px 0 0;
  font-size: 13px;
  color: var(--steel);
  min-height: 1em;
}

/* ---- 结算页：我的排名区（异步回填） ---- */
.r-ranks {
  margin: 12px 0 0;
  border: 1px solid var(--line);
  background: rgba(6, 10, 11, 0.5);
  padding: 8px 12px;
  font-size: 12px;
  color: var(--muted);
}
.r-rank-line {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 2px 0;
}
.r-rank-line b { color: var(--steel); font-weight: 600; letter-spacing: 0.1em; }
.r-rank-line span { color: var(--text); font-family: var(--mono); }

@media (max-width: 760px) {
  .result th, .result td { font-size: 12px; padding: 6px 8px; }
  .r-ranks { font-size: 11px; }
  .rank-list { height: 240px; }
  .sheet { max-height: min(86vh, 760px); }
}

/* ---- 键位提示（仅键鼠操作模式，飞行中显示在右下角） ---- */
/* 【本轮：去掉整块外框，只留按键本身的框】
   原来这里有一圈 1px 描边 + 半透明底板，把八行提示框成一张"卡片"，
   在画面右下角很抢眼。现在外框与底板全部去掉，只保留 .kb-key 的按键框
   —— 键位依然一眼可读，但整块提示退成"浮在画面上的几行小字"。
   padding 归零、文字与按键框的对比同步压低一档，进一步降低存在感。 */
#kbHints {
  position: absolute;
  right: max(2vw, 14px);
  bottom: max(3vh, 14px);
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 0;
  pointer-events: none;
  z-index: 8;                     /* 低于抽屉(20)/触控层(15)，不挡任何交互 */
  user-select: none;
  -webkit-user-select: none;
}
.kb-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  letter-spacing: 0.08em;
  color: rgba(214, 220, 214, 0.55);
}
/* 指挥键（1~4）单独成组：与飞行 / 武器键之间留一点空 */
.kb-sep { margin-top: 6px; }
.kb-key {
  display: inline-block;
  min-width: 36px;
  padding: 1px 6px;
  text-align: center;
  font-size: 11px;
  letter-spacing: 0.06em;
  color: rgba(255, 194, 71, 0.78);
  border: 1px solid rgba(255, 194, 71, 0.26);
  background: rgba(9, 13, 14, 0.22);
}
/* 导弹逼近：X 干扰弹一行红色闪烁（不发光，纯色 + 透明度步进） */
#kbX.danger .kb-key {
  color: var(--red);
  border-color: rgba(255, 91, 70, 0.55);
  animation: kbBlink 0.7s steps(2, start) infinite;
}
#kbX.danger { color: var(--red); }
@keyframes kbBlink {
  0% { opacity: 1; }
  100% { opacity: 0.25; }
}

/* ============================== 作战模式选择 ==============================
   窗口骨架直接复用 .sheet-layer + .sheet（与任务简报 / 设置 / 战绩同一套），
   所以"弹窗和别的窗口长得不一样"从结构上就不会再发生。
   这里只补三件东西：两行左右滑块、说明行、整宽的「开始任务」。
   ⚠ #ui 是 pointer-events:none，本层必须自己接回点击（见 #modePick）。 */
#modePick {
  z-index: 90;
  /* 模式窗和抽屉同处一层时，抽屉的 z-index 是 20；这里更高，不会被压住 */
}
#modePick.hidden { display: none; }
/* ⚠ .sheet 默认是 display:none（抽屉体系里靠 .open 打开）。
   模式窗没有"打开某个抽屉"这一步，所以这里直接让它常显 ——
   否则整层看得见遮罩、却看不到窗口（探针里表现为 rect 全 0）。 */
#modePick .sheet { display: flex; }
.sheet-mode { width: min(560px, 100%); }

.ms-row {
  display: grid;
  grid-template-columns: 64px 44px minmax(0, 1fr) 44px;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  margin-bottom: 10px;
  border: 1px solid var(--line);
  background: rgba(196, 208, 198, 0.035);
}
.ms-label {
  font-size: 12px;
  letter-spacing: 0.18em;
  color: var(--muted);
}
.ms-arrow {
  width: 44px; height: 36px;
  font-family: var(--sans);
  font-size: 13px;
  color: #dbe2db;
  background: rgba(196, 208, 198, 0.06);
  border: 1px solid var(--line-2);
  cursor: pointer;
  outline: none;
  transition: background .14s, border-color .14s;
}
.ms-arrow:hover {
  background: rgba(196, 208, 198, 0.16);
  border-color: rgba(196, 208, 198, 0.44);
}
.ms-arrow:active { background: rgba(196, 208, 198, 0.24); }
.ms-value {
  text-align: center;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: #e6ece6;
  user-select: none;
}
.ms-note {
  margin: 0 0 18px;
  font-size: 12px;
  line-height: 1.7;
  letter-spacing: 0.04em;
  color: var(--muted);
}
.ms-start { width: 100%; }

@media (max-width: 620px) {
  .ms-row { grid-template-columns: 48px 40px minmax(0, 1fr) 40px; gap: 6px; padding: 8px; }
  .ms-arrow { width: 40px; height: 34px; }
  .ms-value { font-size: 15px; letter-spacing: 0.14em; }
  .ms-note { font-size: 11px; margin-bottom: 14px; }
}
@media (max-height: 420px) {
  .ms-row { padding: 6px 8px; margin-bottom: 8px; }
  .ms-note { margin-bottom: 10px; }
}

/* ============================================================================
 * 第 52 轮新增：起始页 / 作战模式卡片 / 版本号
 * ========================================================================== */

/* ================= 起始页（载入屏） =================
   覆盖全屏，z-index 高于模式窗（90）与致命错误层。
   视觉沿用大厅那套哑光仪表色：冷灰墨绿底 + 暖白字 + 黄铜细线，
   不放任何发光装饰 —— 这是"像人做的加载页"和"模板加载页"的分界。 */
#boot {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  background: radial-gradient(120% 90% at 50% 30%, #131a1b 0%, #0a0e0f 62%, #070a0b 100%);
  opacity: 1;
  transition: opacity .42s ease;
}
#boot.done { opacity: 0; pointer-events: none; }

.boot-inner {
  width: min(680px, 86vw);
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 46px;
}

.boot-brand { display: flex; flex-direction: column; align-items: center; }
.boot-logo {
  width: 62px;
  height: 62px;
  object-fit: contain;
  /* 不加边框、不加底板：logo 本身带底色，套一层框会像"图片没加载出来" */
}
.boot-word {
  margin: 16px 0 0;
  font-size: 12px;
  letter-spacing: 0.52em;
  text-indent: 0.52em;
  color: rgba(196, 208, 198, 0.66);
}
.boot-title {
  margin: 8px 0 0;
  font-size: clamp(26px, 4.4vw, 40px);
  font-weight: 600;
  letter-spacing: 0.30em;
  text-indent: 0.30em;
  color: #e8eee8;
}
.boot-load { width: min(360px, 70vw); }
.boot-bar {
  position: relative;
  height: 2px;
  background: rgba(196, 208, 198, 0.14);
  overflow: hidden;
}
.boot-bar span {
  position: absolute;
  inset: 0 auto 0 0;
  width: 8%;
  background: var(--brass, #d9b166);
  transition: width .25s linear;
}
.boot-tip {
  margin: 14px 0 0;
  font-size: 12px;
  letter-spacing: 0.20em;
  color: rgba(196, 208, 198, 0.72);
}

.boot-foot { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.boot-health {
  margin: 0;
  font-size: 11px;
  line-height: 2.0;
  letter-spacing: 0.05em;
  color: rgba(168, 180, 172, 0.56);
}
.boot-engine {
  margin: 0;
  font-size: 10px;
  letter-spacing: 0.26em;
  color: rgba(168, 180, 172, 0.34);
}

/* ================= 作战模式：两张卡片 =================
   一行两张，各占一半；图片按 16:9 裁切（截图本身就是 1280×720）。
   选中的卡片只换边框与标题颜色，不加发光。 */
.mp-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 16px;
}
.mp-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 12px 14px;
  background: rgba(196, 208, 198, 0.035);
  border: 1px solid var(--line);
  cursor: pointer;
  font-family: inherit;
  text-align: left;
  transition: border-color .14s, background .14s;
}
.mp-card:hover { background: rgba(196, 208, 198, 0.08); border-color: var(--line-2); }
.mp-card.on {
  border-color: rgba(217, 177, 102, 0.62);
  background: rgba(217, 177, 102, 0.07);
}
.mp-name {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: #dbe2db;
  white-space: nowrap;
}
.mp-card.on .mp-name { color: #ecd9ae; }
.mp-beta {
  padding: 2px 5px;
  font-style: normal;
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 0.16em;
  color: var(--amber);
  border: 1px solid rgba(255, 194, 71, 0.42);
  vertical-align: middle;
}
.mp-thumb {
  display: block;
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: #0a1012;
  border: 1px solid rgba(196, 208, 198, 0.10);
}
.mp-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* 未选中时压暗一点，选中时还原 —— 不用发光也能读出"当前选择" */
  filter: saturate(0.82) brightness(0.72);
  transition: filter .18s;
}
.mp-card.on .mp-thumb img { filter: none; }

/* ================= 版本号 ================= */
.lb-ver {
  color: rgba(168, 180, 172, 0.44);
  letter-spacing: 0.06em;
  /* 与版权、官网链接同排时用小一号等宽感，读起来像版本串而不是文案 */
  font-variant-numeric: tabular-nums;
}
/* 大厅版面的左上角固定位：页脚只留版权与官网，版本串单独钉角。
   .lobby-inner 已是 position:relative，直接绝对定位即可。 */
.lb-ver-corner {
  position: absolute;
  top: 13px;
  left: 20px;
  z-index: 2;
  font-size: 10.5px;
  letter-spacing: 0.08em;
  line-height: 1;
  pointer-events: none;
  user-select: none;
}

/* ================= 任务简报：两个模式的标题 ================= */
.brief-h {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 0;
  color: #ecd9ae;
}
.brief-sep {
  margin-top: 30px;
  padding-top: 20px;
  border-top: 1px solid var(--line);
}

@media (max-width: 620px) {
  .mp-cards { gap: 8px; margin-bottom: 12px; }
  .mp-card { padding: 8px 8px 10px; gap: 7px; }
  .mp-name { font-size: 13px; letter-spacing: 0.08em; }
  .mp-beta { font-size: 8px; letter-spacing: 0.10em; }
}

/* ======================== 触屏航行灯键（本轮新增） ========================
   位置按需求：加力键的右侧、油门控制条的正上方 —— 也就是右缘那一列的顶端。
   与油门条同宽同列（触控带宽 56px），拇指从油门往上一滑就能按到；
   高度 46px 满足最小触控目标，也用灯色区分开/关。 */
#touchLayer.lay-ergo #tcLights {
  left: auto; right: max(1.5vw, 6px);
  bottom: calc(84px + min(40vh, 300px) + 12px);
  width: 56px; height: 46px; font-size: 12px;
}
#touchLayer.lay-lh.lay-ergo #tcLights {
  left: max(1.5vw, 6px); right: auto;
}
#touchLayer #tcLights.tc-on {
  border-color: rgba(127, 211, 154, 0.85);
  color: #bff0cd;
}
#touchLayer #tcLights.tc-off {
  border-color: rgba(196, 96, 84, 0.85);
  color: #f0b8b0;
}
@media (max-height: 340px) {
  /* 矮屏必须跟着油门条一起缩：油门此时是 bottom 68px + 高 min(38vh,240px)，
     灯键的底边就取这个和再加 10px 间隙，多了会顶到武器簇、少了会压住油门。 */
  #touchLayer.lay-ergo #tcLights {
    bottom: calc(68px + min(38vh, 240px) + 10px);
    width: 48px; height: 40px;
    right: max(1vw, 4px);
  }
  #touchLayer.lay-lh.lay-ergo #tcLights {
    left: max(1vw, 4px); right: auto;
  }
}

/* ============================== 指挥（触屏） ==============================
   按钮在暂停按钮**正下方**：left / 宽度与暂停完全一致（都取 #touchLayer 的
   --tc-l / --tc-pw），top 由暂停的 top + 高度 + 间距推出来 —— 左右两条边
   严格对齐，看上去是一列。点开后向右展开一条横条。
   条本身不拦截空白处的点击（pointer-events 只给按钮），
   所以"点条外不收回"是天然成立的 —— 只有 × 和四条指令能收。 */
#tcOrder {
  position: absolute;
  left: var(--tc-l);
  top: calc(var(--tc-t) + var(--tc-ph) + var(--tc-gap));
  width: var(--tc-pw); height: 34px;
  font-size: 13px; letter-spacing: 1px;
}
.order-bar {
  position: absolute;
  left: var(--tc-l);
  top: calc(var(--tc-t) + var(--tc-ph) + var(--tc-gap));
  display: flex; align-items: center; gap: 4px;
  padding: 4px;
  background: rgba(10, 14, 18, 0.82);
  border: 1px solid #3b444d;
  pointer-events: none;
  z-index: 40;
}
.order-bar.hidden { display: none; }
.ob-btn {
  pointer-events: auto;
  height: 34px; min-width: 52px;
  padding: 0 12px;
  background: linear-gradient(#2a323a, #1b2128);
  color: #cfd8e0;
  border: 1px solid #4a5560;
  font: inherit; font-size: 13px; letter-spacing: 1px;
  cursor: pointer;
}
.ob-btn:active { background: #3a444e; }
.ob-close {
  min-width: 34px; padding: 0 8px;
  color: #e8b44a; border-color: #6b5a33;
}
@media (max-height: 340px) {
  /* 矮视口：只改基准变量与指挥键自身高度，不动对齐关系 */
  #touchLayer { --tc-pw: 66px; --tc-ph: 34px; --tc-gap: 6px; }
  #tcOrder { height: 30px; font-size: 12px; }
  .ob-btn { height: 30px; min-width: 46px; }
}

/* ============================== 开发者工具（音效试听台） ==============================
   入口是隐藏的（系统设置里 3 秒连点 5 次标题），所以这里没有"入口按钮"的样式。
   三列：中文名称 / ID / 播放。ID 用于精确沟通，必须**可读、可复制、不换行**。
   ⚠ 不做手机窄屏适配（按需求）：本工具只给开发者用，窄屏上三列会挤。
   ⚠ 字体仍只用思源黑体栈（不引入 ui-monospace）：等宽数字用 tabular-nums 代替。 */
.sheet-dev .sheet-body { padding-top: 12px; }
.dev-list { display: flex; flex-direction: column; }
.dev-group {
  margin: 14px 0 4px;
  padding-bottom: 5px;
  border-bottom: 1px solid var(--line);
  font-size: 12px;
  letter-spacing: 0.18em;
  color: rgba(168, 180, 172, 0.74);
}
.dev-group:first-child { margin-top: 0; }
.dev-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 212px 78px;
  align-items: center;
  gap: 14px;
  padding: 4px 6px;
}
.dev-row:hover { background: rgba(196, 208, 198, 0.045); }
.dev-name {
  font-size: 13px;
  color: #dbe2db;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.dev-id {
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0.03em;
  font-variant-numeric: tabular-nums;
  color: rgba(141, 255, 159, 0.60);
  white-space: nowrap;
}
.dev-play {
  font-family: var(--sans);
  font-size: 12px;
  letter-spacing: 0.08em;
  padding: 5px 0;
  border: 1px solid var(--line-2);
  background: rgba(196, 208, 198, 0.05);
  color: #dbe2db;
  cursor: pointer;
  outline: none;
  transition: background .12s, border-color .12s;
}
.dev-play:hover {
  background: rgba(196, 208, 198, 0.14);
  border-color: rgba(196, 208, 198, 0.42);
}
/* 按下反馈只作用于按钮自己（不是"提示"）：黄铜实心闪 120ms */
.dev-play.on {
  background: var(--brass);
  border-color: var(--brass);
  color: #17130a;
}

