/*! 365Lab 音频编辑器 - 编辑页专属样式：编辑器布局 / 波形 / 播放控制 / 状态栏（主题令牌见 site.css） */

/* 编辑页全宽：解除站点通用 1200px 容器限制（顶栏 + 主区，页脚保持居中） */
body.page-editor main.wrap,
body.page-editor .site-header .wrap { max-width: none; padding-left: 14px; padding-right: 14px; }

/* 编辑页页脚只剩一行：去掉为网格页脚准备的层层留白 */
body.page-editor .editor { padding-bottom: 6px; }
body.page-editor .site-footer { margin-top: 4px; padding-top: 12px; }
body.page-editor .footer-base { margin-top: 0; padding-top: 0; border-top: none; }

/* ---- 第39轮：编辑器面板控件尺度统一（只作用于 .page-editor，工具页共用样式不受影响）
   改前实测：按钮 30/37/44px、下拉 35/44px、文本框 33/44px、数值框 33px 四种高度混用。
   统一为 44px（不缩小任何既有热区），圆角统一到 --radius-sm。 ---- */
body.page-editor .panel select,
body.page-editor .panel input[type='text'],
body.page-editor .panel input[type='search'],
body.page-editor .panel input[type='number'],
body.page-editor .panel .btn:not(.icon) {
  min-height: 44px;
  border-radius: var(--radius-sm);
}
body.page-editor .row-nrprog { border-radius: var(--radius-sm); }

/* ---- 第40轮：编辑器间距阶梯 / 字号五档（仅 body.page-editor 作用域；panels.css 与 30 个工具页共用，未改）
   间距阶梯：2 / 4 / 6 / 8 / 10 / 12 / 16 / 20 / 24 / 48 px
   1 发丝（徽标内壁）· 2 图标↔文字 · 3 控件内边距 · 4 工具条行距 · 5 控件组距
   6 分组间距 · 7 面板/分组内边距 · 8 页面外层 · 9 大区块 · 10 页底留白
   字号五档：标题 15 / 正文 13 / 数值读数 13（等宽+600）/ 辅助说明 12 / 极小标签 11 ---- */
body.page-editor {
  /* 第43轮：界面字号档位（标准 1 / 大 1.12 / 特大 1.25）。下面所有字号令牌都按它整体缩放；
     间距与图标不缩放，点按目标仍由原 padding / min-height 决定，不会因为字号变大而缩小 */
  --ui-scale: 1;
  --sp-1: 2px;
  --sp-2: 4px;
  --sp-3: 6px;
  --sp-4: 8px;
  --sp-5: 10px;
  --sp-6: 12px;
  --sp-7: 16px;
  --sp-8: 20px;
  --sp-9: 24px;
  --sp-10: 48px;
  --fsx-title: calc(15px * var(--ui-scale));
  --fsx-body: calc(13px * var(--ui-scale));
  --fsx-readout: calc(13px * var(--ui-scale));
  --fsx-aux: calc(12px * var(--ui-scale));
  --fsx-mini: calc(11px * var(--ui-scale));
  /* 站点字号令牌在编辑器作用域内的可缩放副本（30 个工具页仍是 site.css :root 里的固定 px） */
  --fs-2xs: calc(11px * var(--ui-scale));
  --fs-xs: calc(12px * var(--ui-scale));
  --fs-sm: calc(12.5px * var(--ui-scale));
  --fs-md: calc(13px * var(--ui-scale));
  --fs-lg: calc(14.5px * var(--ui-scale));
  --fs-title: calc(15px * var(--ui-scale));
  /* 第41轮：过渡令牌（快/常规/强调）+ 两条缓动；加载/进度类不套固定时长 */
  --t-fast: 120ms;
  --t-base: 180ms;
  --t-emph: 260ms;
  --e-std: cubic-bezier(0.2, 0.7, 0.3, 1);
  --e-emph: cubic-bezier(0.2, 0.9, 0.3, 1.08);
  /* 图标光学尺寸：功能图标统一 14px；空状态展示图 44px、状态栏 .si 11px 保持原样 */
  --ico: 14px;
}

/* 第43轮：字号档位只改缩放系数，不改布局结构 */
body.page-editor[data-uifont="large"] { --ui-scale: 1.12; }
body.page-editor[data-uifont="xlarge"] { --ui-scale: 1.25; }

/* 第41轮：过渡收敛。只覆盖 duration / timing-function 两个长属性，
   原 transition-property 的开关顺序与位移方向一字未动；工具页无 body.page-editor，零命中 */
body.page-editor a,
body.page-editor .main-nav a,
body.page-editor .btn,
body.page-editor .tab,
body.page-editor .link-btn,
body.page-editor .chip-btn,
body.page-editor .theme-btn,
body.page-editor .group h2,
body.page-editor .group h3,
body.page-editor .overview,
body.page-editor .stat,
body.page-editor .panel input,
body.page-editor .panel select { transition-duration: var(--t-fast); transition-timing-function: var(--e-std); }

body.page-editor .group h2::after,
body.page-editor .group h3::after { transition-duration: var(--t-base); transition-timing-function: var(--e-std); }

body.page-editor .toast { transition-duration: var(--t-emph); transition-timing-function: var(--e-emph); }
body.page-editor .panel { animation-duration: var(--t-base); animation-timing-function: var(--e-std); }
body.page-editor .modal.open .modal-card { animation-duration: var(--t-emph); animation-timing-function: var(--e-emph); }

/* 第41轮：图标笔画规格统一。功能图标 14px / 400；行高按改前盒高锁死（17/15/21.5px），
   只换光学尺寸，不压小编辑条、页签、分组头的点击热区。状态栏 .si 与空状态 44px 展示图保留 */
body.page-editor .tab .ti { font-size: var(--ico); font-weight: 400; line-height: 17px; }
body.page-editor .group h2 .gi,
body.page-editor .group h3 .gi { font-size: var(--ico); font-weight: 400; line-height: 15px; }
body.page-editor .btn.icon { font-size: var(--ico); font-weight: 400; }

/* 第41轮：减弱动效。装饰性动画与平滑滚动交由 site.css 的全局 reduce 规则关闭；
   这里补回「状态变化」的可感知性：状态条/提示只做颜色或透明度过渡，不做位移 */
@media (prefers-reduced-motion: reduce) {
  body.page-editor .hint[data-state] {
    transition: background-color 120ms linear, border-color 120ms linear, border-left-color 120ms linear !important;
  }
  body.page-editor .toast { transition: opacity 80ms linear !important; }
  body.page-editor #btnPlay.playing,
  body.page-editor .rec-dot.live { animation: none; }
}

/* 共用面板骨架在编辑器内收敛到阶梯：panels.css 原文一字未动，工具页无 body.page-editor，故零影响 */
body.page-editor .panel { gap: var(--sp-7); }
body.page-editor .panel .group { padding: var(--sp-7); }
body.page-editor .panel .row { gap: var(--sp-5); }
body.page-editor .panel .field { gap: var(--sp-3); font-size: var(--fsx-aux); }
body.page-editor .panel .field output { font-size: var(--fsx-readout); font-weight: 600; font-variant-numeric: tabular-nums; }
body.page-editor .panel .group h2,
body.page-editor .panel .group h3 { font-size: var(--fsx-title); }
body.page-editor .panel .hint { margin: var(--sp-1) 0 var(--sp-5); font-size: var(--fsx-aux); }
body.page-editor .panel .btn { gap: var(--sp-3); padding: var(--sp-4) var(--sp-7); font-size: var(--fsx-body); }
body.page-editor .panel .btn.small { padding: var(--sp-3) var(--sp-6); font-size: var(--fsx-aux); }
body.page-editor .panel .link-btn { padding: var(--sp-2) var(--sp-5); font-size: var(--fsx-aux); }
body.page-editor .panel .chk { font-size: var(--fsx-aux); }
body.page-editor .panel input[type='text'],
body.page-editor .panel input[type='search'],
body.page-editor .panel input[type='number'],
body.page-editor .panel select { padding: var(--sp-4) var(--sp-5); font-size: var(--fsx-body); }
body.page-editor .tab { font-size: var(--fsx-body); }
body.page-editor .eh-actions .link-btn { padding: var(--sp-3) var(--sp-6); font-size: var(--fsx-aux); }
body.page-editor .ed-head b { font-size: var(--fsx-title); }
body.page-editor .empty-card p { font-size: var(--fsx-body); }
body.page-editor .cmd-input,
body.page-editor .cmd-list li,
body.page-editor #helpList li,
body.page-editor #mouseList li,
body.page-editor .modal-sub { font-size: var(--fsx-body); }
body.page-editor .cmd-tip,
body.page-editor .modal-foot .hint { font-size: var(--fsx-aux); }
body.page-editor .modal-head h3 { font-size: var(--fsx-title); }
body.page-editor kbd,
body.page-editor .cmd-list kbd,
body.page-editor .link-btn kbd { font-size: var(--fsx-mini); }
body.page-editor .export-pct,
body.page-editor .rec-dev { font-size: var(--fsx-body); }
body.page-editor .rec-peak { font-size: var(--fsx-aux); }
body.page-editor .mt-summary { font-size: var(--fsx-aux); }

/* 两栏工作区（参考剪映/PR 布局）：左 = 页签与编辑面板，右 = 素材/波形/播放条 */
.editor {
  position: relative;
  display: grid;
  grid-template-columns: 400px minmax(0, 1fr);
  gap: var(--sp-7);
  align-items: start;
  padding: var(--sp-8) 0 var(--sp-10);
}
.ed-main, .ed-side { min-width: 0; }

/* 工作区标题头 */
.ed-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-4);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-6) var(--sp-7);
  margin-bottom: 12px;
  box-shadow: var(--shadow-sm);
}
.ed-head b { font-size: var(--fsx-title); }
.eh-ico { font-size: var(--ico); font-weight: 400; }
.eh-hint { color: var(--muted); font-size: var(--fsx-aux); }
.eh-actions { margin-left: auto; display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; justify-content: flex-end; }
.eh-actions .link-btn {
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 99px;
  padding: var(--sp-3) var(--sp-6);
  font-size: var(--fsx-aux);
  transition: border-color var(--t-fast) var(--e-std), background var(--t-fast) var(--e-std), color var(--t-fast) var(--e-std);
}
.eh-actions .link-btn:hover:not(:disabled) { border-color: var(--accent); }
.eh-actions .link-btn:focus-visible { outline: none; box-shadow: var(--ring); }
.eh-div { width: 1px; height: 18px; background: var(--border); margin: 0 4px; }
.link-btn:disabled { opacity: 0.4; cursor: not-allowed; }
@media (max-width: 720px) { .eh-hint { display: none; } }

/* 左栏页签卡与右栏"编辑区"头部卡片同风格（圆角/描边/阴影/高度对齐）；四等分防遮挡 */
@media (min-width: 1101px) {
  body.page-editor .tabs {
    margin-top: 0;
    padding: var(--sp-4) var(--sp-4);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--sp-2);
    overflow: visible;
  }
  body.page-editor .tab {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    min-width: 0;
    padding: var(--sp-4) var(--sp-2);
    font-size: var(--fsx-body);
  }
  body.page-editor .tab > span:last-child { overflow: hidden; text-overflow: ellipsis; }
  body.page-editor .tab .ti { margin-right: 0; }
  /* 特大档：四等分格宽已容不下「图标 + 四字标签」，改为两行两列，标签不被省略号截断；
     页签顺序仍是素材 → 降噪 → 工具 → 导出，只换换行不换语义 */
  body.page-editor[data-uifont="xlarge"] .tabs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.ed-side { grid-column: 1; grid-row: 1; }
.ed-main { grid-column: 2; grid-row: 1; }
@media (min-width: 1101px) {
  .ed-side {
    position: sticky;
    top: calc(var(--hdr-h, 64px) + 10px);
    /* 第43轮：sticky 的包含块（.editor）在页脚之前就结束，页脚占住视口最后 73~74px；
       侧栏若仍按 100vh-头栏 取高，滚到页面底部会被包含块底边顶回头栏下面（实测 -62.3px）。
       这里把页脚实测高度也扣掉，保证最底一屏里侧栏顶仍落在头栏下沿之上。 */
    max-height: calc(100vh - var(--hdr-h, 64px) - var(--ft-h, 0px) - 16px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-right: var(--sp-1);
  }
}
@media (max-width: 1100px) {
  .editor { grid-template-columns: 1fr; gap: 0; }
  .ed-main, .ed-side { grid-column: auto; grid-row: auto; }
}

/* 空状态提示：仅在波形区内显示，编辑器骨架常驻可见 */
.empty-card {
  position: absolute;
  inset: 6px;
  z-index: 12;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-6);
  text-align: center;
  padding: var(--sp-8);
  overflow-y: auto;
  border: 2px dashed color-mix(in srgb, var(--accent) 55%, var(--border));
  border-radius: var(--radius);
  background: repeating-linear-gradient(-45deg, transparent 0 14px, color-mix(in srgb, var(--accent) 4%, transparent) 14px 28px), var(--wave-bg);
  cursor: pointer;
}

.empty-card[hidden] { display: none; }
/* 空状态两栏：左＝标题/说明/入口，右＝支持的格式（宽屏并排，窄屏上下叠） */
.empty-main {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-6);
  min-width: 0;
}
.empty-side { min-width: 0; text-align: center; }
.empty-side h3 {
  margin: 0 0 var(--sp-5);
  font-size: calc(12px * var(--ui-scale));
  font-weight: 600;
  letter-spacing: .08em;
  color: var(--muted);
}
.fmt-chips { display: flex; gap: var(--sp-3); flex-wrap: wrap; justify-content: center; margin: 0; }
.fmt-chips span {
  font-size: calc(12px * var(--ui-scale));
  font-weight: 600;
  white-space: nowrap;
  color: var(--text);
  border: 1px solid color-mix(in srgb, var(--accent) 26%, var(--border));
  border-radius: 99px;
  padding: var(--sp-2) var(--sp-5);
  background: color-mix(in srgb, var(--accent) 7%, var(--panel-2));
}
:root[data-theme='dark'] .ebi, :root[data-theme='dark'] .gi, :root[data-theme='dark'] .ti,
:root[data-theme='dark'] .si, :root[data-theme='dark'] .eh-ico, :root[data-theme='dark'] .empty-ico { filter: brightness(0.9) saturate(0.9); }
.empty-ico { font-size: 44px; line-height: 1; animation: emptyFloat 2.4s ease-in-out infinite; }
@keyframes emptyFloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-7px); }
}
@media (prefers-reduced-motion: reduce) { .empty-ico { animation: none; } }

/* 说明文字的栏宽是这段排版的要害：480px 在宽屏里会折成五行、两侧全是空白，
   放开到 620px 后同一句话 2-3 行读完，行高也放宽到 1.85 便于扫读 */
.empty-card h2 { font-size: calc(20px * var(--ui-scale, 1)); line-height: 1.35; margin: 0; }
.empty-card p {
  color: color-mix(in srgb, var(--text) 55%, var(--muted));
  max-width: 620px;
  margin: 0;
  font-size: var(--fsx-body);
  line-height: 1.85;
  text-wrap: pretty;
}
.empty-actions { display: flex; flex-wrap: wrap; gap: var(--sp-5); justify-content: center; margin-top: var(--sp-2); }

/* 宽屏：横过来排，右栏把横向空间占住，说明也不再被挤成窄柱。
   断点定在 1400px：1180 左右时右栏一占，左栏只剩 360px，反而比单列更窄。
   右栏给固定宽度，否则它会被内容压成一条 150px 的窄柱，胶囊里的「MP4 / MOV / WebM」会折在框内。 */
@media (min-width: 1400px) {
  .empty-card { flex-direction: row; align-items: center; justify-content: center; gap: 56px; text-align: left; }
  .empty-main { align-items: flex-start; max-width: 660px; }
  .empty-card p { max-width: none; }
  .empty-actions { justify-content: flex-start; }
  .empty-side { flex: 0 0 232px; border-left: 1px solid var(--border); padding-left: 44px; text-align: left; }
  .fmt-chips { justify-content: flex-start; margin: 0; }
}

/* 空状态是这一屏的主角，内容比纯波形高：两栏排开后比原来的 260px 多占几十像素，
   不放高就会把「保留原采样率」那一行压在虚线框外（实测内容 254px、框内 248px；补上格式清单后要 360px） */
@media (min-width: 721px) {
  .wave-wrap:has(.empty-card:not([hidden])) { height: 360px; }
}

/* ---------------- 波形 ---------------- */
.wave-wrap {
  position: relative;
  height: 260px;
  background: var(--wave-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow), inset 0 1px 0 rgba(255, 255, 255, 0.03);
}

#wave { display: block; width: 100%; height: 100%; touch-action: none; cursor: crosshair; }

/* 波形高度：单一固定档位（历史三档切换已移除） */

#spectrumCanvas {
  position: absolute;
  inset: 0;
  z-index: 4;
  width: 100%;
  height: 100%;
  display: block;
  background: var(--wave-bg);
}

#spectrumCanvas[hidden] { display: none; }

.wave-time {
  position: absolute;
  left: 10px;
  bottom: 8px;
  font-variant-numeric: tabular-nums;
  font-size: var(--fsx-aux);
  color: var(--muted);
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  border: 1px solid var(--border-soft);
  padding: var(--sp-1) var(--sp-4);
  border-radius: 99px;
  pointer-events: none;
}

/* 波形悬停时间气泡：跟随鼠标显示光标处时间点 */
.hover-tip {
  position: absolute;
  top: 8px;
  z-index: 11;
  transform: translateX(-50%);
  padding: var(--sp-1) var(--sp-4);
  font-variant-numeric: tabular-nums;
  font-size: var(--fsx-mini);
  font-weight: 600;
  color: var(--text);
  background: color-mix(in srgb, var(--panel) 88%, transparent);
  border: 1px solid var(--border);
  border-radius: 99px;
  box-shadow: var(--shadow);
  pointer-events: none;
  white-space: nowrap;
}
.hover-tip.sel {
  color: #fff;
  background: var(--accent);
  border-color: var(--accent);
}

/* ---------------- 播放控制 ---------------- */
.transport {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 7px;
  margin-top: 14px;
  padding: 12px 10px;
  background: linear-gradient(180deg, var(--panel), color-mix(in srgb, var(--panel) 92%, var(--bg)));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.transport .sep { width: 1px; height: 22px; background: var(--border); flex: 0 0 1px; }
.transport .tzone { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.transport .tzone-out { margin-left: auto; }
.transport .tzone-out .vol-group { margin-left: 0; }

.transport .vol-group { display: flex; align-items: center; gap: 6px; margin-left: auto; }
.transport .vol-group label { font-size: calc(12px * var(--ui-scale, 1)); color: var(--muted); }
.transport input[type='range'] { width: 64px; }
.transport .btn.icon { width: 32px; height: 32px; flex: 0 0 32px; font-size: var(--ico); }
.transport .btn.small { padding: 6px 7px; }
.transport .chk { font-size: calc(12px * var(--ui-scale, 1)); gap: 5px; }

.rate-group { display: inline-flex; align-items: center; gap: 6px; font-size: calc(12px * var(--ui-scale, 1)); color: var(--muted); }
.rate-group select { padding: 5px 7px; font-size: calc(12.5px * var(--ui-scale, 1)); }
.zoom-slider { display: inline-flex; align-items: center; gap: 5px; font-size: calc(12px * var(--ui-scale, 1)); color: var(--muted); }
.zoom-slider input[type='range'] { width: 62px; accent-color: var(--accent); }
.zoom-slider output { font-size: calc(11.5px * var(--ui-scale, 1)); min-width: 32px; font-variant-numeric: tabular-nums; }

/* 波形右键快捷菜单 */
.ctx-menu {
  position: fixed;
  z-index: 60;
  min-width: 172px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: var(--shadow);
  padding: var(--sp-3);
  display: grid;
  gap: var(--sp-1);
}
.ctx-item {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  background: none;
  border: none;
  color: var(--text);
  font: inherit;
  font-size: var(--fsx-body);
  padding: var(--sp-4) var(--sp-5);
  border-radius: 8px;
  cursor: pointer;
  text-align: left;
  -webkit-tap-highlight-color: transparent;
}
.ctx-item:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.ctx-item.off { color: var(--muted); opacity: 0.5; cursor: default; }
.ctx-item.off:hover { background: none; }
.ctx-item .ci { font-size: var(--ico); font-weight: 400; line-height: 21.5px; width: 16px; text-align: center; }
.ctx-sep { height: 1px; background: var(--border-soft); margin: 4px 2px; }

.file-name {
  font-size: var(--fsx-body);
  color: var(--muted);
  max-width: 210px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.stat .file-name { display: inline-block; max-width: 100%; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; color: var(--text); font-weight: 600; }
.stat.stat-file { grid-column: span 2; }

.chk { display: inline-flex; align-items: center; gap: var(--sp-3); font-size: var(--fsx-body); color: var(--muted); cursor: pointer; }
.chk input { accent-color: var(--accent); cursor: pointer; }

/* ---------------- 素材列表（左侧面板内） ---------------- */
.clip-dot { flex: 0 0 auto; width: 10px; height: 10px; border-radius: 50%; }
.clip-acts { flex: 0 0 auto; display: flex; align-items: center; gap: var(--sp-3); margin-left: auto; }
#clipList li:hover { border-color: color-mix(in srgb, var(--accent) 55%, var(--border-soft)); }

/* 素材/标记列表完整展开，不出内部滚动条；侧栏滚动条仅视觉隐藏，滚轮/触摸仍可用 */
#clipList, #markList { max-height: none; overflow: visible; }
/* 波形上双击选中的标记：列表对应行同步描边，拖动目标一眼可辨（颜色与波形标记边线同源） */
#markList li.active-mark { border-color: var(--wave-mark-edge, #e2b23c); }
.tool-files li .tf-name.list-ph, .clip-line1 .tf-name.list-ph { white-space: normal; overflow-wrap: anywhere; }
.ed-side { scrollbar-width: none; }
.ed-side::-webkit-scrollbar { display: none; width: 0; height: 0; }
/* 素材行两行式：第一行 圆点+名称+徽标+操作，第二行 时长·大小·格式 */
#clipList li { display: block; padding: var(--sp-4) var(--sp-5); }
.clip-line1 { display: flex; align-items: center; gap: var(--sp-4); }
#clipList .tf-meta { display: block; margin: 3px 0 0 20px; font-size: var(--fsx-mini); }
/* 按钮行 ↔ 列表 ↔ 说明文字 之间留呼吸间距 */
.group .row + .tool-files { margin-top: 12px; }
.group .tool-files + .hint { margin-top: 12px; margin-bottom: 4px; }
.clip-acts .btn { padding: var(--sp-2) var(--sp-5); font-size: var(--fsx-aux); }
.clip-acts .btn.clip-play { padding: var(--sp-2) var(--sp-4); min-width: 30px; }
.clip-kind {
  flex: 0 0 auto; font-size: var(--fsx-mini); line-height: 1; padding: var(--sp-2) var(--sp-3); border-radius: 99px;
  background: var(--accent-soft); color: var(--accent); font-weight: 600; letter-spacing: 0.03em;
}
.clip-rename-input { flex: 1; min-width: 0; font: inherit; font-size: var(--fsx-body); padding: var(--sp-2) var(--sp-4); border: 1px solid var(--accent); border-radius: 8px; background: var(--panel); color: var(--text); }
.tray-x {
  border: none; background: transparent; color: var(--muted);
  font-size: var(--fsx-body); cursor: pointer; padding: 0 var(--sp-1); line-height: 1;
}
.tray-x:hover { color: #ff5c7a; }

/* ---------------- 工程库 / 素材筛选（工作流补强） ---------------- */
.proj-row .field { flex: 1 1 210px; min-width: 0; }
.proj-row .btn, .proj-acts .btn, .clip-tools .btn,
.clip-tools .field input, .clip-tools .field select,
.save-row .btn, #btnClipMetaRetry, .clip-check { min-height: 44px; }
.clip-tools .field { flex: 1 1 150px; min-width: 0; }
#presetGroup .row { flex-wrap: wrap; }
#presetGroup .field { flex: 1 1 160px; min-width: 0; }
#presetGroup .field select, #presetGroup .field input,
#presetGroup .btn { min-height: 44px; }
#presetGroup #presetPick { max-width: 100%; }
#presetGroup #btnPresetSave { flex: 1 1 auto; }
.save-row { align-items: center; }
.save-row .hint { margin: 0; flex: 1 1 200px; min-width: 0; }
/* 导出/打开工程文件：两枚并列的离线备份入口（空间不足或长工程时的兜底） */
.proj-file-row { gap: var(--sp-4); }
.proj-file-row .btn { flex: 1 1 auto; min-height: 44px; }
.group .hint.warn { color: var(--error); }

/* ---- 第40轮：面板状态行（错误/警告/成功）。色点 + 文字标签 + 正文；
   三态同时用「颜色 + 文字标签」区分，不强依赖颜色；保留 aria-live 语义。
   长文案在 390px 内换行，st-txt 可断行且 min-width:0，不把容器挤出 ---- */
body.page-editor .hint[data-state] {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  min-width: 0;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--border-soft);
  border-left-width: 3px;
  border-radius: var(--radius-sm);
  background: var(--panel-2);
  color: var(--text);
  font-size: var(--fsx-aux);
  line-height: 1.45;
  transition: background-color var(--t-base) var(--e-std), border-color var(--t-base) var(--e-std), border-left-color var(--t-base) var(--e-std);
}
body.page-editor .hint[data-state] .st-dot {
  flex: 0 0 8px;
  width: 8px;
  height: 8px;
  margin-top: 4px;
  border-radius: 50%;
  background: var(--muted);
}
body.page-editor .hint[data-state] .st-tag { flex: 0 0 auto; font-weight: 700; white-space: nowrap; }
body.page-editor .hint[data-state] .st-txt { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
body.page-editor .hint[data-state='ok'] { border-left-color: var(--ok); background: color-mix(in srgb, var(--ok) 8%, var(--panel-2)); }
body.page-editor .hint[data-state='ok'] .st-dot { background: var(--ok); }
body.page-editor .hint[data-state='warn'] { border-left-color: var(--warn); background: color-mix(in srgb, var(--warn) 10%, var(--panel-2)); }
body.page-editor .hint[data-state='warn'] .st-dot { background: var(--warn); }
body.page-editor .hint[data-state='err'] { border-left-color: var(--error); background: color-mix(in srgb, var(--error) 9%, var(--panel-2)); }
body.page-editor .hint[data-state='err'] .st-dot { background: var(--error); }
body.page-editor .hint[data-state='info'] { border-left-color: var(--accent); background: var(--accent-soft); }
body.page-editor .hint[data-state='info'] .st-dot { background: var(--accent); }
#projList li { display: block; padding: var(--sp-4) var(--sp-5); }
#projList li:hover { border-color: color-mix(in srgb, var(--accent) 55%, var(--border-soft)); }
#projList .tf-meta { display: block; margin: 3px 0 0 20px; font-size: var(--fsx-mini); }
.proj-name { display: block; overflow-wrap: anywhere; word-break: break-word; font-size: var(--fsx-body); line-height: 1.35; }
.clip-check { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; margin: -10px 0 -10px -10px; cursor: pointer; }
.clip-check input { width: 18px; height: 18px; margin: 0; accent-color: var(--accent); cursor: pointer; }
#clipList li.clip-sel { border-color: var(--accent); }

/* ---------------- 编辑动作条（波形下方常驻；基础编辑唯一操作面） ---------------- */
.edit-bar {
  display: flex; flex-direction: column;
  padding: var(--sp-5) var(--sp-6); margin-top: 10px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: var(--panel);
  position: sticky; top: 66px; z-index: 15;
  box-shadow: var(--shadow-sm);
}
.eb-row, .eb-adv, .eb-fx { display: flex; flex-wrap: wrap; gap: var(--sp-4); align-items: center; }
.eb-adv, .eb-fx { margin-top: 8px; padding-top: var(--sp-4); border-top: 1px dashed var(--border-soft); }

/* 剪切列表：并入右侧工作区，状态栏下方整行 */
.ed-panels { grid-template-columns: 1fr; align-items: start; margin-top: 12px; }
.eb-adv .field.mini { flex: 0 0 auto; }
.eb-adv .field.mini input { width: 88px; }
/* 帧率与帧语义说明只在「帧」单位下出现；hidden 必须压过 .field 的 flex 显示 */
#fpsWrap[hidden], #fpsRule[hidden] { display: none; }
.fps-rule { font-size: var(--fs-xs); color: var(--text-dim); line-height: 1.3; }
/* 时间码开关：只在帧单位出现；复选框不能被 .eb-adv .field input 的 88px 宽度规则拉宽 */
#tcWrap[hidden], #tcDropWrap[hidden], #tcRule[hidden] { display: none; }
.eb-adv .tc-field { min-height: 44px; display: flex; align-items: center; gap: var(--sp-2); cursor: pointer; }
.eb-adv .tc-field input { width: 18px; height: 18px; flex: 0 0 18px; margin: 0; }
#tcRule { flex: 1 0 100%; }
.edit-bar .sep { width: 1px; height: 22px; background: var(--border); flex: 0 0 1px; margin: 0 2px; }
.edit-bar .ebi { margin-right: 7px; font-size: var(--ico); font-weight: 400; line-height: 17px; }

/* 缩略总览条 */
.overview {
  display: block;
  width: 100%;
  height: 34px;
  margin-top: 8px;
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  background: var(--panel-2);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: border-color var(--t-fast) var(--e-std);
}
.overview:hover { border-color: color-mix(in srgb, var(--accent) 55%, var(--border-soft)); }
.overview:active { border-color: var(--accent); }
.overview.flash { border-color: var(--accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 42%, transparent); }
.overview[hidden] { display: none; }

/* ---------------- 状态栏 ---------------- */
.statusbar {
  display: grid;
  /* 第43轮：列宽下限跟随字号档位，特大档下状态值（-11.0 dBFS / 00:06.000）不再被省略号截断；
     标准档仍是最小 100px，与原布局一致 */
  grid-template-columns: repeat(auto-fit, minmax(calc(100px * var(--ui-scale, 1)), 1fr));
  gap: 8px;
  margin-top: 12px;
  padding: 12px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.stat {
  min-width: 0;
  padding: 8px 10px;
  background: var(--panel-2);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-sm);
  transition: border-color var(--t-fast) var(--e-std);
}

.stat:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--border)); }
.stat.warn { border-color: color-mix(in srgb, var(--error) 55%, var(--border)); background: color-mix(in srgb, var(--error) 8%, var(--panel-2)); }
.stat.warn b { color: var(--error); }
.stat span { display: block; font-size: 11px; color: var(--muted); letter-spacing: 0.04em; }
.stat .si { display: inline; margin-right: 5px; }
.stat > span:not(.si) { display: inline; }
.stat b { display: block; margin-top: 3px; font-size: 14.5px; font-weight: 650; font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.sel-info {
  grid-column: 1 / -1;
  font-size: var(--fsx-aux);
  color: var(--accent);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  padding: var(--sp-1) var(--sp-2);
}
.sel-info.none { color: var(--muted); font-weight: 400; }

/* ---------------- 编辑页响应式 ---------------- */
@media (max-width: 900px) {
  .header-actions .btn.small { display: none; }
}

@media (max-width: 720px) {
  .wave-wrap { height: 200px; }
  /* 窄屏把波形区压到 200px，而空状态卡里装着标题＋说明＋格式筹码＋按钮（实测内容高 ~254px）：
     卡片是绝对定位在这个 overflow:hidden 的区域里，居中一排就把「选择文件」那一行整排推到可视区外，
     手机上既看不见也点不到。改成从顶部排、卡片自身可滚，并把芯片与内边距收紧到不必滚就能拿到按钮。 */
  .empty-card { justify-content: flex-start; overflow-y: auto; padding: var(--sp-6) var(--sp-6); gap: var(--sp-3); }
  /* 说明改成两栏后单看更高了：窄屏叠成一列要收紧行高与间距，否则三个按钮会被推到可视区外 */
  .empty-card p { line-height: 1.7; }
  .empty-main { gap: var(--sp-4); }
  /* 格式清单在窄屏是重复信息：它上面那句说明已经把 MP3/WAV/OGG/M4A/FLAC 逐个列了一遍，
     而且 260px 的高度里再塞一栏只会把按钮推出去 */
  .empty-card .empty-side { display: none; }
  /* 空状态本来就是「还没有波形」，此时没必要为波形把区域压到 200px；
     回到 260px 才能让三个按钮不靠滚动就完整落在可视区内（实测 200px 时按钮整排在裁切线外）。 */
  .wave-wrap:has(.empty-card:not([hidden])) { height: 260px; }
  .transport { gap: 8px; padding: 10px; }
  .transport .vol-group { margin-left: 0; width: 100%; justify-content: space-between; }
  .transport .tzone-out { margin-left: 0; width: 100%; }
  .transport input[type='range'] { flex: 1; width: auto; }
  .statusbar { grid-template-columns: repeat(3, 1fr); }
  /* 档位系数叠加在窄屏原有的轨道行字号上，避免作用域规则把 12/14/13 顶回桌面值 */
  body.page-editor .mt-gainv { font-size: calc(12px * var(--ui-scale)); }
  body.page-editor .mt-move,
  body.page-editor .mt-rename,
  body.page-editor .mt-dup { font-size: calc(14px * var(--ui-scale)); }
  body.page-editor .mt-offset { font-size: calc(13px * var(--ui-scale)); }
}

/* 超小屏：播放条只留高频控件 */
@media (max-width: 560px) {
  .zoom-slider { display: none; }
}

@media (max-width: 400px) {
  .statusbar { grid-template-columns: repeat(2, 1fr); }
}

/* ---------------- 第45轮：小屏 EQ 精细调节（只作用于 editor.html） ---------------- */
/* 十段 EQ 的两排 10 段在 HTML 里合成一个 .row.eq10：桌面用 5 列网格，排布与原来一致；
   窄屏在下面 480px 段改成 2 列，把每段行程从 33.6px 提到约 135px */
body.page-editor .row.eq10 { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); }

/* 窄屏编辑器工具条：一排改横滑，粘性条才留得下波形区（按钮一个不少，只是不再逐颗折行） */
@media (max-width: 480px) {
  .eb-row, .eb-adv, .eb-fx { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: thin; overscroll-behavior-x: contain; }
  .eb-row > *, .eb-adv > *, .eb-fx > * { flex: 0 0 auto; white-space: nowrap; }
  /* 带滑杆的 .field.mini 自带 flex: 0 1 auto，窄屏横滑条里会被压成 0 宽，
     里面的标签/滑杆/数值直接盖到后面的按钮上；这里让它按内容宽度占位，随整条横滑 */
  .eb-row > .field, .eb-adv > .field, .eb-fx > .field { flex: 0 0 auto; }
  .edit-bar { padding: var(--sp-3) var(--sp-5); }
  .ed-head { padding: 7px 10px; gap: 6px; margin-bottom: 6px; }
  .transport { margin-top: 6px; padding: 6px 8px; gap: 6px; }
  /* 播放条与动作条同一种窄屏节奏：一排横滑，别逐组换行吃掉半屏 */
  .transport { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: thin; }
  .transport > * { flex: 0 0 auto; }
  .transport .tzone-out, .transport .vol-group { margin-left: 0; }
  /* 横滑条里的文字按钮（含「缩放到选区 / 缩放到光标」）：高度抬到 44px，手指点得中。
     整条本来就不换行，加高只让播放条厚 14px，不挤占波形 */
  .transport .btn.small { min-height: 44px; }
  /* 编辑动作条同理：窄屏横滑时按钮、数字框与下拉都抬到 44px，手指点得准；
     只加高不加宽，整条仍然一排行滑，不挤占波形 */
  .edit-bar .btn.small, .eb-adv .field.mini input, .eb-adv .field.mini select,
  .eb-fx .field.mini input, .eb-fx .field.mini select, .edit-bar .chk { min-height: 44px; }
  .edit-bar .chk { display: inline-flex; align-items: center; }
  /* 播放条上的勾选项（含新增的「精细吸附」）同样要有 44px 的点击高度；
     它们本来就在可换行的 tzone 里，加高只让这一组多占一行，不会横向溢出 */
  .transport .chk { min-height: 44px; }
  /* 「保留 WAV 原采样率」在空状态与素材区都出现，窄屏同样要 44px 的点击高度 */
  .chk.keep-rate { min-height: 44px; }
  /* 第39轮：面板内的勾选项（保留音高 / 仅导出选区 / 末尾淡出）此前只有 21.4px，
     与已抬到 44px 的其他控件不一致；窄屏统一补齐触控高度 */
  .page-editor .panel .chk { min-height: 44px; }
  /* 顶栏图标钮、播放/缩放图标钮与滑杆在 390px 下只有 32–40px，手指容易点偏；
     统一抬到 44px 触控目标。顶栏动作区本来就换行、播放条本来横滑，只增高不改变可达性 */
  .page-editor .btn.icon, .page-editor .transport .btn.icon { width: 44px; height: 44px; flex: 0 0 44px; }
  .page-editor .chip-btn, .page-editor .theme-btn { width: 44px; height: 44px; flex: 0 0 44px; }
  .page-editor .ed-head .link-btn { min-height: 44px; }
  .page-editor .modal-foot .btn { min-height: 44px; }
  .page-editor .edit-bar input[type='range'] { min-height: 44px; }
  /* 播放条与右侧面板里的下拉/滑杆/数值框也按 44px 触控目标抬齐：
     只改高度、不改宽度，横滑区与面板仍各自滚动，不会挤出横向溢出 */
  .page-editor .transport select, .page-editor .transport input[type='range'],
  .page-editor .side select, .page-editor .side input[type='number'] { min-height: 44px; }
  .statusbar { gap: 6px; padding: 8px; margin-top: 8px; }
  .stat { padding: 4px 7px; }
  .stat b { display: inline; margin: 0 0 0 5px; font-size: 12.5px; }
  .stat > span { font-size: 10.5px; }
  .stat .si { margin-right: 3px; font-size: 11px; }
  body.page-editor .statusbar .stat b { font-size: calc(12.5px * var(--ui-scale)); }
  body.page-editor .statusbar .stat > span { font-size: calc(10.5px * var(--ui-scale)); }
  /* 窄屏字号选择器保持 44px 点按高度：用更高特异性，避免被文件末尾的基础规则按顺序盖回去 */
  body.page-editor .header-actions .ui-font select { min-height: 44px; }
  /* 第45轮：390 宽 EQ 十段每段行程仅 33.6px（0.5 dB 台阶占 0.7px），点按落不到全部台阶；
     侧栏内改 5 行×2 列，每段行程约 135px（2.8px/0.5 dB），48 个台阶全部可点中。
     只改列数，不动控件、文案与桌面 5×2 排布 */
  body.page-editor .row.eq10 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* 第46轮：390 宽下 .row.row3 仍是三列并排（字段 102.7px、行程 78.7px），
     压缩器启动/释放 0.8px 一档、噪声门启动/释放/保持 1.6px 一档，手指点不到目标值。
     这里把 row3 的字段改成整行一个（行程 304px）：启动 3.07px/档、释放 3.10px/档、
     门 6.2px/档，全部台阶可落点；不改控件类型、不加手势、桌面三列排布不变。
     同一条规则顺带把 EQ 低频/中频/高频、混响/回声/失真、迟滞等 row3 参数统一放宽 */
  body.page-editor .row.row3 > .field { flex: 1 1 100%; min-width: 100%; }
  /* 第47轮：单列后效果面板 2202→3968px（+80%）。把 row3 临时改回三列实测 2810px，
     即其中约 1158px 是单列本身必要的高度，其余来自每个字段「标签一行 + 读数一行 +
     滑杆一行」的三段占位。这里只把标签与读数并成一行（读数右对齐），滑杆仍整行、
     行程不变、控件高度仍 44px：实测 3968→3012px（-24%），每档像素 2.81 不变
     （EQ 2.81 / 压缩器 3.07 / 噪声门 6.20），不涉及列数变化，也没有缩小任何控件 */
  body.page-editor #ePanelFx .field { gap: 4px; }
  body.page-editor #ePanelFx .field output { margin-top: 0; }
  body.page-editor #ePanelFx .row + .row { margin-top: 6px; }
  body.page-editor #ePanelFx .row.row-fxsub { margin-top: 8px; }
  body.page-editor #ePanelFx .field:not(.mini) { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 8px; row-gap: 4px; align-items: center; }
  body.page-editor #ePanelFx .field:not(.mini) > span { grid-column: 1; grid-row: 1; min-width: 0; }
  body.page-editor #ePanelFx .field:not(.mini) > output { grid-column: 2; grid-row: 1; margin: 0; text-align: right; white-space: nowrap; }
  body.page-editor #ePanelFx .field:not(.mini) > input[type='range'],
  body.page-editor #ePanelFx .field:not(.mini) > select,
  body.page-editor #ePanelFx .field:not(.mini) > input[type='number'],
  body.page-editor #ePanelFx .field:not(.mini) > .numstep { grid-column: 1 / -1; grid-row: 2; width: 100%; margin: 0; }
}

/* ---------------- 第48轮：481–768 中间宽度（平板竖屏 / 横屏手机） ---------------- */
/* 这段宽度原来既没有 390 的单列，也没放宽 EQ 网格：十段 EQ 固定 5 列（481→75.8px、600→99.6px、
   768→133.2px，每档 1.08 / 1.57 / 2.27px），压缩器启动/释放三列并排（133–228.7px，1.10–2.09px）。
   这里不套用 390 的整行单列（实测 +1159px 且救不了 EQ），只按「点不中的行」加宽：
   · 十段 EQ 用 auto-fill 144px（144px 是 48 档 × 2.5px + 拇指 24px 的下限），
     481→2 列（204.5px，3.76px/档）、600→3 列（172.7px，3.10px/档）、768→4 列（169px，3.02px/档）；
   · 压缩器启动/释放（99/98 档）auto-fit 280px：481/600→整行（419/538px）、768→2 列（348px）；
   · 噪声门启动/释放/保持 149px、低/中/高频 144px、压缩阈值 174px 各自只到刚过 2.5px/档的列数；
   · 再套用第 47 轮 390 的「标签左、读数右、滑杆整行」与行距压缩，抵掉加宽带来的高度。
   实测面板总高 481：2468→2565、600：2369→2227、768：2002→1691；全部 31 个滑杆 ≥2.97px/档 */
@media (min-width: 481px) and (max-width: 768px) {
  body.page-editor .row.eq10 { grid-template-columns: repeat(auto-fill, minmax(144px, 1fr)); }
  body.page-editor .row.row3:has(#eqLowRange) { display: grid; grid-template-columns: repeat(auto-fit, minmax(144px, 1fr)); gap: 10px; }
  body.page-editor .row.row3:has(#gateAttack) { display: grid; grid-template-columns: repeat(auto-fit, minmax(149px, 1fr)); gap: 10px; }
  body.page-editor .row.row3:has(#compThreshold) { display: grid; grid-template-columns: repeat(auto-fit, minmax(174px, 1fr)); gap: 10px; }
  body.page-editor .row.row3:has(#compAttack) { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 10px; }
  body.page-editor #ePanelFx .field { gap: 4px; }
  body.page-editor #ePanelFx .field output { margin-top: 0; }
  body.page-editor #ePanelFx .row + .row { margin-top: 6px; }
  body.page-editor #ePanelFx .row.row-fxsub { margin-top: 8px; }
  body.page-editor #ePanelFx .field:not(.mini) { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 8px; row-gap: 4px; align-items: center; }
  body.page-editor #ePanelFx .field:not(.mini) > span { grid-column: 1; grid-row: 1; min-width: 0; }
  body.page-editor #ePanelFx .field:not(.mini) > output { grid-column: 2; grid-row: 1; margin: 0; text-align: right; white-space: nowrap; }
  body.page-editor #ePanelFx .field:not(.mini) > input[type='range'],
  body.page-editor #ePanelFx .field:not(.mini) > select,
  body.page-editor #ePanelFx .field:not(.mini) > input[type='number'],
  body.page-editor #ePanelFx .field:not(.mini) > .numstep { grid-column: 1 / -1; grid-row: 2; width: 100%; margin: 0; }
}

/* ---------------- 第49轮：769–899（平板横屏 / 小笔电）只修两行 ---------------- */
/* 这段上轮没覆盖，仍按桌面：十段 EQ 固定 5 列、压缩器三列。800 实测 EQ 2.41px/档、
   压缩启动 2.18 / 释放 2.20（12 个滑杆低于 2.5）；900 起已 2.51+、1000 为 2.85，不动。
   只让这两行按可用宽度自动减列：800 → EQ 4 列、压缩器 2 列；899 仍 5 列 / 2 列 */
@media (min-width: 769px) and (max-width: 899px) {
  body.page-editor .row.eq10 { grid-template-columns: repeat(auto-fill, minmax(144px, 1fr)); }
  body.page-editor .row.row3:has(#compAttack) { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 10px; }
}

/* ---------------- 第47轮：触摸下的数值步进（editor only） ---------------- */
/* 原生 number 步进箭头实测命中区仅 9×13px（1440），390 触摸下 30 点探针 0 命中。
   给编辑器内每个数字框补一对 −/+ 按钮：只在粗指针设备显示，44×44，长按 400ms 后
   每 80ms 连发，到达上下限时按钮置灰并给出回执；步长直接读 input.step，与方向键同源 */
.numstep { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.numstep > input { min-width: 0; flex: 1 1 auto; }
.numstep .step-btn { display: none; }
.field.mini .numstep { flex: 0 0 auto; }

@media (pointer: coarse) {
  .numstep .step-btn {
    display: inline-flex; align-items: center; justify-content: center;
    flex: 0 0 44px; width: 44px; height: 44px; min-width: 44px; padding: 0;
    font-size: 20px; font-weight: 600; line-height: 1; border-radius: 10px;
  }
  .numstep .step-btn[aria-disabled='true'] { opacity: 0.45; cursor: not-allowed; }
  /* 触摸下隐藏原生箭头，避免出现第二个点不中的步进控件 */
  .numstep input[type='number'] { -webkit-appearance: textfield; appearance: textfield; }
  .numstep input[type='number']::-webkit-inner-spin-button,
  .numstep input[type='number']::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
}

/* 第48轮：桌面（细指针）原生 spinner 实测可点区 16×8 / 12×8，鼠标几乎点不中。
   同一对 −/+ 按钮在细指针下改为 28×33（两个维度都 ≥24），贴着输入框左右排；
   不改变 .eb-adv / 效果面板的行高（1440 实测工具条 238px 不变），也不影响页签、下拉与滑杆 */
@media (pointer: fine) {
  .numstep .step-btn {
    display: inline-flex; align-items: center; justify-content: center;
    flex: 0 0 28px; width: 28px; height: 33px; min-width: 28px; padding: 0;
    font-size: 15px; font-weight: 600; line-height: 1; border-radius: 7px;
  }
  .numstep .step-btn[aria-disabled='true'] { opacity: 0.45; cursor: not-allowed; }
  /* 有自有按钮后隐藏原生箭头：16×8 的旧热区不再作为唯一入口 */
  .numstep input[type='number'] { -webkit-appearance: textfield; appearance: textfield; }
  .numstep input[type='number']::-webkit-inner-spin-button,
  .numstep input[type='number']::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
}

/* 第42轮：视觉层级——左侧「准备类」主按钮从填充色降为描边权重，
   首屏只留「播放 / 导出 WAV」两个填充色主操作。只改颜色权重，不改尺寸、位置与任何文案。
   本文件只被 editor.html 引用，30 个工具页不受影响。 */
body.page-editor .ed-side #btnProjSave,
body.page-editor .ed-side #btnAddAudio,
body.page-editor .ed-side #btnMtEnable {
  background: color-mix(in srgb, var(--accent) 9%, transparent);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  color: var(--accent);
  box-shadow: none;
}
body.page-editor .ed-side #btnProjSave:hover:not(:disabled),
body.page-editor .ed-side #btnAddAudio:hover:not(:disabled),
body.page-editor .ed-side #btnMtEnable:hover:not(:disabled) {
  background: color-mix(in srgb, var(--accent) 16%, transparent);
  border-color: color-mix(in srgb, var(--accent) 70%, transparent);
  color: var(--accent);
  filter: none;
  box-shadow: none;
}
/* 第45轮：WCAG AA 复核——这三个描边主按钮在浅色主题是 accent 文字压 9% accent 底，
   实测 4.03:1（12px/500 需 4.5:1）；仅浅色把文字再压深一档（常态 5.18:1、悬停 4.76:1）。
   深色主题原组合 6.35/5.66:1 已通过，不重复声明；底色、描边、尺寸、文案均不动 */
[data-theme='light'] body.page-editor .ed-side #btnProjSave,
[data-theme='light'] body.page-editor .ed-side #btnAddAudio,
[data-theme='light'] body.page-editor .ed-side #btnMtEnable,
[data-theme='light'] body.page-editor .ed-side #btnProjSave:hover:not(:disabled),
[data-theme='light'] body.page-editor .ed-side #btnAddAudio:hover:not(:disabled),
[data-theme='light'] body.page-editor .ed-side #btnMtEnable:hover:not(:disabled) {
  color: color-mix(in srgb, var(--accent) 76%, #0b1b33);
}

/* 第42轮：标记列表组（h2 标题）此前带折叠箭头与 pointer 光标却没接线；
   补上后与其余 11 个 h3 分组一致（折叠状态同样写进 grpCollapsed365）。
   panels.css 的 .group.collapsed > :not(h3) 会把 h2 一起藏掉，这里按编辑器作用域还原标题行。 */
body.page-editor .group.collapsed > h2 { display: flex; }
body.page-editor .group.collapsed > h2::after { transform: rotate(-90deg); }

/* ---------------- 第43轮：键盘跳转与界面字号档位（均只作用于 editor.html） ---------------- */

/* 跳转链接：平时移出视口，键盘聚焦时浮出，回车把焦点送到侧栏当前页签。
   第44轮：浮出位置由脚本量头栏空档后写入 --skip-l/--skip-t，不再固定压左上角品牌字；
   量不到空档时脚本给头栏下沿之外的值，这两个默认值只作无脚本兜底 */
.skip-link {
  position: fixed;
  left: var(--skip-l, 12px);
  top: var(--skip-t, 12px);
  z-index: 60;
  padding: 10px 16px;
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  text-decoration: none;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-160%);
  transition: transform var(--t-fast) var(--e-std), opacity var(--t-fast) var(--e-std);
}
.skip-link:focus,
.skip-link:focus-visible {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
  outline: none;
  box-shadow: var(--ring);
}

/* 顶栏的界面字号选择器：与语言/主题按钮同排，避免藏进面板深处 */
body.page-editor .ui-font { display: inline-flex; align-items: center; }
body.page-editor .ui-font select {
  min-height: 34px;
  padding: 3px 8px;
  border: 1px solid var(--border);
  border-radius: 99px;
  background: var(--panel);
  color: var(--text);
  font-family: inherit;
  font-size: calc(12.5px * var(--ui-scale));
  cursor: pointer;
}
body.page-editor .ui-font select:hover { border-color: var(--accent); color: var(--accent); }

/* 顶栏与页脚字号也随档位缩放（仍限定在 page-editor，工具页的同一套 chrome 不受影响） */
body.page-editor .brand-name { font-size: calc(16.5px * var(--ui-scale)); }
body.page-editor .brand-name small { font-size: calc(11.5px * var(--ui-scale)); }
body.page-editor .main-nav a { font-size: calc(14px * var(--ui-scale)); }
body.page-editor .chip-btn { font-size: calc(13px * var(--ui-scale)); }
body.page-editor .site-footer { font-size: calc(12.5px * var(--ui-scale)); }
body.page-editor .footer-grid h3 { font-size: calc(13.5px * var(--ui-scale)); }

/* 不走字号令牌的历史 px 文本：按同一系数缩放，档位才是“整体”而不是只放大面板标题 */
body.page-editor .edit-bar .btn.small { font-size: calc(12.5px * var(--ui-scale)); }
body.page-editor .edit-bar .chk { font-size: calc(13px * var(--ui-scale)); }
body.page-editor .statusbar .stat > span { font-size: calc(11px * var(--ui-scale)); }
body.page-editor .statusbar .stat b { font-size: calc(14.5px * var(--ui-scale)); }
body.page-editor .row-nrprog .nrprog-phase { font-size: calc(13px * var(--ui-scale)); }
body.page-editor .rec-head { font-size: calc(14px * var(--ui-scale)); }
body.page-editor .rec-time { font-size: calc(22px * var(--ui-scale)); }
body.page-editor .mt-name,
body.page-editor .mt-name-edit,
body.page-editor .mt-del,
body.page-editor .mt-mute,
body.page-editor .mt-solo { font-size: calc(12.5px * var(--ui-scale)); }
body.page-editor .mt-gainv { font-size: calc(11px * var(--ui-scale)); }
body.page-editor .mt-off-lbl,
body.page-editor .mt-offset { font-size: calc(12px * var(--ui-scale)); }
body.page-editor .mt-move,
body.page-editor .mt-rename,
body.page-editor .mt-dup { font-size: calc(11px * var(--ui-scale)); }

/* ---------------- 第44轮：空状态一致性与触屏滑杆热区（均只作用于 editor.html） ---------------- */

/* 空列表占位行统一。素材/标记/导出记录本来就是 13px/1.55，只有工程列表的空行继承
   .proj-name 的 var(--fsx-body)/1.35，特大档下变成 16.25px/21.9px，与其它三个列表割裂；
   这里只规范占位行，不动真实列表行（.tool-files 是 30 个工具页共用组件） */
body.page-editor .ed-side .list-ph { font-size: 13px; line-height: 1.55; }

/* 触屏滑杆热区。panels.css 给粗指针滑杆加了 padding:8px 0，但滑杆本身是固定 22px 的
   border-box，padding 把内容压成 6px、盒子仍 22px，加大的热区被吞掉；这里显式抬到 44px
   并让上下 padding 对称，24px 的拇指才真正有可操作的纵向余量 */
@media (pointer: coarse) {
  body.page-editor .ed-side input[type='range'] { height: 44px; padding: 19px 0; }
}
