/* ── Handpan Noter — 现代化视觉系统（2026-05-02 重构） ── */
/* 路线 A：克制工具感（Linear / Things / Cron 系）              */
/* 设计令牌见 docs/2026-05-02-modern-redesign.md §2              */

:root {
  /* 配色：F1 粉桃 + 鼠尾草（清新温馨疗愈，2026-05-02 选定） */
  /* 中性色阶（浅色 — 设计图采样 2026-05-07）
     bg-0=谱子 paper rgb(252,248,244) / bg-1=页面 rgb(253,249,246) / bg-2=卡 rgb(240,228,220, 微粉米) */
  --bg-0: #fcf8f4;
  --bg-1: #fdf9f6;
  --bg-2: #f0e4dc;
  --bg-3: #e6dccd;
  --bg-4: #b7a98c;

  --ink-0: #2b2418;
  --ink-1: #5a4f3e;
  --ink-2: #948871;
  --ink-3: #c4b9a3;

  /* accent — 粉桃 (rh) + 鼠尾草绿 (lh) + 主 accent 走桃红（title / 选中态强调，2026-05-07） */
  --rh: #db7d6a;
  --lh: #5b9573;
  --accent: #c87864;
  --accent-soft: rgba(200, 120, 100, 0.13);
  --accent-ring: rgba(200, 120, 100, 0.32);

  /* 阴影 elevation */
  --e0: none;
  --e1: 0 1px 2px rgba(0,0,0,0.04), 0 1px 3px rgba(0,0,0,0.06);
  --e2: 0 4px 12px rgba(0,0,0,0.06), 0 2px 4px rgba(0,0,0,0.05);
  --e3: 0 12px 32px rgba(0,0,0,0.10), 0 4px 12px rgba(0,0,0,0.06);

  /* radius / motion */
  --r-sm: 6px; --r-md: 10px; --r-lg: 14px; --r-xl: 22px;
  --ease: cubic-bezier(0.32, 0.72, 0, 1);
  --t-fast: 0.12s; --t-med: 0.22s; --t-slow: 0.4s;

  /* 谱面尺寸 */
  --score-row-height: 36px;

  /* 模块间距 / gutter（卡片化与留白用） */
  --gap-xs: 4px;
  --gap-sm: 8px;
  --gap-md: 16px;
  --gap-lg: 24px;
  --gap-xl: 32px;

  /* 谱面色（指向 token，便于暗色）
     editor 与 practice 故意取不同强度：editor 编辑场景需要看清拍 / 子分边界（高对比），
     practice 练琴场景追求"呼吸感"（拍线弱化、子分线雾里参考）。
     practice 的弱化值在 practice.css 里 hardcode（barline 0.50 / beatline 0.22 / subline 0.08）。
     这里给 editor 用更深的 ink 色族 + 更高的 opacity，避免之前用 bg-4 → 几乎与背景同色看不清。 */
  --paper-bg: var(--bg-0);
  --paper-ink: var(--ink-0);
  --barline: color-mix(in srgb, var(--ink-0) 50%, transparent);
  --beatline: color-mix(in srgb, var(--ink-2) 42%, transparent);
  --subline:  color-mix(in srgb, var(--ink-3) 50%, transparent);
}

[data-theme="dark"] {
  /* F1 暗色版 — 浅奶米暗化 + 粉桃/鼠尾草提亮 */
  --bg-0: #1d1a16;
  --bg-1: #26221c;
  --bg-2: #2f2a23;
  --bg-3: #3e3830;
  --bg-4: #564f43;

  --ink-0: #f5ecdd;
  --ink-1: #c4b8a2;
  --ink-2: #918672;
  --ink-3: #5b5346;

  --rh: #ed9a86;
  --lh: #8cba9a;
  --accent: #e3a16a;
  --accent-soft: rgba(227, 161, 106, 0.16);
  --accent-ring: rgba(227, 161, 106, 0.42);

  --e1: 0 1px 2px rgba(0,0,0,0.4), 0 1px 3px rgba(0,0,0,0.3);
  --e2: 0 4px 12px rgba(0,0,0,0.4), 0 2px 4px rgba(0,0,0,0.3);
  --e3: 0 12px 32px rgba(0,0,0,0.5), 0 4px 12px rgba(0,0,0,0.4);

  --paper-bg: var(--bg-0);
  --paper-ink: var(--ink-0);
  --barline: color-mix(in srgb, var(--ink-0) 50%, transparent);
  --beatline: color-mix(in srgb, var(--ink-2) 42%, transparent);
  --subline:  color-mix(in srgb, var(--ink-3) 50%, transparent);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { height: 100%; }
body {
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text", "Inter", "Helvetica Neue", sans-serif;
  background: var(--bg-1);
  color: var(--ink-0);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: background var(--t-med) var(--ease), color var(--t-med) var(--ease);
}

/* ── 工具栏 ── */
#toolbar {
  position: sticky; top: 0; z-index: 100;
  flex-shrink: 0;
  background: var(--bg-1);
  border-bottom: 1px solid color-mix(in srgb, var(--ink-3) 18%, transparent);
  padding: 8px 20px;
  transition: background var(--t-med) var(--ease), border-color var(--t-med) var(--ease);
}

/* practice-topbar 风格叠加在 #toolbar 上：grid 两行（主控件 / 进度细线；mini-map 已迁主区顶部 sticky）
   Stage 2: 高度统一到 var(--topbar-h)=72px，跟 practice 页一致；padding 同 24px。
   header 跨整 viewport 100% 宽（brand 在最左角），sidebar 在 header 下面（main-wrapper 内）。 */
#toolbar.practice-topbar {
  padding: 0 24px;
  position: sticky;
  height: auto;
  grid-template-rows: var(--topbar-h, 72px);
  align-items: center;
}
/* editor 页播放球与 practice 页统一为 56px 圆球 */
#toolbar.practice-topbar #btnPlay.practice-play-btn { width: 56px; height: 56px; }
#toolbar.practice-topbar #btnPlay.practice-play-btn svg { width: 22px; height: 22px; }
#toolbar.practice-topbar .practice-play-wrap { gap: 0; }
/* 顶栏不再显示"待机/播放中"文字：播放图标(▶/■) + 进度条 + loop is-active 已经足够反馈，
   且这行字撑高 .practice-play-wrap 会让播放球在 64px 行内偏上 */
#toolbar.practice-topbar .practice-play-status { display: none; }
/* loop / 沉浸练习按钮已下沉到 inspector「编辑工具」卡——
   原 #toolbar .topbar-loop-btn / .topbar-practice-btn 规则不再有命中目标，删除。 */
#toolbar.practice-topbar .practice-icon-btn { width: 36px; height: 36px; }
#toolbar.practice-topbar .practice-icon-btn svg { width: 17px; height: 17px; }
#toolbar.practice-topbar .practice-bpm-value { font-size: 17px; }
#toolbar.practice-topbar .practice-bpm-icon { font-size: 13px; }
#toolbar.practice-topbar .practice-topbar-right { gap: 10px; }
/* 让 #toolbar 内的左/中/右区域生效 grid 单元（练习模式定义的 flex 内部不变） */
#toolbar.practice-topbar .practice-topbar-left  { grid-row: 1; justify-self: start;  }
#toolbar.practice-topbar .practice-topbar-center{ grid-row: 1; justify-self: center; }
#toolbar.practice-topbar .practice-topbar-right { grid-row: 1; justify-self: end;    }
/* 播放细线 absolute 贴 toolbar 底沿，不占 grid 物理空间（toolbar 严格 64px） */
#toolbar.practice-topbar #playback-progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  width: auto;
  height: 2px;
}
/* 文件 / 编辑 / 更多 menu cluster 在新 topbar 里横排 */
#toolbar.practice-topbar .toolbar-cluster { gap: 4px; flex-wrap: nowrap; }
#toolbar.practice-topbar .toolbar-group { min-height: auto; }
/* BPM 按钮：保留静态底，但去掉边框（边框是上次"灰胶囊"感的主因），hover 加深一档 */
#toolbar.practice-topbar .practice-bpm.bpm-display {
  background: var(--bg-2);
  border: 0;
  cursor: pointer; padding: 7px 14px;
  border-radius: 10px;
  /* 锁定按钮宽度：与 .practice-bpm-input 同 width + box-sizing，避免编辑切换时跳动 */
  box-sizing: border-box;
  width: 92px;
  justify-content: center;
  transition: background var(--t-fast) var(--ease);
}
#toolbar.practice-topbar .practice-bpm.bpm-display:hover {
  background: var(--bg-3);
}

/* editor 的 header 曲名（#songTitle）点击触发 renameCurrentScore，加可点提示与 hover 反馈。
   practice 页 #songTitle 不可点（只读），靠 .app-song-title 区分。 */
.app-song-title {
  cursor: pointer;
  border-radius: 4px;
  padding: 2px 4px;
  margin: -2px -4px;
  transition: background var(--t-fast) var(--ease);
}
.app-song-title:hover { background: var(--bg-2); }
.app-song-title:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* editor topbar subtitle 内的 inline BPM 按钮（Stage 2 加入）。
   不同于 right slot 的 .practice-bpm.bpm-display 那种胶囊；这里是 subtitle 行内的极简按钮——
   样式要融入 .practice-subtitle 文本流（12px、ink-2 颜色）。 */
.bpm-display-inline {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
  background: transparent;
  border: 0;
  padding: 0 2px;
  margin: 0;
  font: inherit;
  color: var(--ink-2);
  cursor: pointer;
  border-radius: 4px;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.bpm-display-inline:hover { background: var(--bg-2); color: var(--ink-0); }
.bpm-display-inline .practice-bpm-icon { font-size: 12px; color: var(--ink-2); }
.bpm-display-inline .practice-bpm-value { font-weight: 600; color: var(--ink-1); font-variant-numeric: tabular-nums; }

/* BPM 内联输入（编辑时临时替代 #bpmDisplay；与按钮等高 + 等宽，避免编辑态跳动） */
.practice-bpm-input {
  font: inherit;
  font-size: 17px;
  font-weight: 600;
  color: var(--ink-0);
  background: var(--bg-2);
  border: 1px solid var(--accent);
  border-radius: 10px;
  padding: 7px 12px;
  box-sizing: border-box;
  width: 92px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  outline: 0;
  box-shadow: 0 0 0 3px var(--accent-soft);
  -moz-appearance: textfield;
  appearance: textfield;
}
.practice-bpm-input::-webkit-outer-spin-button,
.practice-bpm-input::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}

/* 文件 / 编辑 menu summary：静态底（无边框），hover / open 加深 */
#toolbar.practice-topbar .toolbar-menu > .toolbar-menu-summary {
  background: var(--bg-2);
  border: 0;
  padding: 7px 12px;
  border-radius: 10px;
}
#toolbar.practice-topbar .toolbar-menu > .toolbar-menu-summary:hover {
  background: var(--bg-3);
}
#toolbar.practice-topbar .toolbar-menu[open] > .toolbar-menu-summary {
  background: var(--bg-3);
}

/* 圆形 icon 按钮（⌘K / 用户）：静态底（无边框），hover 加深。
   loop 按钮已搬到 inspector，原 .topbar-loop-btn 视觉已删。 */
#toolbar.practice-topbar .practice-icon-btn {
  background: var(--bg-2);
  border: 0;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
#toolbar.practice-topbar .practice-icon-btn:hover {
  background: var(--bg-3);
}
/* hand-mute R/L 在新 topbar 里保持紧凑 */
#toolbar.practice-topbar .hand-mute { display: inline-flex; gap: 2px; }
/* 新 burger 在桌面隐藏（已 hidden 属性）；在 ≤820px 由旧 mobile-hamburger 规则接管显示 */
#toolbar.practice-topbar .practice-burger { margin-right: 4px; }
/* btnPlay 在播放/停止时 editor.js 会 set textContent="■" 把 SVG 抹掉 —— 让圆按钮在纯文字态依然居中 */
#toolbar.practice-topbar #btnPlay.practice-play-btn {
  font-size: 22px; line-height: 1;
}

/* 品牌文字（顶栏最左，practice-topbar-left 内首项；移动端隐藏避免挤压） */
.topbar-brand {
  display: inline-flex;
  align-items: center;
  margin-right: 12px;
  user-select: none;
}
.topbar-brand-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-1);
  letter-spacing: 0.01em;
  white-space: nowrap;
}
@media (max-width: 820px) {
  .topbar-brand { display: none; }
}

/* 播放进度条 — header 下方独立细线，播放期间显隐由 editor.js 控制 */
#playback-progress {
  flex-shrink: 0;
  height: 2px;
  width: 100%;
  background: transparent;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--t-med) var(--ease);
  position: relative;
  z-index: 99;
  overflow: hidden;
}
#playback-progress.active { opacity: 1; }
.playback-progress-fill {
  height: 100%;
  width: 100%;
  background: var(--accent);
  box-shadow: 0 0 8px var(--accent-ring);
  transform-origin: left center;
  transform: scaleX(0);
  /* JS 每帧直接写 transform，不要在这里加 transition 导致游标"追尾" */
  will-change: transform;
}
.toolbar-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.toolbar-primary { justify-content: space-between; }
/* deprecated 2026-05-07：toolbar-secondary 已合并到主行的"更多"菜单，保留规则以防外部引用 */
.toolbar-secondary { display: none; }
.toolbar-cluster { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

/* HTML5 hidden 属性强制生效——本项目里 .toolbar-cluster / .toolbar-group / button 等
   都设了显式 display 规则，会覆盖浏览器默认的 [hidden]{display:none}。这条 important 规则
   兜底，让 hidden 始终隐藏。 */
[hidden] { display: none !important; }
.toolbar-group {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 30px;
  padding: 0; border: 0; border-radius: 0;
  background: transparent;
}
.playback-group { gap: 8px; }
.toolbar-right { gap: 6px; margin-left: auto; }
.toolbar-sep { width: 1px; height: 20px; background: var(--bg-3); margin: 0 4px; }
.toolbar-label {
  font-size: 11px; font-weight: 500;
  color: var(--ink-2);
  letter-spacing: 0.02em;
  margin-right: 2px;
}

#toolbar button,
#toolbar .btn-label,
#toolbar .strike-summary,
#toolbar .toolbar-menu-summary {
  background: transparent;
  color: var(--ink-1);
  border: 1px solid transparent;
  border-radius: var(--r-md);
  padding: 4px 11px;
  cursor: pointer;
  font-size: 12px;
  font-weight: 500;
  font-family: inherit;
  transition:
    background var(--t-fast) var(--ease),
    border-color var(--t-fast) var(--ease),
    color var(--t-fast) var(--ease),
    transform var(--t-fast) var(--ease);
}
#toolbar button:hover,
#toolbar .btn-label:hover,
#toolbar .strike-summary:hover,
#toolbar .toolbar-menu-summary:hover {
  background: var(--bg-2);
  color: var(--ink-0);
}
#toolbar button:active { transform: scale(0.97); }
#toolbar button:disabled { opacity: 0.4; cursor: default; transform: none; }

.btn-play {
  background: var(--accent) !important;
  color: #fff !important;
  border: 0 !important;
  border-radius: 50% !important;
  width: 38px; height: 38px; padding: 0 !important;
  font-size: 15px !important;
  display: flex !important; align-items: center; justify-content: center;
  box-shadow: var(--e1);
  transition: transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease), background var(--t-fast) var(--ease) !important;
}
.btn-play:hover {
  background: var(--accent) !important;
  filter: brightness(1.06);
  box-shadow: var(--e2);
  transform: translateY(-1px);
}
.btn-play:active { transform: scale(0.95) !important; }

.play-status {
  min-width: 38px;
  font-size: 11px;
  color: var(--ink-2);
  letter-spacing: 0.02em;
}
.play-status.active,
.play-status.looping { color: var(--accent); font-weight: 600; }

/* ── BPM 顶栏常显（点击改） ── */
.bpm-display {
  font-variant-numeric: tabular-nums;
  font-size: 12px !important;
  font-weight: 600 !important;
  color: var(--ink-1) !important;
  padding: 4px 9px !important;
  white-space: nowrap;
  letter-spacing: 0.02em;
}
.bpm-display:hover { color: var(--ink-0) !important; }
.bpm-display #bpmValue { color: var(--ink-0); margin-left: 1px; }
.bpm-display:hover #bpmValue { color: var(--ink-0); }

.import-status {
  min-width: 0;
  font-size: 11px;
  color: var(--ink-2);
  white-space: nowrap;
}
.import-status.active,
.import-status.error { min-width: 64px; }
.import-status.active { color: var(--accent); font-weight: 600; }
.import-status.error { color: #d04848; font-weight: 600; }

.toolbar-menu { position: relative; }
.toolbar-menu-summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 26px;
  user-select: none;
}
.toolbar-menu-summary::-webkit-details-marker { display: none; }
.toolbar-menu-summary::after {
  content: "▾";
  font-size: 9px;
  color: var(--ink-2);
  transition: transform var(--t-fast) var(--ease);
}
.toolbar-menu[open] .toolbar-menu-summary::after { transform: rotate(180deg); }
.toolbar-menu-panel {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 220;
  display: grid;
  grid-template-columns: 1fr;
  gap: 4px;
  min-width: 144px;
  max-width: min(92vw, 280px);
  max-height: min(70vh, 360px);
  overflow-y: auto;
  padding: 6px;
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-md);
  box-shadow: var(--e3);
}
.playback-settings .toolbar-menu-panel { left: auto; right: 0; }

/* 更多工具菜单（合并的 secondary 行，分 section 排版） */
.more-tools-panel {
  min-width: 280px;
  max-width: min(94vw, 340px);
  max-height: min(78vh, 520px);
  padding: 8px;
  gap: 8px;
}
.more-tools-section {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 8px 6px 10px;
  border-bottom: 1px dashed var(--bg-3);
}
.more-tools-section:last-child { border-bottom: 0; padding-bottom: 4px; }
.more-tools-section-title {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-2);
  padding-left: 2px;
}
.more-tools-strike {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.more-tools-stepper-row {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.more-tools-button-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}
/* 在 panel 中的 strike / stepper / grid 内的按钮覆盖 panel 默认 100%-width 行为 */
.more-tools-panel .more-tools-strike button,
.more-tools-panel .more-tools-stepper-row button,
.more-tools-panel .more-tools-button-grid button {
  width: auto;
  justify-content: center;
  text-align: center;
  background: var(--bg-2) !important;
  border: 1px solid color-mix(in srgb, var(--ink-3) 25%, transparent) !important;
  padding: 5px 9px !important;
  font-size: 12px !important;
}
.more-tools-panel .more-tools-strike button:hover,
.more-tools-panel .more-tools-stepper-row button:hover,
.more-tools-panel .more-tools-button-grid button:hover {
  background: var(--bg-3) !important;
}
.more-tools-inline {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 0 2px;
}
.more-tools-inline .speed-control,
.more-tools-panel .speed-control {
  width: 100%;
}
.more-tools-panel .slider-speed { flex: 1; }
.more-tools-panel .handpan-select {
  width: 100%;
}

/* 用户菜单（toolbar 右侧，登出入口） */
.user-menu .user-menu-summary {
  font-size: 12px;
  color: var(--ink-1);
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  gap: 5px;
}
.user-menu-label:empty { display: none; }
#toolbar.practice-topbar .user-menu .user-menu-summary { padding: 4px 8px; }
.user-menu .toolbar-menu-panel { left: auto; right: 0; min-width: 180px; }
/* practice-topbar 顶栏最右，强制 panel 右对齐避免溢出屏幕右边 */
#toolbar.practice-topbar .user-menu .toolbar-menu-panel { left: auto; right: 0; }
.user-menu-info {
  padding: 6px 10px 4px;
  font-size: 12px;
  color: var(--ink-2);
  border-bottom: 1px solid var(--bg-3);
  margin-bottom: 4px;
}
.user-menu-info strong {
  color: var(--ink-0);
  font-weight: 600;
}
.user-menu-logout {
  width: 100%;
  justify-content: flex-start;
  background: transparent !important;
  color: var(--ink-0) !important;
  border: 0 !important;
  text-align: left;
  padding: 6px 10px !important;
  border-radius: var(--r-sm) !important;
  font-size: 12px !important;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.user-menu-logout:hover {
  background: var(--bg-2) !important;
  color: #d04848 !important;
}

/* 文件菜单（toolbar 右侧，新建 / 导入 / 导出）——形态、字号、padding 与 #userMenu 对齐，
   panel 默认 left:0 从按钮左下垂落（按钮在 user-menu 左侧，向右展开不会出屏）。 */
.file-menu .file-menu-summary {
  font-size: 12px;
  color: var(--ink-1);
  gap: 5px;
}
#toolbar.practice-topbar .file-menu .file-menu-summary { padding: 4px 8px; }
.file-menu-label { color: var(--ink-1); }
/* hover 给一点反馈，跟其它顶栏按钮一致 */
.file-menu .file-menu-summary:hover { color: var(--ink-0); }

/* user-menu 普通菜单项（专注 / 主题 等）：与 logout 同尺寸但保持中性色，hover 不变红 */
.user-menu-item {
  width: 100%;
  justify-content: flex-start;
  background: transparent !important;
  color: var(--ink-1) !important;
  border: 0 !important;
  text-align: left;
  padding: 6px 10px !important;
  border-radius: var(--r-sm) !important;
  font-size: 13px !important;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.user-menu-item:hover {
  background: var(--bg-2) !important;
  color: var(--ink-0) !important;
}

.speed-control {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  font-size: 11px;
  color: var(--ink-1);
}

.hand-mute {
  display: inline-flex;
  align-items: center;
  gap: 0;
  flex-shrink: 0;
}
#toolbar .hand-mute-btn {
  padding: 4px 10px;
  min-width: 30px;
  font-weight: 700;
  font-size: 12px;
  line-height: 1;
  color: #fff;
  border: 1px solid transparent;
  border-radius: 0;
  transition:
    background var(--t-fast) var(--ease),
    color var(--t-fast) var(--ease),
    opacity var(--t-fast) var(--ease),
    transform var(--t-fast) var(--ease);
}
#toolbar .hand-mute-btn.hand-mute-r {
  border-top-left-radius: var(--r-sm);
  border-bottom-left-radius: var(--r-sm);
  background: var(--rh);
}
#toolbar .hand-mute-btn.hand-mute-l {
  border-top-right-radius: var(--r-sm);
  border-bottom-right-radius: var(--r-sm);
  background: var(--lh);
}
#toolbar .hand-mute-btn:hover {
  filter: brightness(1.06);
  color: #fff;
}
#toolbar .hand-mute-btn.muted {
  background: var(--bg-2);
  color: var(--ink-2);
  text-decoration: line-through;
  opacity: 0.55;
}
#toolbar .hand-mute-btn.muted:hover {
  filter: none;
  background: var(--bg-3);
  color: var(--ink-1);
}

.toolbar-menu-panel button,
.toolbar-menu-panel .btn-label {
  width: 100%;
  justify-content: flex-start;
  background: transparent !important;
  color: var(--ink-0) !important;
  border: 0 !important;
  text-align: left;
  padding: 6px 10px !important;
  border-radius: var(--r-sm) !important;
}
.toolbar-menu-panel .btn-label { display: flex; }
.toolbar-menu-panel button:hover,
.toolbar-menu-panel .btn-label:hover {
  background: var(--bg-2) !important;
}

.settings-menu-panel {
  min-width: 240px;
  gap: 6px;
}
.settings-menu-panel .settings-row,
.settings-menu-panel .settings-check {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 10px;
  color: var(--ink-1) !important;
  font-size: 12px !important;
}
.settings-menu-panel .settings-row .slider-speed,
.settings-menu-panel .settings-row .slider-zoom {
  width: 110px;
  accent-color: var(--accent);
}
.settings-menu-panel .settings-row #speedLabel,
.settings-menu-panel .settings-row #scoreZoomLabel {
  min-width: 38px;
  color: var(--ink-2);
  font-size: 11px;
}
.settings-menu-panel .settings-check { justify-content: flex-start; }
.settings-menu-panel .settings-check input[type="checkbox"] { accent-color: var(--accent); }

/* note tools (打击下拉) */
.note-tool {
  min-width: 26px;
  height: 26px;
  padding: 0 6px !important;
  font-size: 11px !important;
  font-weight: 700 !important;
}
.note-tool-wide { min-width: 32px; }
.strike-group { position: relative; }
.strike-tools { position: relative; }
.strike-summary {
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 26px;
  user-select: none;
}
.strike-summary::-webkit-details-marker { display: none; }
.strike-summary::after {
  content: "▾";
  font-size: 9px;
  color: var(--ink-2);
  transition: transform var(--t-fast) var(--ease);
}
.strike-tools[open] .strike-summary::after { transform: rotate(180deg); }
.strike-menu {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 200;
  display: grid;
  grid-template-columns: repeat(4, minmax(28px, auto));
  gap: 6px;
  padding: 8px;
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-md);
  box-shadow: var(--e3);
}
.strike-menu .note-tool {
  background: var(--bg-2) !important;
  color: var(--ink-0) !important;
  border: 1px solid var(--bg-3) !important;
}
.strike-menu .note-tool:hover {
  background: var(--bg-3) !important;
}

.settings-group { position: relative; }
/* ── 练习面板（渐进加速练习） ── */
.practice-menu-panel {
  min-width: 340px !important;
  padding: 10px !important;
  gap: 8px !important;
  display: flex !important;
  flex-direction: column !important;
}
.practice-toggle {
  display: flex !important;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  cursor: pointer;
  background: transparent !important;
  color: var(--ink-0) !important;
  font-size: 12px !important;
  transition: background var(--t-fast) var(--ease);
}
.practice-toggle:hover { background: var(--bg-2) !important; }
.practice-toggle input[type="checkbox"] {
  margin-top: 3px;
  flex-shrink: 0;
  accent-color: var(--accent);
  width: 14px; height: 14px;
}
.practice-toggle-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}
.practice-toggle-text strong {
  font-size: 13px;
  color: var(--ink-0);
  font-weight: 600;
  letter-spacing: 0.01em;
}
.practice-toggle-text small {
  font-size: 11px;
  color: var(--ink-2);
  font-weight: 400;
  line-height: 1.45;
}
.practice-rows {
  border-top: 1px solid var(--bg-3);
  padding: 6px 4px 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  opacity: 0.4;
  pointer-events: none;
  transition: opacity var(--t-fast) var(--ease);
}
.practice-tools.practice-on .practice-rows {
  opacity: 1;
  pointer-events: auto;
}
.practice-row {
  display: grid !important;
  grid-template-columns: 86px 1fr 50px !important;
  align-items: center;
  gap: 10px;
  padding: 4px 6px !important;
  font-size: 12px !important;
  color: var(--ink-1) !important;
}
.practice-row-label {
  font-weight: 500;
  color: var(--ink-1);
}
.practice-row-value {
  font-weight: 600;
  color: var(--accent);
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-size: 12px;
}
.practice-row .slider-practice {
  width: 100%;
  accent-color: var(--accent);
}
.practice-preview {
  margin: 4px 4px 0;
  padding: 8px 10px;
  background: var(--accent-soft);
  border-radius: var(--r-sm);
  font-size: 11px;
  color: var(--ink-0);
  line-height: 1.5;
  font-variant-numeric: tabular-nums;
  word-break: break-all;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.practice-tools:not(.practice-on) .practice-preview {
  background: var(--bg-2);
  color: var(--ink-2);
}
.practice-hint {
  font-size: 11px;
  color: var(--ink-2);
  line-height: 1.45;
  padding: 0 6px 2px;
}

.btn-subdiv {
  min-width: 26px !important; height: 26px !important;
  border-radius: var(--r-sm) !important; padding: 0 7px !important;
  font-size: 14px !important; font-weight: 600 !important;
  display: flex !important; align-items: center; justify-content: center;
}
.btn-with-kbd {
  gap: 4px;
  padding: 0 6px 0 8px !important;
}
.btn-with-kbd kbd {
  font-size: 9px;
  font-family: -apple-system, BlinkMacSystemFont, monospace;
  padding: 1px 4px;
  border: 1px solid var(--bg-3);
  border-radius: 3px;
  background: var(--bg-1);
  color: var(--ink-2);
  font-weight: 600;
  line-height: 1;
}
.subdiv-display {
  font-size: 13px; font-weight: 700;
  color: var(--ink-0);
  min-width: 18px; text-align: center;
}

.input-sm {
  width: 38px; padding: 3px;
  border: 1px solid var(--bg-3);
  border-radius: var(--r-sm);
  background: var(--bg-2);
  color: var(--ink-0);
  text-align: center;
  font-size: 11px; font-weight: 500;
}
.input-sm:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.slider-speed,
.slider-zoom { width: 88px; accent-color: var(--accent); vertical-align: middle; }
#speedLabel, #scoreZoomLabel {
  font-size: 11px; color: var(--ink-2);
  min-width: 30px; display: inline-block;
}
#toolbar label {
  font-size: 11px; color: var(--ink-1);
  display: flex; align-items: center; gap: 4px; cursor: pointer;
}
#toolbar input[type="checkbox"] { accent-color: var(--accent); }

/* 图标 + 文字 label 组合（文件 / 编辑 menu summary 内的"文件"/"编辑"用） */
.btn-icon-label { font-size: 12px; line-height: 1; font-weight: 500; }
.btn-emoji { font-size: 14px; line-height: 1; }
.btn-icon { display: inline-flex; align-items: center; justify-content: center; color: var(--ink-2); }
.toolbar-menu-summary:hover .btn-icon { color: var(--ink-0); }
@media (max-width: 820px) {
  .btn-icon-label { display: none; }
}

/* ── 音频 ── */
#audio-bar { display: none; }

/* ── 主体布局（2026-05-23 改 4 栏：rail / 侧栏 / 主区 / inspector）──
   原 3 栏布局，侧栏（曲库 / 曲谱结构）是 position:absolute 浮在主区上面的
   抽屉；现改为真正的 grid 第 2 列，宽度由 --drawer-w 控制——关闭时 0、打开
   时 240（或用户拖到的宽度），grid-template-columns 上加 transition 实现
   开合滑动。第 2 列再套 min(...,86vw) 防止小屏被侧栏吃光。 */
#main-wrapper {
  flex: 1;
  min-height: 0;
  display: grid;
  --drawer-w: 0px;
  grid-template-columns: auto min(var(--drawer-w), 86vw) 1fr 320px;
  transition: grid-template-columns 180ms var(--ease, ease);
  overflow: hidden;
  background: var(--bg-0);
  position: relative;
}

/* 主区元素（workspace / AI panel）共享 grid 第 3 列（旧 2 列），叠在同一格，
   靠 hidden 切换显隐。#library-panel 现在占第 2 列、in-flow，不再 absolute。 */
#workspace {
  grid-column: 3;
  grid-row: 1;
  min-width: 0;
  overflow: hidden;
}

/* deprecated 2026-05-07 — 旧 .mode-tab 视觉规则已迁到 .practice-sidebar / .practice-sidebar-item（见 practice.css）。
   这里只保留 #mode-sidebar 的 width / flex-shrink，因为 #main-wrapper 是 flex 布局，
   .practice-sidebar 自身没声明宽度。其它（background / padding / border-right / display / gap）
   全部交给 practice.css 接管。focus-mode / tap-mode 的 #mode-sidebar { display: none } 仍生效（特异性更高）。*/
#mode-sidebar {
  width: var(--sidebar-w, 84px);
  flex-shrink: 0;
}

#workspace {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  /* 2026-05-23 v2：position relative 让浮窗手碟 #handpan-visual 能 absolute 锚到这里
     （右下角 240×240 card）。不影响内部 flex 行为。 */
  position: relative;
}
#workspace[hidden] { display: none; }
#score-scroll {
  flex: 2;
  overflow-y: auto;
  min-height: 0;
  background: var(--bg-0);
  padding: var(--gap-md) var(--gap-lg) var(--gap-lg);
}

/* 2026-05-23 mini-map 移回 #bottom-area，.score-sticky-top 包装层一并删除。
   #score-header / .score-header-deco / .title-row 早已下线（曲名/作者/同步 chip 走顶栏
   mountTopbar 注入），所以 score-scroll 顶部不再需要 sticky 容器。 */

/* dirty-dot 已删（与 sync-icon 重复，统一用 .sync-icon）。
   .sync-icon[data-state="syncing"] 引用 dirty-pulse 动画，故保留 keyframes。 */
@keyframes dirty-pulse {
  0%, 100% { opacity: 0.4; }
  50%      { opacity: 1; }
}

/* 同步状态图标（在顶栏曲名右侧；clean=✓ 已同步 / syncing=⟳ 上传中 / error=⚠ 上传失败 / dirty=• 待保存） */
.sync-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 22px;
  padding: 0 10px;
  font-size: 12px;
  line-height: 1;
  white-space: nowrap;
  color: var(--ink-2);
  background: var(--bg-2);
  border: 1px solid var(--bg-3);
  border-radius: 999px;
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease);
  opacity: 0.95;
  cursor: help;
  user-select: none;
  flex-shrink: 0;
  letter-spacing: 0.02em;
}
.sync-icon[data-state="clean"]   { color: var(--accent); opacity: 0.55; }
.sync-icon[data-state="syncing"] { color: var(--lh, var(--accent)); opacity: 0.95; animation: dirty-pulse 1.2s ease-in-out infinite; }
.sync-icon[data-state="error"]   { color: #d04848; opacity: 1; }
.sync-icon[data-state="dirty"]   { color: var(--ink-2); opacity: 0.7; }

/* ── 谱面 ── */
#score-area {
  --measures-per-line: 3;
  --score-zoom: 1;
  --score-row-height: calc(36px * var(--score-zoom));
  /* 单小节目标宽度：一行总宽 = 目标宽 × measures-per-line，受容器宽度上限限制；
     这样减/增 measures-per-line 主要改的是「行总宽」，单小节宽度变化幅度小。 */
  --measure-width-target: 540px;
  padding: 24px 36px 40px;
  width: 100%;
  max-width: 1780px;
  margin: 0 auto;
}

.section-header {
  font-size: 14px; font-weight: 600;
  color: var(--ink-0);
  margin: 32px 0 14px 2px;
  display: flex; align-items: center; gap: 8px;
  letter-spacing: 0.02em;
}
.section-header .part-tag {
  background: transparent;
  padding: 1px 9px;
  border-radius: var(--r-sm);
  border: 1px solid var(--ink-0);
  font-size: 13px; font-weight: 600;
  color: var(--ink-0);
}
.section-header .subsection-tag {
  font-size: 13px; font-weight: 500;
  color: var(--ink-1);
}
.section-header .bpm-tag {
  font-size: 12px; color: var(--ink-2); font-weight: 500;
  margin-left: 4px;
}
.section-header .editable {
  cursor: text;
  border-radius: var(--r-sm);
  padding: 1px 4px;
  transition: background var(--t-fast) var(--ease);
}
.section-header .editable:hover { background: var(--bg-2); }
.section-header .editable.placeholder { color: var(--ink-3); font-weight: 400; }
.section-header .section-edit {
  font: inherit;
  color: inherit;
  background: var(--bg-1);
  border: 1px solid var(--accent);
  border-radius: var(--r-sm);
  padding: 0 4px;
  outline: none;
}
.tempo-badge {
  font-size: 12px;
  color: var(--ink-2);
  font-weight: 500;
  margin: 18px 0 10px 2px;
}
.tempo-badge.editable {
  cursor: pointer;
  display: inline-block;
  padding: 2px 6px;
  border-radius: var(--r-sm);
  transition: background var(--t-fast) var(--ease);
}
.tempo-badge.editable:hover { background: var(--bg-2); }
.section-header .bpm-tag.editable { cursor: pointer; }

/* 变速 badge：浮在变速所在 cell 上方（任意 step，不限拍起点） */
.beat-tempo-tag {
  position: absolute;
  top: -14px;
  left: 0;
  font-size: 11px;
  color: var(--ink-2);
  font-weight: 500;
  background: var(--bg-1);
  padding: 0 4px;
  border-radius: var(--r-sm);
  cursor: pointer;
  white-space: nowrap;
  z-index: 2;
  pointer-events: auto;
  transition: background var(--t-fast) var(--ease);
}
.beat-tempo-tag:hover { background: var(--bg-2); color: var(--ink-1); }

/* cell 右键菜单 */
.context-menu {
  position: fixed;
  z-index: 1000;
  background: var(--bg-1);
  border: 1px solid var(--bg-3, #d8d8d8);
  border-radius: var(--r-sm);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.18);
  padding: 4px 0;
  min-width: 200px;
  font-size: 13px;
}
.context-menu button {
  display: block;
  width: 100%;
  padding: 7px 14px;
  background: transparent;
  border: 0;
  text-align: left;
  cursor: pointer;
  color: var(--ink-1);
  font: inherit;
}
.context-menu button:hover { background: var(--bg-2); }

/* 变速覆盖范围标识：浮在 R2 顶行 cell 上方的 dashed 横线 */
.tempo-range-mark {
  position: absolute;
  top: -3px;
  left: 0;
  right: 0;
  height: 0;
  border-top: 2px dashed var(--accent);
  pointer-events: none;
  z-index: 1;
}

/* ── 谱行（一行多小节）── */
.score-line {
  display: flex;
  gap: 0;
  margin-bottom: calc(40px * var(--score-zoom));
  align-items: flex-start;
  /* 行宽随 measures-per-line 缩放，但不超过容器宽度；剩余空间靠 margin: 0 auto 居中 */
  width: min(100%, calc(var(--measure-width-target) * var(--measures-per-line)));
  margin-left: auto;
  margin-right: auto;
}

/* ── 小节 ── */
.measure {
  width: calc(100% / var(--measures-per-line));
  min-width: 0;
  flex-shrink: 0;
  flex-grow: 0;
  position: relative;
  border-left: 1.5px solid var(--barline);
  padding: 0 7px 5px 0;
  transition: background var(--t-med) var(--ease);
}
.measure:last-child { border-right: 1.5px solid var(--barline); }
.measure.active-measure {
  background: linear-gradient(90deg, var(--accent-soft), transparent 70%);
}
/* 当前 measure：极弱 tint，让 step 顶部游标成为主要视觉 */
.measure.playing-measure {
  background: color-mix(in srgb, var(--accent) 4%, transparent);
}
/* 流动虚线圈：呼应"练习模式"设计图里的柔光圆环 */
.measure.playing-measure::before {
  content: "";
  position: absolute;
  inset: -3px;
  border: 1px dashed var(--accent-ring);
  border-radius: 8px;
  pointer-events: none;
  opacity: 0.55;
  animation: deco-dash-flow 18s linear infinite;
}
.measure.playing-measure .measure-number {
  color: var(--accent);
  font-weight: 700;
}
.measure-number {
  position: absolute; top: -18px; left: -2px;
  font-size: calc(11px * var(--score-zoom));
  color: var(--ink-2);
  font-weight: 500;
  transition: color var(--t-fast) var(--ease);
}
.linebreak-mark { color: var(--accent); font-weight: 600; margin-left: 2px; }

/* ── 网格 ── */
.measure-grid { display: grid; position: relative; color: var(--paper-ink); }

/* ── 单元格 ── */
.cell {
  height: var(--score-row-height);
  display: flex; align-items: center; justify-content: center;
  font-size: calc(15.5px * var(--score-zoom)); font-weight: 700;
  cursor: pointer; user-select: none;
  position: relative;
  line-height: 1;
  isolation: isolate;
  transition:
    background var(--t-fast) var(--ease),
    color var(--t-fast) var(--ease),
    transform var(--t-fast) var(--ease);
}
.cell:hover { background: var(--bg-2); }
.cell.active-step::after,
.cell.active-row::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  transition: background var(--t-fast) var(--ease);
}
.cell.active-step::after { background: var(--accent-soft); opacity: 0.5; }
.cell.active-row::after { background: var(--bg-2); opacity: 0.6; }
.cell.active-step.active-row::after {
  background: var(--accent-soft);
  opacity: 0.85;
}

.cell.selected {
  background: transparent;
  border-radius: 0;
  box-shadow: inset 0 0 0 1.5px var(--accent);
  z-index: 5;
}
.cell.selected.active-step {
  box-shadow: inset 0 0 0 2px var(--accent);
}

/* 循环播放期间：选区描边干扰播放视觉，改成弱 accent 底色提示范围，
   把"边框"留给 .cell.playing 的 playhead 横条独占 — 谱子内容清晰可读。 */
body.is-looping .cell.selected {
  background: var(--accent-soft);
  box-shadow: none;
}
body.is-looping .cell.selected.active-step {
  background: var(--accent-soft);
  box-shadow: inset 0 -1px 0 0 var(--accent);  /* 仅当前 step 留底部一道 1px 提示 */
}
body.is-looping .cell.drop-target {
  box-shadow: inset 0 0 0 1px var(--accent);  /* drop-target 也变细 */
}
.cell.drop-target {
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 1.5px var(--accent);
}

.note-label {
  position: relative;
  z-index: 3;
  display: inline;
  min-width: 0;
  height: auto;
  padding: 0;
  border-radius: 0;
  line-height: 1;
}

/* note 写入 pop 动画 — 由 editor.js 在 setCellNote 时给 cell 加 .note-pop class */
@keyframes notePop {
  0%   { transform: scale(0.6); opacity: 0; }
  60%  { transform: scale(1.12); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
.cell.note-pop .note-label {
  display: inline-block;
  animation: notePop 0.22s var(--ease);
}

/* 右手/左手颜色 */
.cell.rh { color: var(--rh); }
.cell.lh { color: var(--lh); }
.cell.rh.filled-cell .note-label,
.cell.lh.filled-cell .note-label { background: transparent; }
.cell.note-percussive .note-label,
.cell.note-fist .note-label,
.cell.note-effect .note-label,
.cell.note-ding-palm-mute .note-label,
.cell.note-ding-tonefield .note-label {
  background: transparent;
  color: inherit;
  font-size: inherit;
  letter-spacing: 0;
}
.cell.note-ghost .note-label {
  min-width: 0;
  background: transparent;
  color: var(--ink-2);
  font-size: 18px;
  line-height: 1;
  font-weight: 700;
  letter-spacing: 0;
}

.cell.empty-cell { color: transparent; }
.cell.outer-row { height: var(--score-row-height); font-size: calc(15.5px * var(--score-zoom)); }

/* 左右手分隔 */
.cell.hand-divider { border-bottom: 1px solid var(--bg-4); }
.cell.row-line-bottom { border-bottom: none; }

/* 竖线层级 */
.cell.beat-start::before {
  content: ""; position: absolute; left: -1px; top: 0; bottom: 0;
  width: 1px; background: var(--beatline); z-index: 2;
}
.cell.beat-start[data-ri="0"]::before { top: 18%; }
.cell.beat-start[data-ri="3"]::before { bottom: 18%; }

.cell.sub-div::before {
  content: ""; position: absolute; left: -1px; top: 0; bottom: 0;
  width: 1px; background: var(--subline); z-index: 1;
}
.cell.sub-div[data-ri="0"]::before { top: 54%; }
.cell.sub-div[data-ri="3"]::before { bottom: 54%; }

.cell.split-div::before {
  content: ""; position: absolute; left: -1px; top: 0; bottom: 0;
  width: 1px;
  background: repeating-linear-gradient(to bottom, var(--bg-3) 0 3px, transparent 3px 6px);
  z-index: 1;
}
.cell.split-div[data-ri="0"]::before,
.cell.split-div[data-ri="3"]::before { display: none; }
.cell.split-div[data-ri="1"]::before { top: 32%; }
.cell.split-div[data-ri="2"]::before { bottom: 32%; }

/* ── Phase B：音乐表情（nuance / effect） ─────────────────── */
/* nuance：cell 数字 opacity 五档（0=极淡，4=完全不透明 + 微加粗） */
.cell[data-nuance] .note-label { transition: opacity var(--t-fast) var(--ease); }
.cell[data-nuance="0"] .note-label { opacity: 0.30; }
.cell[data-nuance="1"] .note-label { opacity: 0.55; }
.cell[data-nuance="2"] .note-label { opacity: 1.0; }  /* 默认就是不写 dataset，这条仅兜底 */
.cell[data-nuance="3"] .note-label { opacity: 1.0; font-weight: 800; }
.cell[data-nuance="4"] .note-label {
  opacity: 1.0;
  font-weight: 900;
  text-shadow: 0 0 6px var(--accent-ring);
}

/* effect=muted：cell 加 _ 下划线（accent 同色，区别于超链接） */
.cell[data-effect="muted"] .note-label {
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 2px;
  text-decoration-color: currentColor;
}

/* effect=harmonic：cell 加 F 上标。跟 noteName 自带的 *F (DF/4F/1F..9F) 拆出来的
   .note-harmonic-sup 视觉一致，让所有泛音表达都用同一个右上 "F" 标记。 */
.cell[data-effect="harmonic"] .note-label {
  position: relative;
}
.cell[data-effect="harmonic"] .note-label::after {
  content: "F";
  position: absolute;
  top: -0.45em;
  right: -0.55em;
  font-size: 0.7em;
  font-weight: 600;
  color: currentColor;
  pointer-events: none;
}
.note-harmonic-sup {
  font-size: 0.7em;
  font-weight: 600;
  vertical-align: super;
  line-height: 0;
  margin-left: 0.05em;
}

/* 表情右键菜单（contextmenu 弹出） */
.expression-menu {
  position: fixed;
  z-index: 200;
  min-width: 200px;
  padding: 8px;
  border-radius: var(--r-md);
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  box-shadow: var(--e3);
  font-size: 13px;
  color: var(--ink-0);
}
.expression-menu[hidden] { display: none; }
.expression-menu-group + .expression-menu-group {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--bg-3);
}
.expression-menu-title {
  font-size: 11px;
  color: var(--ink-2);
  margin-bottom: 4px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.expression-menu-row {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
}
.expression-menu button {
  flex: 1 1 auto;
  min-width: 36px;
  padding: 6px 8px;
  border-radius: var(--r-sm);
  border: 1px solid var(--bg-3);
  background: var(--bg-2);
  color: var(--ink-0);
  font: inherit;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.expression-menu button:hover {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}
.expression-menu .expression-menu-clear {
  width: 100%;
  margin-top: 2px;
}

/* 播放高亮 — DAW playhead 风：列顶端一根 2px accent 横条，不再整格染色 */
.cell.playing { background: transparent; }
.cell.playing[data-ri="0"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: -2px;
  height: 2px;
  background: var(--accent);
  border-radius: 1px;
  box-shadow: 0 0 6px var(--accent-ring);
  animation: accent-glow-pulse 1.4s ease-in-out infinite;
  z-index: 6;
  pointer-events: none;
}
.cell.playing .note-label { box-shadow: none; }

/* ── 底部 mini-map 条（2026-05-23 v2：手碟浮窗化后，bottom-area 只装 mini-map）──
   视觉关系完全对齐 practice.html 的 .practice-footer-top：bg-1 + border-top + 内部
   flex column with gap，包 status-strip + practice-mini-map。
   原 #resize-handle 拖来调本块高度——手碟挪走后无意义已删；原 height: 360px 改 auto，
   #handpan-visual 不再是子节点（绝对定位浮在右下角，规则见下）。 */
#bottom-area {
  flex-shrink: 0;
  height: auto;
  padding: 0;
  background: var(--bg-1);
  border-top: 1px solid color-mix(in srgb, var(--ink-3) 25%, transparent);
  position: relative;
  transition: background var(--t-med) var(--ease), border-color var(--t-med) var(--ease);
}

/* 手碟浮窗：绝对定位在 #workspace 内，横向居中、固定挂在 mini-map 上方。
   - 默认尺寸 240px 方形；通过 .hp-resize-handle 拖角调整，存到 localStorage
     `hpn.handpanSize`，下次开页 initHandpanUI 还原。
   - 居中靠 left:50% + translateX(-50%)；transform 还兼任 hover 微浮（translateY），
     所以一定要把 translateX 留在 transform 里，hover 时只动 Y。
   - bottom 留出 mini-map 一条（约 80px）+ 16px 呼吸距 = 96px；mini-map 高度变了
     就 tune 这个数。
   - #workspace 已声明 position: relative，absolute 锚到它就行。 */
#workspace > #handpan-visual {
  position: absolute;
  left: 50%;
  bottom: 96px;
  z-index: 50;
  width: 240px;
  height: 240px;
  min-width: 0;
  background: var(--bg-1);
  border: 1px solid color-mix(in srgb, var(--ink-3) 22%, transparent);
  border-radius: 24px;
  box-shadow: 0 10px 30px color-mix(in srgb, #000 18%, transparent),
              0 2px 6px color-mix(in srgb, #000 8%, transparent);
  padding: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translateX(-50%) translateY(0);
  transition: box-shadow var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
#workspace > #handpan-visual:hover {
  box-shadow: 0 14px 36px color-mix(in srgb, #000 22%, transparent),
              0 3px 8px color-mix(in srgb, #000 10%, transparent);
  transform: translateX(-50%) translateY(-1px);
}

/* resize handle —— 右上角小圆按钮（与左上角 .hp-close-btn 对称），
   bound by initHandpanUI in index.html. drag 区间 160-460px，等比缩放（width=height）。 */
.hp-resize-handle {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 5;
  width: 26px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-1);
  color: var(--ink-2);
  border: 1px solid var(--bg-3);
  border-radius: 50%;
  font-size: 14px;
  line-height: 1;
  cursor: nesw-resize;  /* 右上角→左下角，drag ↗ 放大 / ↙ 缩小 */
  touch-action: none;
  user-select: none;
  opacity: 0.7;
  transition: opacity var(--t-fast) var(--ease), background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.hp-resize-handle:hover { opacity: 1; background: var(--bg-2); color: var(--ink-0); }
.hp-resize-handle.is-dragging { opacity: 1; background: var(--accent); color: #fff; border-color: var(--accent); }

/* mini-map（2026-05-23 起结构与练习页底栏完全对齐，位置也回到 #bottom-area 上沿）
   外层 .score-mini-map 包：① .practice-status-strip 状态条 + ② .practice-mini-map 主体。
   主体的所有视觉规则（baseline / ticks / loop fill / thumbs / marker / marker-label）
   走 practice.css 共享样式。#bottom-area 本身就是 bg-1，所以 wrapper 不再画底色 / 边线。
   交互见 editor.js initMiniMapInteraction：thumbs 拖动写 sel/selEnd 多小节选区，
   marker 拖动 = scrub（松手 jumpToMeasure），点空白 track = jumpToMeasure。 */
/* .score-mini-map 现在就是 #bottom-area 的唯一直接子节点，完全照搬
   practice.css 的 .practice-footer-top：padding 12/32/10 + flex column + gap 6。 */
.score-mini-map {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 32px 10px;
  margin: 0;
}
.score-mini-map-status {
  margin: 0;
}
/* practice.css 的 strip bold 规则用 #curMeasureNum / #loopRangeLabel ID 选择器，
   编辑器复用了 .practice-status-strip 但 ID 不一样，这里给编辑器 ID 补一遍。 */
.score-mini-map-status .practice-status-strip-item > #bottomMiniMapCur,
.score-mini-map-status .practice-status-strip-item > #bottomMiniMapLoopText {
  color: var(--ink-0);
  font-weight: 600;
}

/* ── 手碟 SVG（v2 立体感，默认风格 A） ── */
#handpan-visual {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px;
  pointer-events: auto;
}
/* 卡片化覆盖：默认 .card 18/20 padding 会挤压定高 SVG，缩到 8px */
#handpan-visual.card {
  padding: 8px;
  width: auto;
  max-width: 100%;
  aspect-ratio: 1;
}
.hp-svg {
  width: auto;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  aspect-ratio: 1;
  filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.08));
}

/* gradient stop colors（attribute 不解析 var()，必须 class） — light/dark 都用 var(--bg-X) */
.hp-stop-disc-light { stop-color: var(--bg-1); }
.hp-stop-disc-mid   { stop-color: var(--bg-2); }
.hp-stop-disc-deep  { stop-color: var(--bg-3); }
.hp-stop-ding-light { stop-color: var(--bg-0); }
.hp-stop-ding-mid   { stop-color: var(--bg-1); }
.hp-stop-ding-deep  { stop-color: var(--bg-2); }
.hp-stop-field-light { stop-color: var(--bg-0); }
.hp-stop-field-mid   { stop-color: var(--bg-1); }
.hp-stop-field-deep  { stop-color: var(--bg-2); }

.hp-disc {
  stroke: var(--bg-3);
  stroke-width: 0.6;
  stroke-opacity: 0.7;
  transition: stroke var(--t-med) var(--ease);
}
.hp-disc-shine {
  stroke: rgba(255, 255, 255, 0.32);
  stroke-width: 0.8;
  stroke-dasharray: 90 200;
  pointer-events: none;
}
[data-theme="dark"] .hp-disc-shine { stroke: rgba(255, 255, 255, 0.06); }

.hp-note {
  cursor: pointer;
  transition: transform 120ms cubic-bezier(0.34, 1.56, 0.64, 1);
  transform-origin: center;
  transform-box: fill-box;
}
@media (hover: hover) {
  .hp-note:hover { transform: scale(1.06); }
  .hp-note:hover .hp-circle,
  .hp-note:hover .hp-rect { stroke: var(--accent-ring, var(--accent)); }
}

.hp-circle {
  stroke: var(--bg-3);
  stroke-width: 0.8;
  transition: stroke var(--t-fast) var(--ease);
}
.hp-circle-ding {
  stroke: var(--bg-3);
  stroke-width: 1.2;
}
.hp-ding-shadow {
  fill: rgba(0, 0, 0, 0.14);
  filter: blur(2px);
  pointer-events: none;
}
[data-theme="dark"] .hp-ding-shadow { fill: rgba(0, 0, 0, 0.4); }

.hp-rect {
  fill: var(--bg-2);
  stroke: var(--bg-3);
  stroke-width: 0.8;
  transition: fill var(--t-fast) var(--ease), stroke var(--t-fast) var(--ease);
}
.hp-hit { pointer-events: fill; cursor: pointer; }

.hp-label, .hp-sublabel {
  text-anchor: middle;
  dominant-baseline: middle;
  pointer-events: none;
  transition: fill var(--t-fast) var(--ease);
  font-family: inherit;
}
.hp-label {
  fill: var(--ink-0);
  font-weight: 600;
  font-size: 14px;
}
.hp-sublabel {
  fill: var(--ink-2);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.02em;
}
.hp-note-ding .hp-label { font-size: 19px; font-weight: 700; letter-spacing: -0.02em; }
.hp-note-ding .hp-sublabel { font-size: 10px; fill: var(--ink-1); }
.hp-note-field .hp-label { font-size: 15px; }
.hp-note-field .hp-sublabel { font-size: 9.5px; }
.hp-note-top .hp-label { font-size: 13px; }
.hp-note-top .hp-sublabel { font-size: 8.5px; }
.hp-note-perc .hp-label { font-size: 11px; font-weight: 700; fill: var(--ink-1); }

.hp-note.active .hp-circle,
.hp-note.active .hp-rect {
  fill: var(--accent);
  stroke: var(--accent);
  stroke-width: 1.5;
}
.hp-note.active .hp-label,
.hp-note.active .hp-sublabel { fill: #fff; }
.hp-note-ding.active .hp-circle-ding { fill: var(--accent); }

/* 播放高亮：乐谱模式播放时手碟图同步点亮当前 step 的音区，R/L 用
   --rh/--lh 区分（与练习页 mini 手碟一致）。切 step / 停止后 note 转入
   .hp-playing-fade，让 fill/stroke/filter 在 ~460ms 内衰减回基础态。
   选择器统一带 #handpan-visual 前缀拿 id 权重，盖过 .hp-style-* 主题
   对 .hp-circle / .hp-rect 的 fill 覆写。 */
#handpan-visual .hp-note.hp-playing-rh .hp-circle,
#handpan-visual .hp-note.hp-playing-rh .hp-rect,
#handpan-visual .hp-note.hp-playing-rh .hp-circle-ding {
  fill: color-mix(in srgb, var(--rh) 34%, var(--bg-1));
  stroke: var(--rh);
  stroke-width: 1.8;
  filter: drop-shadow(0 0 5px color-mix(in srgb, var(--rh) 60%, transparent));
}
#handpan-visual .hp-note.hp-playing-lh .hp-circle,
#handpan-visual .hp-note.hp-playing-lh .hp-rect,
#handpan-visual .hp-note.hp-playing-lh .hp-circle-ding {
  fill: color-mix(in srgb, var(--lh) 34%, var(--bg-1));
  stroke: var(--lh);
  stroke-width: 1.8;
  filter: drop-shadow(0 0 5px color-mix(in srgb, var(--lh) 60%, transparent));
}
#handpan-visual .hp-note.hp-playing-rh .hp-label,
#handpan-visual .hp-note.hp-playing-rh .hp-sublabel,
#handpan-visual .hp-note.hp-playing-lh .hp-label,
#handpan-visual .hp-note.hp-playing-lh .hp-sublabel { fill: var(--ink-0); }
#handpan-visual .hp-note.hp-playing-fade .hp-circle,
#handpan-visual .hp-note.hp-playing-fade .hp-rect,
#handpan-visual .hp-note.hp-playing-fade .hp-circle-ding {
  transition: fill 460ms ease-out, stroke 460ms ease-out, filter 460ms ease-out;
}

#handpan-visual .hp-status-pill {
  position: absolute;
  top: 8px;
  right: 8px;
  bottom: auto;
  left: auto;
}

/* ─────────────────────────────────────────────────────── */
/* 风格 D：暖色奶油（默认） */
/* ─────────────────────────────────────────────────────── */
#handpan-visual.hp-style-d .hp-disc {
  fill: var(--accent-soft);
  stroke: var(--accent-ring, var(--accent));
  stroke-opacity: 0.5;
}
#handpan-visual.hp-style-d .hp-disc-shine { stroke: rgba(255,255,255,0.45); }
#handpan-visual.hp-style-d .hp-circle {
  fill: var(--bg-0);
  stroke: var(--accent-ring, var(--accent));
  stroke-width: 1;
}
#handpan-visual.hp-style-d .hp-circle-ding {
  fill: var(--accent);
  stroke: var(--accent);
}
#handpan-visual.hp-style-d .hp-note-ding .hp-label,
#handpan-visual.hp-style-d .hp-note-ding .hp-sublabel { fill: #fff; }
#handpan-visual.hp-style-d .hp-rect {
  fill: var(--accent-soft);
  stroke: var(--accent-ring, var(--accent));
}
#handpan-visual.hp-style-d .hp-ding-shadow { fill: rgba(180, 100, 30, 0.18); }

/* ─────────────────────────────────────────────────────── */
/* 风格 E：钛钢深色 + 金 Ding（真实金属手碟感） */
/* ─────────────────────────────────────────────────────── */
#handpan-visual.hp-style-e .hp-svg {
  filter: drop-shadow(0 4px 14px rgba(0, 0, 0, 0.32))
          drop-shadow(0 1px 2px rgba(0, 0, 0, 0.18));
}
#handpan-visual.hp-style-e .hp-disc {
  fill: #1f2228;
  stroke: #0c0e12;
  stroke-width: 1;
  stroke-opacity: 1;
}
#handpan-visual.hp-style-e .hp-disc-shine {
  stroke: rgba(255, 255, 255, 0.22);
  stroke-width: 1.2;
}
#handpan-visual.hp-style-e .hp-stop-disc-light,
#handpan-visual.hp-style-e .hp-stop-disc-mid,
#handpan-visual.hp-style-e .hp-stop-disc-deep,
#handpan-visual.hp-style-e .hp-stop-field-light,
#handpan-visual.hp-style-e .hp-stop-field-mid,
#handpan-visual.hp-style-e .hp-stop-field-deep,
#handpan-visual.hp-style-e .hp-stop-ding-light,
#handpan-visual.hp-style-e .hp-stop-ding-mid,
#handpan-visual.hp-style-e .hp-stop-ding-deep { display: none; }
#handpan-visual.hp-style-e .hp-circle {
  fill: #d4d8de;
  stroke: #6c7280;
  stroke-width: 0.8;
  filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.45));
}
#handpan-visual.hp-style-e .hp-circle-ding {
  fill: #e8b96c;
  stroke: #7a5a1a;
  stroke-width: 1.5;
}
#handpan-visual.hp-style-e .hp-ding-shadow { fill: rgba(0, 0, 0, 0.55); }
#handpan-visual.hp-style-e .hp-rect {
  fill: #4a4f58;
  stroke: #6c7280;
  stroke-width: 1;
}
#handpan-visual.hp-style-e .hp-label { fill: #1c1f24; font-weight: 700; }
#handpan-visual.hp-style-e .hp-sublabel { fill: #4a5058; }
#handpan-visual.hp-style-e .hp-note-ding .hp-label,
#handpan-visual.hp-style-e .hp-note-ding .hp-sublabel { fill: #2c1f08; }
#handpan-visual.hp-style-e .hp-note-perc .hp-label { fill: #e2e6ea; }

/* ─────────────────────────────────────────────────────── */
/* 风格 F：蓝橙双色（Notepan 应用感，明亮干净） */
/* ─────────────────────────────────────────────────────── */
#handpan-visual.hp-style-f .hp-svg { filter: drop-shadow(0 2px 8px rgba(60, 90, 140, 0.14)); }
#handpan-visual.hp-style-f .hp-disc {
  fill: #f6f1e8;
  stroke: #c1cad6;
  stroke-width: 1;
  stroke-opacity: 1;
}
#handpan-visual.hp-style-f .hp-stop-disc-light,
#handpan-visual.hp-style-f .hp-stop-disc-mid,
#handpan-visual.hp-style-f .hp-stop-disc-deep,
#handpan-visual.hp-style-f .hp-stop-field-light,
#handpan-visual.hp-style-f .hp-stop-field-mid,
#handpan-visual.hp-style-f .hp-stop-field-deep,
#handpan-visual.hp-style-f .hp-stop-ding-light,
#handpan-visual.hp-style-f .hp-stop-ding-mid,
#handpan-visual.hp-style-f .hp-stop-ding-deep { display: none; }
#handpan-visual.hp-style-f .hp-disc-shine,
#handpan-visual.hp-style-f .hp-ding-shadow { display: none; }
#handpan-visual.hp-style-f .hp-circle {
  fill: #e7f1fa;
  stroke: #3d88c4;
  stroke-width: 1.5;
}
#handpan-visual.hp-style-f .hp-circle-ding {
  fill: #ff8847;
  stroke: #cc5520;
  stroke-width: 1.8;
}
#handpan-visual.hp-style-f .hp-rect {
  fill: #fff0e6;
  stroke: #ff8847;
  stroke-width: 1.4;
}
#handpan-visual.hp-style-f .hp-label { fill: #1a3a5f; font-weight: 700; }
#handpan-visual.hp-style-f .hp-sublabel { fill: #5295cc; font-weight: 500; }
#handpan-visual.hp-style-f .hp-note-ding .hp-label,
#handpan-visual.hp-style-f .hp-note-ding .hp-sublabel { fill: #fff; }
#handpan-visual.hp-style-f .hp-note-perc .hp-label { fill: #cc5520; font-weight: 700; }

/* ─────────────────────────────────────────────────────── */
/* 风格 G：音高彩虹（黑底 + 紫蓝青绿黄橙红渐变，按音高排序） */
/* ─────────────────────────────────────────────────────── */
#handpan-visual.hp-style-g .hp-svg { filter: drop-shadow(0 3px 10px rgba(0, 0, 0, 0.28)); }
#handpan-visual.hp-style-g .hp-disc {
  fill: #23262b;
  stroke: #0e0f12;
  stroke-width: 1;
  stroke-opacity: 1;
}
#handpan-visual.hp-style-g .hp-disc-shine {
  stroke: rgba(255, 255, 255, 0.14);
  stroke-width: 1;
}
#handpan-visual.hp-style-g .hp-stop-disc-light,
#handpan-visual.hp-style-g .hp-stop-disc-mid,
#handpan-visual.hp-style-g .hp-stop-disc-deep,
#handpan-visual.hp-style-g .hp-stop-field-light,
#handpan-visual.hp-style-g .hp-stop-field-mid,
#handpan-visual.hp-style-g .hp-stop-field-deep,
#handpan-visual.hp-style-g .hp-stop-ding-light,
#handpan-visual.hp-style-g .hp-stop-ding-mid,
#handpan-visual.hp-style-g .hp-stop-ding-deep { display: none; }
#handpan-visual.hp-style-g .hp-circle {
  stroke: rgba(255, 255, 255, 0.32);
  stroke-width: 1;
}
#handpan-visual.hp-style-g .hp-note-field[data-note="1"] .hp-circle { fill: #a466ff; }
#handpan-visual.hp-style-g .hp-note-field[data-note="2"] .hp-circle { fill: #5b8eff; }
#handpan-visual.hp-style-g .hp-note-field[data-note="3"] .hp-circle { fill: #3ec0d8; }
#handpan-visual.hp-style-g .hp-note-field[data-note="4"] .hp-circle { fill: #3ed8a4; }
#handpan-visual.hp-style-g .hp-note-field[data-note="5"] .hp-circle { fill: #bbd840; }
#handpan-visual.hp-style-g .hp-note-field[data-note="6"] .hp-circle { fill: #f5c842; }
#handpan-visual.hp-style-g .hp-note-field[data-note="7"] .hp-circle { fill: #ffa040; }
#handpan-visual.hp-style-g .hp-note-field[data-note="8"] .hp-circle { fill: #ff7050; }
#handpan-visual.hp-style-g .hp-note-field[data-note="9"] .hp-circle { fill: #ff4060; }
#handpan-visual.hp-style-g .hp-circle-ding {
  fill: #ffffff;
  stroke: #23262b;
  stroke-width: 1.8;
}
#handpan-visual.hp-style-g .hp-ding-shadow { fill: rgba(0, 0, 0, 0.5); }
#handpan-visual.hp-style-g .hp-rect {
  fill: #4a4d54;
  stroke: rgba(255, 255, 255, 0.25);
  stroke-width: 1;
}
#handpan-visual.hp-style-g .hp-label { fill: #ffffff; font-weight: 700; }
#handpan-visual.hp-style-g .hp-sublabel { fill: rgba(255, 255, 255, 0.78); }
#handpan-visual.hp-style-g .hp-note-ding .hp-label,
#handpan-visual.hp-style-g .hp-note-ding .hp-sublabel { fill: #23262b; }
#handpan-visual.hp-style-g .hp-note-perc .hp-label { fill: #ffffff; }

/* ─────────────────────────────────────────────────────── */
/* 关闭手碟视图 + 重新打开按钮 */
/* ─────────────────────────────────────────────────────── */
.hp-close-btn {
  position: absolute;
  top: 6px;
  left: 6px;
  z-index: 5;
  width: 26px;
  height: 26px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-1);
  color: var(--ink-2);
  border: 1px solid var(--bg-3);
  border-radius: 50%;
  font-size: 18px;
  line-height: 1;
  font-weight: 400;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity var(--t-fast) var(--ease), background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.hp-close-btn:hover { opacity: 1; background: var(--bg-2); color: var(--ink-0); }

/* 用户点 × 收起手碟：浮窗整块隐藏；bottom-area 已是 auto 高，无需额外处理 */
body.no-handpan #workspace > #handpan-visual { display: none !important; }

.hp-reopen-btn {
  display: none;
  position: fixed;
  right: 14px;
  bottom: 14px;
  z-index: 8000;
  align-items: center;
  gap: 6px;
  padding: 8px 14px 8px 12px;
  background: var(--bg-1);
  color: var(--ink-0);
  border: 1px solid var(--bg-3);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.14);
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.hp-reopen-btn svg { width: 16px; height: 16px; }
.hp-reopen-btn:hover { background: var(--bg-2); border-color: var(--accent); transform: translateY(-1px); }
body.no-handpan .hp-reopen-btn { display: inline-flex; }
body.no-handpan #hp-style-gallery { bottom: 70px; }

/* ─────────────────────────────────────────────────────── */
/* 风格预览 gallery — 浮在右下角，让用户对比挑选 */
/* ─────────────────────────────────────────────────────── */
.hp-style-gallery {
  position: fixed;
  right: 14px;
  bottom: 14px;
  z-index: 9000;
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: 14px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18), 0 2px 6px rgba(0, 0, 0, 0.1);
  padding: 10px 12px 12px;
  max-width: min(540px, 94vw);
  font-size: 11px;
}
.hp-style-gallery-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 6px;
}
.hp-style-gallery-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-0);
  letter-spacing: 0;
}
.hp-style-gallery-close {
  background: none;
  border: none;
  color: var(--ink-2);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: 4px;
}
.hp-style-gallery-close:hover { background: var(--bg-2); color: var(--ink-0); }
.hp-style-gallery-row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.hp-style-card {
  margin: 0;
  flex: 1 1 110px;
  min-width: 110px;
  border: 1.5px solid transparent;
  border-radius: 10px;
  padding: 6px 8px 8px;
  cursor: pointer;
  background: var(--bg-0);
  transition: border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
  text-align: center;
}
.hp-style-card:hover { border-color: var(--bg-3); transform: translateY(-1px); }
.hp-style-card.is-active { border-color: var(--accent); background: var(--accent-soft); }
.hp-style-card svg {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  max-width: 110px;
  margin: 0 auto;
}
.hp-style-card figcaption {
  font-size: 11px;
  color: var(--ink-1);
  margin-top: 4px;
  font-weight: 500;
}
@media (max-width: 540px) {
  .hp-style-gallery {
    right: 8px;
    bottom: 8px;
    left: 8px;
    max-width: none;
    padding: 8px 10px 10px;
  }
  .hp-style-card { flex: 1 1 calc(50% - 5px); min-width: 0; }
  .hp-style-card svg { max-width: 80px; }
}

/* ── Metronome / Drone 陪练 ── */
.metro-control {
  display: inline-flex !important;
  align-items: center;
  gap: 6px !important;
  cursor: help;
}
.metro-label {
  font-size: 11px;
  color: var(--ink-2);
  letter-spacing: 0.02em;
}
/* 节拍器音量 popover：summary 是 🔊 图标，展开后显示滑块 + 数字 + 快捷按钮 */
.metro-vol-pop { margin-left: 2px; }
.metro-vol-summary {
  /* 复用 toolbar 风格但不显示下拉箭头（图标自身已说明） */
  padding: 4px 8px !important;
  font-size: 14px !important;
}
.metro-vol-summary::after { display: none; }
.metro-vol-icon-glyph {
  display: inline-flex;
  align-items: center;
  line-height: 1;
}
.metro-vol-popover {
  /* 比普通菜单稍紧凑，挂在 🔊 下方 */
  min-width: 200px;
  padding: 10px;
  gap: 8px;
}
.metro-vol-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.slider-metro-vol {
  flex: 1;
  width: 140px;
  cursor: pointer;
}
.metro-vol-label {
  font-size: 11px;
  color: var(--ink-2);
  min-width: 36px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.metro-vol-actions {
  display: flex;
  gap: 6px;
}
.metro-vol-action {
  flex: 1;
  font-size: 11px !important;
  padding: 4px 6px !important;
  background: var(--bg-0) !important;
  border: 1px solid color-mix(in srgb, var(--ink-3) 25%, transparent) !important;
  color: var(--ink-1) !important;
  border-radius: var(--r-sm) !important;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.metro-vol-action:hover {
  background: var(--accent) !important;
  border-color: var(--accent) !important;
  color: #fff !important;
}
.metro-vol-action.is-muted {
  /* 静音状态下让按钮明显一点 */
  background: var(--accent) !important;
  color: #fff !important;
  border-color: var(--accent) !important;
}
/* drone-control / drone-label / drone-select / drone-hint 整段已删——drone 陪练功能下线。 */

/* 节拍器 select（早期参考 drone-select 风格） */
.metro-select {
  background: var(--bg-2);
  color: var(--ink-0);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-sm);
  padding: 3px 22px 3px 8px;
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-2) 50%), linear-gradient(135deg, var(--ink-2) 50%, transparent 50%);
  background-position: calc(100% - 11px) 50%, calc(100% - 7px) 50%;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
  min-width: 86px;
}
.metro-select:hover { background-color: var(--accent); border-color: var(--accent); color: #fff; }
.metro-select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.metro-select option { color: var(--ink-0); background: var(--bg-1); }

footer { display: none; }

/* ── 移动端 ── */
@media (max-width: 820px) {
  #toolbar { padding: 6px 10px; }
  .toolbar-row { flex-wrap: wrap; overflow: visible; gap: 6px; }
  .toolbar-primary { justify-content: flex-start; }
  .toolbar-secondary { margin-top: 5px; padding-top: 5px; }
  .toolbar-cluster, .playback-group, .toolbar-group {
    flex-wrap: wrap; max-width: 100%;
  }
  .toolbar-label { display: none; }
  #toolbar button, #toolbar .btn-label, #toolbar .strike-summary, #toolbar .toolbar-menu-summary {
    padding: 5px 9px;
    min-height: 30px;
    white-space: nowrap;
  }
  .toolbar-menu-panel { min-width: 160px; }
  .strike-menu, .toolbar-menu-panel { z-index: 320; }
  .btn-play { width: 34px; height: 34px; font-size: 14px !important; }
  .playback-group { margin-left: 0; }
  .speed-control { min-height: 28px; padding: 0 2px; }
  .speed-control .slider-speed { width: 84px; }
  .play-status { display: none; }
  #mode-sidebar { display: none; }
  #inspector { display: none; }
  #main-wrapper { grid-template-columns: auto 1fr; }
  #toolbar.practice-topbar { padding: 0 14px; }
  #score-area { --measures-per-line: 1; padding: 18px 14px 28px; }
  .measure { width: 100%; }
  .cell { font-size: 14px; }
  .note-label { min-width: 0; height: auto; }
  /* 移动端：手碟浮窗整个隐藏（屏幕太小，浮窗会挡谱面）；mini-map 一条 auto 高 */
  #workspace > #handpan-visual { display: none; }
  .settings-menu-panel { min-width: min(92vw, 250px); }
  .settings-menu-panel .settings-row .slider-zoom { width: 96px; }
  /* 触控反馈：按下时缩放，比 hover 更明显（手机上 hover 会粘连） */
  .hp-note.pressed {
    transform: scale(0.94);
    transform-origin: center;
    transform-box: fill-box;
    transition: transform 80ms ease-out;
  }
  .hp-note.pressed .hp-circle { fill: var(--accent); }
  .hp-note.pressed .hp-label,
  .hp-note.pressed .hp-sublabel { fill: #fff; }
}

@media (max-width: 480px) {
  #bottom-area { height: 64px; }
  #score-area { padding-left: 10px; padding-right: 10px; }
}

/* 横屏小屏（手机翻横）：底部手碟区更扁 */
@media (orientation: landscape) and (max-height: 500px) {
  #bottom-area {
    height: 56px;
    padding: 4px 8px;
  }
}

/* ── ⌘K 命令面板 ── */
.cmdk-overlay {
  position: fixed; inset: 0;
  background: rgba(28, 22, 16, 0.36);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  z-index: 9999;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding-top: 14vh;
  animation: cmdk-fade-in 0.16s var(--ease);
}
[data-theme="dark"] .cmdk-overlay {
  background: rgba(8, 6, 4, 0.5);
}
.cmdk-overlay[hidden] { display: none; }

@keyframes cmdk-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.cmdk-card {
  width: min(560px, 92vw);
  max-height: 60vh;
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-lg);
  box-shadow: var(--e3);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: cmdk-rise 0.2s var(--ease);
}

@keyframes cmdk-rise {
  from { transform: translateY(8px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

.cmdk-input {
  width: 100%;
  padding: 16px 20px;
  border: 0;
  border-bottom: 1px solid var(--bg-3);
  background: transparent;
  font-size: 15px;
  font-family: inherit;
  color: var(--ink-0);
  outline: none;
  letter-spacing: -0.005em;
}
.cmdk-input::placeholder { color: var(--ink-2); }

.cmdk-list {
  list-style: none;
  margin: 0;
  padding: 6px 8px 8px;
  overflow-y: auto;
  flex: 1;
}

.cmdk-group-label {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
  padding: 12px 10px 4px;
}
.cmdk-list .cmdk-group-label:first-child { padding-top: 6px; }

.cmdk-item {
  display: flex;
  align-items: center;
  padding: 9px 12px;
  border-radius: var(--r-sm);
  cursor: pointer;
  font-size: 13px;
  color: var(--ink-0);
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.cmdk-item .cmdk-title { flex: 1; }
.cmdk-item .cmdk-keys {
  margin-left: 12px;
  font-size: 11px;
  color: var(--ink-2);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
}
.cmdk-item.active {
  background: var(--accent-soft);
  color: var(--accent);
}
.cmdk-item.active .cmdk-keys { color: var(--accent); opacity: 0.85; }

.cmdk-empty {
  padding: 32px 12px;
  text-align: center;
  color: var(--ink-2);
  font-size: 12px;
}

/* 工具栏的 ⌘K 入口按钮 */
.cmdk-trigger {
  display: inline-flex !important;
  align-items: center;
  gap: 6px;
  padding: 4px 10px 4px 8px !important;
  font-size: 11px !important;
  color: var(--ink-2) !important;
}
.cmdk-trigger svg { width: 13px; height: 13px; }
.cmdk-trigger kbd {
  display: inline-flex;
  align-items: center;
  height: 16px;
  padding: 0 5px;
  margin-left: 2px;
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: 3px;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 10px;
  color: var(--ink-2);
}
.cmdk-trigger:hover kbd {
  border-color: var(--bg-4);
  color: var(--ink-1);
}

@media (max-width: 820px) {
  .cmdk-trigger .cmdk-trigger-label { display: none; }
  .cmdk-overlay { padding-top: 8vh; }
  .cmdk-card { max-height: 78vh; }
}

/* ── 移动端触屏增强（路线 C，Phase 3）─────────────────────
   全部规则只在 ≤820px 激活；桌面端这些元素由 [hidden] / display:none 完全隐藏。
   FAB / drawer / hamburger 的 DOM 结构在 index.html，开关逻辑在 mobile.js。
   ─────────────────────────────────────────────── */
.mobile-fab,
.mobile-drawer,
.mobile-drawer-backdrop,
.mobile-hamburger {
  display: none;
}
/* hidden 属性（由 mobile.js 切换）保险叠加 */
.mobile-fab[hidden],
.mobile-hamburger[hidden] { display: none !important; }

@media (max-width: 820px) {
  /* hamburger：只在 mobile 出现，外观与 .theme-toggle 同尺寸圆角 */
  .mobile-hamburger {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    width: 30px !important;
    height: 30px !important;
    padding: 0 !important;
    border-radius: 50% !important;
    background: transparent !important;
    border: 1px solid var(--bg-3) !important;
    color: var(--ink-1) !important;
  }
  .mobile-hamburger[hidden] { display: none !important; }
  .mobile-hamburger:hover {
    background: var(--bg-2) !important;
    color: var(--accent) !important;
  }
  .mobile-hamburger svg { width: 16px; height: 16px; display: block; }

  /* FAB：右下角浮动播放球，56×56 圆，accent 实色 */
  .mobile-fab {
    display: flex;
    position: fixed;
    right: max(16px, env(safe-area-inset-right));
    bottom: max(20px, env(safe-area-inset-bottom));
    width: 56px;
    height: 56px;
    padding: 0;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    box-shadow: var(--e3);
    cursor: pointer;
    z-index: 9000;
    transition:
      transform var(--t-fast) var(--ease),
      box-shadow var(--t-fast) var(--ease),
      background var(--t-fast) var(--ease);
  }
  .mobile-fab[hidden] { display: none; }
  .mobile-fab:active { transform: scale(0.94); }
  .mobile-fab:hover { filter: brightness(1.06); }
  .mobile-fab.is-playing {
    background: var(--accent);
    /* 播放中给一圈微微的脉冲提示（ring，不抢戏） */
    box-shadow: var(--e3), 0 0 0 4px var(--accent-ring);
  }
  .mobile-fab svg { width: 24px; height: 24px; display: block; }
  .mobile-fab svg[hidden] { display: none; }

  /* Drawer：从右滑入 280px，bg-1 底，e3 阴影 */
  .mobile-drawer-backdrop {
    display: block;
    position: fixed; inset: 0;
    background: rgba(28, 22, 16, 0.36);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    z-index: 9050;
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--t-med) var(--ease), visibility var(--t-med) var(--ease);
  }
  [data-theme="dark"] .mobile-drawer-backdrop {
    background: rgba(8, 6, 4, 0.5);
  }
  .mobile-drawer-backdrop.is-visible {
    opacity: 1;
    visibility: visible;
  }
  .mobile-drawer {
    display: flex;
    position: fixed;
    top: 0; right: 0; bottom: 0;
    width: min(280px, 86vw);
    flex-direction: column;
    background: var(--bg-1);
    border-left: 1px solid var(--bg-3);
    box-shadow: var(--e3);
    z-index: 9100;
    transform: translateX(100%);
    transition: transform var(--t-med) var(--ease);
    padding-top: env(safe-area-inset-top);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .mobile-drawer.is-open { transform: translateX(0); }

  .mobile-drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px;
    border-bottom: 1px solid var(--bg-3);
  }
  .mobile-drawer-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--ink-0);
    letter-spacing: 0.02em;
  }
  .mobile-drawer-close {
    width: 32px; height: 32px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--bg-3);
    border-radius: 50%;
    background: transparent;
    color: var(--ink-1);
    cursor: pointer;
    transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
  }
  .mobile-drawer-close:hover {
    background: var(--bg-2);
    color: var(--accent);
  }
  .mobile-drawer-close svg { width: 14px; height: 14px; display: block; }

  .mobile-drawer-body {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: 12px 12px 20px;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }
  .mobile-drawer-item {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    width: 100%;
    min-height: 56px;
    padding: 10px 14px;
    border: 1px solid var(--bg-3);
    border-radius: var(--r-md);
    background: var(--bg-2);
    color: var(--ink-0);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
  }
  .mobile-drawer-item:hover {
    background: var(--bg-3);
    border-color: var(--bg-4);
  }
  .mobile-drawer-item:active { transform: scale(0.98); }
  .mobile-drawer-item-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--ink-0);
  }
  .mobile-drawer-item-desc {
    font-size: 11px;
    color: var(--ink-2);
  }
  .mobile-drawer-hint {
    margin-top: 8px;
    padding: 10px 12px;
    border-radius: var(--r-md);
    background: transparent;
    border: 1px dashed var(--bg-3);
    color: var(--ink-2);
    font-size: 11px;
    line-height: 1.5;
  }
  .mobile-drawer-section {
    margin: 14px 4px 6px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-2);
  }
  .mobile-drawer-section:first-child { margin-top: 6px; }
  .mobile-drawer-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
    margin-bottom: 6px;
  }
  .mobile-drawer-row-3 { grid-template-columns: repeat(3, 1fr); }
  .mobile-drawer-row-4 { grid-template-columns: repeat(4, 1fr); }
  .mobile-drawer-key {
    min-height: 44px;
    padding: 0 10px;
    background: var(--bg-2);
    color: var(--ink-0);
    border: 1px solid var(--bg-3);
    border-radius: var(--r-sm);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
  }
  .mobile-drawer-key:hover { background: var(--bg-3); }
  .mobile-drawer-key:active {
    background: var(--accent-soft);
    border-color: var(--accent-ring);
    color: var(--accent);
    transform: scale(0.97);
  }

  /* Drawer 打开时锁住 body 滚动 */
  body.mobile-drawer-open { overflow: hidden; }

  /* 手碟 SVG：tonefield r=24 命中区已达标；perc 区 r=16 视觉不够，
     靠 index.html 里 <circle class="hp-hit"> r=22 透明圈把判定区扩到 44 svg 单位 */
  #handpan-visual .hp-note-perc .hp-circle { stroke-width: 1.4; }
  #handpan-visual .hp-hit { pointer-events: fill; cursor: pointer; }
}

/* ── ? 快捷键速查卡（与 ⌘K 同视觉系） ── */
.help-overlay {
  position: fixed; inset: 0;
  background: rgba(28, 22, 16, 0.36);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  z-index: 9999;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding-top: 12vh;
  animation: cmdk-fade-in 0.16s var(--ease);
}
[data-theme="dark"] .help-overlay {
  background: rgba(8, 6, 4, 0.5);
}
.help-overlay[hidden] { display: none; }

.help-card {
  width: min(620px, 92vw);
  max-height: 76vh;
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-lg);
  box-shadow: var(--e3);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: cmdk-rise 0.2s var(--ease);
}

.help-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 14px 20px 12px;
  border-bottom: 1px solid var(--bg-3);
}
.help-title {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink-0);
}
.help-hint {
  font-size: 11px;
  color: var(--ink-2);
}

.help-body {
  padding: 6px 14px 14px;
  overflow-y: auto;
  flex: 1;
}

.help-section {
  padding-top: 10px;
}
.help-section-title {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-2);
  padding: 8px 6px 4px;
}

.help-grid {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.help-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 7px 8px;
  border-radius: var(--r-sm);
  font-size: 13px;
  color: var(--ink-0);
  transition: background var(--t-fast) var(--ease);
}
.help-row:hover {
  background: var(--accent-soft);
}

.help-desc {
  flex: 1;
  min-width: 0;
}

.help-keys {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px;
  flex-shrink: 0;
}

.help-key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  background: var(--bg-0);
  border: 1px solid var(--bg-3);
  border-radius: 4px;
  box-shadow: 0 1px 0 var(--bg-3);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 11px;
  color: var(--ink-1);
  font-style: normal;
}

.help-sep {
  font-size: 11px;
  color: var(--ink-2);
  padding: 0 2px;
}

@media (max-width: 820px) {
  .help-overlay { padding-top: 6vh; }
  .help-card { max-height: 88vh; }
  .help-row { font-size: 12px; }
}

/* ── 历史版本面板（与 ⌘K / 快捷键卡同视觉系） ── */
.history-overlay {
  position: fixed; inset: 0;
  background: rgba(28, 22, 16, 0.36);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  z-index: 9999;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  padding-top: 12vh;
  animation: cmdk-fade-in 0.16s var(--ease);
}
[data-theme="dark"] .history-overlay {
  background: rgba(8, 6, 4, 0.5);
}
.history-overlay[hidden] { display: none; }

.history-card {
  width: min(620px, 92vw);
  max-height: 76vh;
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-lg);
  box-shadow: var(--e3);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  animation: cmdk-rise 0.2s var(--ease);
}

.history-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px 12px 20px;
  border-bottom: 1px solid var(--bg-3);
  gap: 12px;
}
.history-title-wrap {
  display: flex;
  align-items: baseline;
  gap: 10px;
  min-width: 0;
  flex: 1;
}
.history-title {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--ink-0);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.history-sub {
  font-size: 11px;
  color: var(--ink-2);
  flex-shrink: 0;
}
.history-close {
  background: transparent;
  border: 1px solid var(--bg-3);
  border-radius: var(--r-sm);
  width: 26px;
  height: 26px;
  font-size: 16px;
  line-height: 1;
  color: var(--ink-1);
  cursor: pointer;
  flex-shrink: 0;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.history-close:hover {
  background: var(--accent-soft);
  color: var(--ink-0);
}

.history-body {
  padding: 8px 14px 14px;
  overflow-y: auto;
  flex: 1;
}

.history-empty {
  padding: 24px 12px;
  font-size: 13px;
  color: var(--ink-2);
  text-align: center;
}

.history-row {
  display: grid;
  grid-template-columns: 130px 1fr auto;
  align-items: center;
  gap: 14px;
  padding: 10px 8px;
  border-radius: var(--r-sm);
  font-size: 13px;
  color: var(--ink-0);
  border-bottom: 1px solid var(--bg-3);
}
.history-row:last-child { border-bottom: none; }
.history-row:hover { background: var(--accent-soft); }

.history-thumb {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 4px 5px;
  background: var(--bg-1);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-sm);
  width: 120px;
  height: 40px;
  box-sizing: border-box;
}
.history-thumb-row {
  display: grid;
  grid-template-columns: repeat(64, 1fr);
  height: 7px;
  gap: 0;
}
.history-thumb-cell {
  background: transparent;
  position: relative;
}
.history-thumb-cell.measure-start::before {
  content: "";
  position: absolute;
  left: 0; top: -1px; bottom: -1px;
  width: 1px;
  background: var(--bg-3);
}
.history-thumb-cell.filled.r-row { background: var(--rh); border-radius: 1px; }
.history-thumb-cell.filled.l-row { background: var(--lh); border-radius: 1px; }

.history-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  flex-wrap: wrap;
}
.history-when {
  font-weight: 600;
  color: var(--ink-0);
}
.history-label {
  display: inline-block;
  font-size: 11px;
  padding: 1px 7px;
  border-radius: 9px;
  background: var(--accent-soft);
  color: var(--ink-1);
}
.history-sep-dot {
  color: var(--ink-2);
  padding: 0 2px;
}
.history-summary {
  color: var(--ink-2);
  font-size: 12px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

.history-actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.history-action {
  background: var(--bg-0);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-sm);
  padding: 4px 10px;
  font-size: 12px;
  color: var(--ink-1);
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.history-action:hover {
  background: var(--bg-2);
  color: var(--ink-0);
}
.history-action-primary {
  background: var(--accent-soft);
  color: var(--ink-0);
  border-color: transparent;
}
.history-action-primary:hover {
  background: var(--accent);
  color: var(--bg-0);
}
.history-action-danger {
  font-size: 14px;
  line-height: 1;
  width: 26px;
  padding: 0;
  height: 24px;
  color: var(--ink-2);
}
.history-action-danger:hover {
  color: #b94a3b;
  border-color: #b94a3b;
  background: var(--bg-0);
}

@media (max-width: 820px) {
  .history-overlay { padding-top: 6vh; }
  .history-card { max-height: 88vh; }
  .history-row { font-size: 12px; }
}

/* ── 侧栏（曲库 / 曲谱结构）面板（2026-05-23 从 absolute overlay 抽屉改为
   in-flow grid 第 2 列）── 宽度由 #main-wrapper 上的 --drawer-w 控制（关闭 0、
   打开 240 或用户保存的值），自身 width:100% 充满 grid cell。
   panel 本身不再 overflow；交给内部 .drawer-view 各自管滚（结构 / 谱库 列表
   独立滚条，不污染 panel）。 */
.library-panel {
  grid-column: 2;
  grid-row: 1;
  position: relative;   /* .library-resize-handle / .library-drawer-close absolute 锚到这里 */
  width: 100%;
  min-width: 0;
  border-right: 1px solid var(--bg-3);
  background: var(--bg-1);
  color: var(--ink-0);
  overflow: hidden;
  padding: 14px 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.library-panel[hidden] {
  /* 保持 display:flex 让 grid cell 上的过渡动画走完；用 visibility 隐藏
     内容并挡指针。column 宽度由 --drawer-w 收到 0 自然让 cell 缩没。 */
  display: flex;
  visibility: hidden;
  pointer-events: none;
}

/* 抽屉顶部双 tab：曲库 / 曲谱结构 同级互斥（Notepan Score/Staffing 模式）。
   margin-right:36 给 .library-drawer-close ✕（absolute right:8 + width:28）
   让出右上角，避免 tab 文字压到关闭按钮下。outer 比 inner .library-tabs
   更大更粗，视觉上 outer 是「视图切换」、inner 是「视图内分类」。 */
.drawer-tabs {
  display: flex;
  gap: 4px;
  margin: 0 36px 10px 0;
  border-bottom: 1px solid var(--bg-3);
}
.drawer-tab {
  flex: 1;
  padding: 10px 12px;
  background: transparent;
  color: var(--ink-2);
  border: 0;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.drawer-tab:hover { color: var(--ink-0); }
.drawer-tab.active {
  color: var(--ink-0);
  font-weight: 600;
  border-bottom-color: var(--accent);
}
/* drawer-view 撑满 .library-panel 在 .drawer-tabs 之下的剩余高度，并把垂直
   滚动下放给 list 自己，让结构 chip 网格 / 谱列表都能滚到面板底。 */
.drawer-view {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}
.drawer-view[hidden] { display: none; }

/* 结构 view 只有一个孩子（list），让它独占剩余高度 + 自滚 */
.drawer-view[data-drawer-view="structure"] #inspectorStructureList {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}
/* 谱库 view 上面有多个固定行（tabs / header / actions），让 list 独占剩余高度 + 自滚 */
.drawer-view[data-drawer-view="library"] #library-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

/* 抽屉右边缘拖拽条：用户拖动改宽度，结果持久化到 localStorage hpn.drawerWidth。
   width:6 / right:-3 让 handle 横跨 panel 右边线两侧各 3px——hover 给 6px 命中
   反馈不挡内容点击；z:31 高于 .library-panel z:30。 */
.library-resize-handle {
  position: absolute;
  top: 0;
  right: -3px;
  bottom: 0;
  width: 6px;
  cursor: ew-resize;
  z-index: 31;
  background: transparent;
  transition: background 120ms ease;
}
.library-resize-handle:hover,
.library-resize-handle.is-dragging {
  background: color-mix(in srgb, var(--accent) 35%, transparent);
}

/* 抽屉顶部右上角的 ✕ 关闭按钮 */
.library-drawer-close {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: var(--ink-2);
  border: 0;
  border-radius: var(--r-sm);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
  z-index: 1;
}
.library-drawer-close:hover {
  background: var(--bg-3);
  color: var(--ink-0);
}

.library-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 0 2px 4px;
}
.library-title {
  font-size: 16px;
  font-weight: 600;
  color: var(--ink-0);
}
.library-new-btn {
  padding: 4px 10px;
  background: var(--accent);
  color: #fff;
  border: 0;
  border-radius: var(--r-sm);
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--e1);
  transition: filter var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.library-new-btn:hover { filter: brightness(1.06); }
.library-new-btn:active { transform: scale(0.96); }

.library-actions {
  display: flex;
  flex-wrap: wrap;   /* drawer 收窄到 160 后 5 按钮一行放不下，按需换行 */
  gap: 4px;
  padding: 0 2px 6px;
  border-bottom: 1px solid var(--bg-3);
}
.library-action {
  flex: 1 0 42px;     /* min-width 42 保证文字不挤；多余空间均分 */
  padding: 5px 6px;
  background: var(--bg-2);
  color: var(--ink-1);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-sm);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.library-action:hover { background: var(--bg-3); color: var(--ink-0); }
.library-action-danger:hover { background: #d04848; color: #fff; border-color: #d04848; }

/* 批量选择 */
.library-bulk-actions { align-items: center; }
.library-bulk-count {
  flex: 1;
  font-size: 11px;
  color: var(--accent);
  font-weight: 600;
  letter-spacing: 0.02em;
}
.library-checkbox {
  flex-shrink: 0;
  width: 16px; height: 16px;
  margin-right: 8px;
  border: 1.5px solid var(--bg-4);
  border-radius: 4px;
  background: var(--bg-0);
  position: relative;
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.library-checkbox.checked {
  background: var(--accent);
  border-color: var(--accent);
}
.library-checkbox.checked::after {
  content: "";
  position: absolute;
  left: 4px; top: 1px;
  width: 5px; height: 9px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.library-item.is-selected {
  background: var(--accent-soft);
  border-color: var(--accent-ring);
}
.library-item.is-selected .library-item-title { color: var(--accent); }
.library-item-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
/* 选择模式时 item 横排：checkbox + body 同行 */
.library-item:has(.library-checkbox) {
  flex-direction: row;
  align-items: center;
}

.library-list {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin-top: 2px;
}
.library-empty {
  padding: 28px 12px;
  text-align: center;
  color: var(--ink-2);
  font-size: 11.5px;
  line-height: 1.5;
}
.library-item {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 9px 11px;
  border: 1px solid transparent;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--ink-0);
  font: inherit;
  cursor: pointer;
  text-align: left;
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.library-item:hover { background: var(--bg-2); }
.library-item.active {
  background: var(--accent-soft);
  border-color: var(--accent-ring);
}
.library-item-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-0);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.library-item.active .library-item-title { color: var(--accent); }
.library-item-meta {
  font-size: 10.5px;
  color: var(--ink-2);
  letter-spacing: 0.01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.library-item.active .library-item-meta {
  color: var(--accent);
  opacity: 0.8;
}

@media (max-width: 820px) {
  /* 小屏抽屉占满宽 */
  .library-panel { width: 100%; max-width: 100%; }
}

/* ── Login modal ─────────────────────────────────────── */
.login-modal {
  position: fixed; inset: 0; z-index: 9999;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
.login-modal[hidden] { display: none; }
.login-card {
  width: 340px; max-width: 92vw;
  background: var(--bg-1); color: var(--ink-0);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-lg);
  padding: 22px 24px 18px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
.login-title {
  font-size: 16px; font-weight: 600;
  color: var(--ink-0);
  margin-bottom: 4px;
}
.login-desc {
  font-size: 12px; color: var(--ink-1);
  margin: 0 0 14px;
  line-height: 1.5;
}
.login-row {
  display: flex; flex-direction: column; gap: 4px;
  font-size: 12px; color: var(--ink-1);
  margin-bottom: 10px;
}
.login-row input {
  padding: 8px 10px;
  background: var(--bg-0); color: var(--ink-0);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-sm);
  font-size: 14px;
  transition: border-color var(--t-fast) var(--ease);
}
.login-row input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ring);
}
.login-remember {
  display: flex; align-items: center; gap: 8px;
  margin: 4px 0 8px;
  font-size: 12px; color: var(--ink-1);
  cursor: pointer;
  user-select: none;
}
.login-remember input[type="checkbox"] { width: 14px; height: 14px; cursor: pointer; accent-color: var(--accent); }
.login-msg {
  min-height: 18px;
  font-size: 12px;
  color: #d04848;
  margin: 4px 0 10px;
  line-height: 1.5;
}
.login-msg.success { color: var(--accent); }
.login-actions {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
}
.login-primary, .login-secondary {
  font: inherit;
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.login-primary {
  flex: 1;
  padding: 9px 14px;
  background: var(--accent); color: #fff;
  border: 1px solid var(--accent);
  font-weight: 600;
}
.login-primary:hover { filter: brightness(1.05); }
.login-primary:disabled { opacity: 0.6; cursor: not-allowed; }
.login-secondary {
  padding: 9px 12px;
  background: transparent; color: var(--ink-1);
  border: 1px solid var(--bg-3);
}
.login-secondary:hover { color: var(--ink-0); border-color: var(--accent); }

/* ── Library tabs (mine / public) ────────────────────── */
.library-tabs {
  display: flex;
  gap: 0;
  margin: 0 -2px 8px;
  border-bottom: 1px solid var(--bg-3);
}
.library-tab {
  flex: 1;
  padding: 7px 10px;
  background: transparent;
  color: var(--ink-2);
  border: 0;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.library-tab:hover { color: var(--ink-0); }
.library-tab.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

/* ── Library item (公共谱) ────────────────────────────── */
.library-item.public {
  cursor: default;
  text-align: left;
}
.library-item-owner {
  font-size: 11px;
  color: var(--ink-2);
  margin-top: 3px;
  font-style: italic;
}
.library-item-forked {
  font-size: 10px;
  color: var(--ink-2);
  margin-top: 2px;
  font-style: italic;
}
.library-item-actions {
  display: flex;
  gap: 6px;
  margin-top: 8px;
  flex-wrap: wrap;
}
.library-item-actions button {
  font: inherit;
  font-size: 11px;
  padding: 4px 10px;
  background: var(--bg-2);
  color: var(--ink-1);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-sm);
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.library-item-actions button:hover { background: var(--bg-3); color: var(--ink-0); }
.library-item-actions .item-action-primary {
  background: var(--accent-soft);
  border-color: var(--accent-ring);
  color: var(--accent);
  font-weight: 600;
}
.library-item-actions .item-action-primary:hover {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.library-item-actions .item-action-danger { color: #d04848; }
.library-item-actions .item-action-danger:hover {
  background: #d04848;
  color: #fff;
  border-color: #d04848;
}

/* ── 减少动效（系统级开了 prefers-reduced-motion 时秒切，不动来动去） ── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0s !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0s !important;
  }
}

/* ── 专注模式 / 演奏视图（Shift+F 切换） ──
   #playlist-panel 和 #score-header 已删；#syncIcon 现在在 #toolbar 内被父级一并隐藏。 */
body.focus-mode #toolbar,
body.focus-mode #mode-sidebar,
body.focus-mode #library-panel,
body.focus-mode #inspector,
body.focus-mode footer { display: none !important; }
body.focus-mode #main-wrapper { grid-template-columns: 1fr; }
body.focus-mode #score-scroll { padding-top: 12px; }
body.focus-mode #score-area { padding: 12px 24px; }
/* focus-mode 下 bottom-area 是 auto 高 mini-map 一条；#handpan-visual 浮窗不在 #bottom-area
   内、未被本节 display:none 隐藏，仍可见——焦点模式下用户经常用手碟点选编辑，留着合理。 */

#focusExit {
  position: fixed;
  top: 12px;
  right: 12px;
  z-index: 9000;
  background: var(--bg-2);
  color: var(--ink-1);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-sm);
  padding: 6px 12px;
  font-size: 12px;
  cursor: pointer;
  box-shadow: var(--e2);
  display: none;
}
body.focus-mode #focusExit { display: inline-flex; align-items: center; gap: 6px; }
#focusExit:hover { background: var(--bg-3); }
#focusExit kbd {
  font-size: 10px;
  padding: 1px 5px;
  border: 1px solid var(--bg-3);
  border-radius: 3px;
  background: var(--bg-1);
}

/* ── 选区浮动「沉浸练习」按钮 ── */
/* 鼠标拖选出多 cell 区域后，editor.js 把它定位到松手处附近并 unhide。 */
#practiceFloatBtn {
  position: fixed;
  z-index: 9000;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 7px 12px;
  font-size: 13px;
  font-weight: 600;
  color: #fff;
  background: var(--accent);
  border: none;
  border-radius: var(--r-sm);
  box-shadow: var(--e2);
  cursor: pointer;
  white-space: nowrap;
  animation: practiceFloatBtnIn 0.12s ease-out;
}
#practiceFloatBtn[hidden] { display: none; }
#practiceFloatBtn:hover { filter: brightness(1.07); }
@keyframes practiceFloatBtnIn {
  from { opacity: 0; transform: translateY(3px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ── 新用户引导提示（一行） ── */
#onboardingHint {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin: 6px auto 10px;
  padding: 8px 14px;
  background: var(--accent-soft);
  color: var(--ink-1);
  border-radius: var(--r-md);
  font-size: 12px;
  max-width: max-content;
  animation: onboardingFadeIn 0.3s var(--ease);
}
#onboardingHint[hidden] { display: none; }
.onboarding-text { line-height: 1.5; }
.onboarding-link {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dashed color-mix(in srgb, var(--accent) 50%, transparent);
  padding-bottom: 1px;
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.onboarding-link:hover {
  color: var(--ink-0);
  border-bottom-color: var(--accent);
}
.onboarding-text kbd {
  display: inline-block;
  font-size: 11px;
  padding: 1px 5px;
  margin: 0 1px;
  border: 1px solid var(--bg-3);
  border-radius: 3px;
  background: var(--bg-0);
  color: var(--ink-0);
  font-family: inherit;
}
.onboarding-dismiss {
  flex: none;
  width: 18px;
  height: 18px;
  border: none;
  background: transparent;
  color: var(--ink-2);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  border-radius: 50%;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.onboarding-dismiss:hover { background: var(--bg-3); color: var(--ink-0); }
@keyframes onboardingFadeIn {
  from { opacity: 0; transform: translateY(-2px); }
  to   { opacity: 1; transform: translateY(0); }
}
body.focus-mode #onboardingHint { display: none !important; }

/* ── 手碟状态 pill + a11y ── */
.hp-status-pill {
  position: absolute;
  right: 8px; bottom: 6px;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px;
  background: var(--bg-2);
  color: var(--ink-2);
  border: 1px solid var(--bg-3);
  border-radius: 999px;
  font-size: 11px;
  letter-spacing: 0.01em;
  pointer-events: none;
  user-select: none;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.hp-status-pill.is-write {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent-ring, var(--accent));
}
.hp-status-icon { font-size: 12px; line-height: 1; }
.hp-status-text { font-weight: 500; }

.hp-note:focus { outline: none; }
.hp-note:focus-visible .hp-circle {
  stroke: var(--accent);
  stroke-width: 2;
  filter: drop-shadow(0 0 0 var(--accent-soft));
}

/* ── N2 试音模式（大屏点奏 + 录临时谱） ── */
body.tap-mode #toolbar,
body.tap-mode #mode-sidebar,
body.tap-mode #library-panel,
body.tap-mode #score-scroll,
body.tap-mode #onboardingHint,
body.tap-mode #focusExit,
body.tap-mode footer { display: none !important; }
body.tap-mode #main-wrapper { grid-template-columns: 1fr; }
/* tap-mode：手碟已从 inspector 移至 #bottom-area，inspector 整块隐藏 */
body.tap-mode #inspector { display: none !important; }
body.tap-mode #inspector-card-measure,
body.tap-mode #inspector-card-playback,
body.tap-mode #inspector-card-ai { display: none !important; }
/* tap-mode 现在通过 body.tap-mode #bottom-area / #handpan-visual 全屏铺满（见下方），
   原 inspector-card-handpan 规则已随卡片删除一并移除 */

body.tap-mode { background: var(--bg-1); }

body.tap-mode #bottom-area {
  position: fixed; inset: 0; height: 100vh !important;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
}

body.tap-mode #mixer-panel { display: none !important; }

/* tap-mode 用 position: fixed inset:0 把手碟铺满全屏，覆盖默认浮窗定位 + border / shadow */
body.tap-mode #workspace > #handpan-visual {
  position: fixed; inset: 0;
  width: 100vw; height: 100vh;
  right: auto; bottom: auto;
  border: none; border-radius: 0; box-shadow: none;
  padding: 0;
  background: var(--bg-1);
  z-index: 9500;
  display: flex; align-items: center; justify-content: center;
}
body.tap-mode #handpan-visual svg {
  height: min(80vh, 80vw) !important;
  width: min(80vh, 80vw) !important;
  min-height: 0 !important;
  max-height: none !important;
}

#tapBar {
  position: fixed; bottom: 0; left: 0; right: 0;
  display: none;
  background: var(--bg-1);
  border-top: 1px solid var(--bg-3);
  padding: 12px 20px;
  z-index: 9000;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.08);
}
body.tap-mode #tapBar { display: flex; }

#tapCount {
  font-size: 13px;
  color: var(--ink-1);
  font-weight: 500;
}

.tap-bar-actions { display: flex; gap: 10px; }

.tap-bar-actions button {
  font: inherit;
  font-size: 13px;
  padding: 7px 16px;
  border-radius: var(--r-sm);
  cursor: pointer;
  border: 1px solid var(--bg-3);
  background: var(--bg-2);
  color: var(--ink-1);
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.tap-bar-actions button:hover { background: var(--bg-3); color: var(--ink-0); }
.tap-bar-actions .tap-save {
  background: var(--accent-soft);
  border-color: var(--accent-ring, var(--accent));
  color: var(--accent);
  font-weight: 600;
}
.tap-bar-actions .tap-save:hover {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}

#tapLastNote {
  position: fixed; top: 24px; left: 50%; transform: translateX(-50%);
  display: none;
  font-size: 32px; font-weight: 600; color: var(--accent);
  z-index: 9001;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.4s var(--ease);
  letter-spacing: 0.04em;
}

.handpan-group { gap: 4px; }
.handpan-select {
  background: var(--bg-2);
  color: var(--ink-0);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-sm);
  padding: 3px 22px 3px 8px;
  font-size: 12px;
  font-family: inherit;
  cursor: pointer;
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--ink-2) 50%), linear-gradient(135deg, var(--ink-2) 50%, transparent 50%);
  background-position: calc(100% - 11px) 50%, calc(100% - 7px) 50%;
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
  max-width: 240px;
  text-overflow: ellipsis;
}
.handpan-select:hover { background-color: var(--bg-3); }
.handpan-select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.handpan-select option { color: var(--ink-0); background: var(--bg-1); }

/* ── mini SVG（gallery 内 4 个风格预览） ── */
.hp-mini { display: block; width: 100%; aspect-ratio: 1; max-width: 110px; margin: 0 auto; }

/* D · 暖色奶油（其它 E/F/G mini 颜色直接 hardcoded inline 在 SVG attribute 上） */
.hp-mini-d .hp-mini-disc { fill: var(--accent-soft); stroke: var(--accent); stroke-width: 0.6; stroke-opacity: 0.4; }
.hp-mini-d .hp-mini-field { fill: var(--bg-0); stroke: var(--accent); stroke-width: 0.6; }
.hp-mini-d .hp-mini-ding { fill: var(--accent); stroke: var(--accent); stroke-width: 0.7; }

/* ── 缩放反馈 toast（屏幕中央，~900ms 淡出） ─────────────── */
.zoom-toast {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%) scale(0.92);
  padding: 14px 28px;
  background: var(--bg-1);
  color: var(--ink-0);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-md);
  font-size: 22px;
  font-weight: 600;
  letter-spacing: 0.02em;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  user-select: none;
  z-index: 9000;
  opacity: 0;
  box-shadow: var(--e2);
  transition: opacity 0.18s var(--ease), transform 0.18s var(--ease);
}
.zoom-toast.visible {
  opacity: 0.96;
  transform: translate(-50%, -50%) scale(1);
}

/* ── AI 识谱 panel（Wave 2B：从底部 fixed dock 改为主区 grid 面板） ───
   不再是 fixed bottom popup —— 现在和 #workspace / #library-panel 共占 grid 第 2 列，
   靠 setMode('ai') 切 hidden 互斥可见。子元素（.ai-dock-col / .ai-dock-intro 等）样式
   保持不变，仍然复用 .ai-dock-* 规则。 */
.ai-import-panel {
  grid-column: 3;
  grid-row: 1;
  position: relative;            /* .ai-dock-close 用 absolute 钉到右上角 */
  background: var(--bg-1);
  padding: 24px 32px 32px;
  overflow-y: auto;
  min-width: 0;
  font-size: 13px;
  color: var(--ink-0);
  animation: ai-panel-fade 0.18s var(--ease);
}
.ai-import-panel[hidden] { display: none; }

/* 顶部欢迎文案：模块 contextual 引导，温暖一行 */
.ai-import-panel .ai-import-intro {
  max-width: 1100px;
  margin: 0 auto 18px;
  font-size: 13px;
  color: var(--ink-2);
  text-align: center;
  letter-spacing: 0.01em;
}

/* 内层容器：max-width 居中，宽屏下不显得稀疏；
   2026-05-09 重构为两卡布局：左 Notepan 谱子（PDF / 截图）/ 右 音频。
   原三栏 grid 已废弃，对应 .ai-dock-intro / .ai-dock-waveform-col / .ai-dock-action
   wrapper class 已不在 HTML 中使用，相关样式作为 dead rules 暂留以兼容快照。 */
.ai-import-panel .ai-import-inner {
  max-width: 1100px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1.25fr;
  gap: 32px;
  align-items: stretch;
  min-height: 220px;
}

/* 卡片化：两卡共享外观，padding / 边框 / 圆角 / 浅阴影 / 暖纸渐变 */
.ai-import-panel .ai-dock-card {
  background:
    linear-gradient(180deg,
      var(--bg-0) 0%,
      color-mix(in srgb, var(--bg-0) 94%, var(--accent-soft) 6%) 100%);
  border: 1px solid color-mix(in srgb, var(--ink-3) 18%, transparent);
  border-radius: var(--r-xl);
  padding: 20px 22px 22px;
  gap: 12px;
  box-shadow: var(--shadow-card);
  position: relative;
  overflow: hidden;
}
/* 两卡 top accent 细线区分：Notepan = RH（橙陶），音频 = LH（鼠尾草绿）；
   隐喻"两只手 / 两条路径"，与产品里 RH/LH 配色形成呼应 */
.ai-import-panel .ai-dock-card-notepan::before,
.ai-import-panel .ai-dock-card-audio::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  border-radius: var(--r-xl) var(--r-xl) 0 0;
}
.ai-import-panel .ai-dock-card-notepan::before {
  background: linear-gradient(90deg, transparent, var(--rh) 50%, transparent);
  opacity: 0.55;
}
.ai-import-panel .ai-dock-card-audio::before {
  background: linear-gradient(90deg, transparent, var(--lh) 50%, transparent);
  opacity: 0.55;
}

/* 音频识谱 prod 未上线遮罩：卡片照常渲染，罩一层"开发中 / 敬请期待"
   （仅非 dev，由 editor.js applyAudioImportEnvGate 注入 .ai-dock-soon 子元素）。
   .ai-dock-card 自带 position:relative + overflow:hidden，inset:0 贴满裁到圆角内；
   遮罩 cursor:not-allowed + 捕获点击，下层上传控件不可点。 */
.ai-import-panel .ai-dock-soon {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 24px;
  text-align: center;
  cursor: not-allowed;
  background: color-mix(in srgb, var(--bg-0) 10%, transparent);
  backdrop-filter: blur(2px) saturate(0.95);
  -webkit-backdrop-filter: blur(2px) saturate(0.95);
  animation: ai-panel-fade 0.2s var(--ease);
}
/* 文字单独套底色卡片：整体遮罩很透（30%）时仍让"开发中"读得清，
   不靠抬高遮罩不透明度。卡片自己近不透明 + 描边 + 阴影，浮在虚化卡面上。 */
.ai-import-panel .ai-dock-soon-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 16px 24px;
  border-radius: var(--r-lg);
  background: color-mix(in srgb, var(--bg-0) 94%, transparent);
  border: 1px solid color-mix(in srgb, var(--ink-3) 16%, transparent);
  box-shadow: var(--shadow-card);
}
.ai-import-panel .ai-dock-soon-icon { font-size: 30px; line-height: 1; }
.ai-import-panel .ai-dock-soon-title {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink-0);
  letter-spacing: 0.02em;
}
.ai-import-panel .ai-dock-soon-sub {
  font-size: 12px;
  color: var(--ink-2);
  letter-spacing: 0.1em;
}

/* 卡头：icon + 标题区横排（标题 + 副标题在右侧纵排） */
.ai-import-panel .ai-dock-card-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 2px;
}
.ai-import-panel .ai-dock-card-head .ai-dock-icon {
  width: 30px;
  height: 30px;
  font-size: 14px;
  margin-bottom: 0;
  flex-shrink: 0;
}
.ai-import-panel .ai-dock-card-titles {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.ai-import-panel .ai-dock-card-titles .ai-dock-title {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
}
.ai-import-panel .ai-dock-card-titles .ai-dock-sub {
  margin: 0;
  font-size: 12px;
  color: var(--ink-2);
  opacity: 0.85;
  line-height: 1.3;
}

/* 文件类型 chip：低饱和胶囊，辅助扫描 */
.ai-import-panel .ai-dock-card-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 4px;
}
.ai-import-panel .ai-dock-chip {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--accent-soft) 60%, transparent);
  border: 1px solid color-mix(in srgb, var(--ink-3) 16%, transparent);
  font-size: 10.5px;
  letter-spacing: 0.02em;
  color: var(--ink-1);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}
/* 卡内 stage 块（upload / progress / result / error）顶部留点呼吸 */
.ai-import-panel .ai-dock-card .ai-dock-upload,
.ai-import-panel .ai-dock-card .ai-dock-progress,
.ai-import-panel .ai-dock-card .ai-dock-result,
.ai-import-panel .ai-dock-card .ai-dock-error {
  margin-top: 4px;
}
/* 上传 stage 内部纵向 flex（dropzone / 波形 / 选项 / 提交按钮） */
.ai-import-panel .ai-dock-card .ai-dock-upload {
  flex: 1;
  min-height: 0;
  gap: 10px;
}
/* dropzone 变体：fill —— 在 Notepan 卡内撑满高度，避免下半空白 */
.ai-import-panel .ai-dock-card .ai-dock-dropzone--fill {
  flex: 1;
  min-height: 160px;
}
/* 音频卡 dropzone 也吃 stage upload 内剩余空间 */
.ai-import-panel .ai-dock-card .ai-dock-upload > .ai-dock-dropzone {
  flex: 1;
  min-height: 140px;
}
/* fields 紧凑放在 dropzone 下方，不再 margin-top:auto 撑底 */
.ai-import-panel .ai-dock-card .ai-dock-fields {
  margin-top: 0;
  flex: 0 0 auto;
}
/* 波形：上传后显示，自然高度 */
.ai-import-panel .ai-dock-card .ai-dock-waveform {
  flex: 0 0 auto;
}

/* 响应式：< 900px 时两卡 stack 单列 */
@media (max-width: 900px) {
  .ai-import-panel .ai-import-inner {
    grid-template-columns: 1fr;
    min-height: 0;
  }
  .ai-import-panel .ai-dock-card .ai-dock-dropzone--fill,
  .ai-import-panel .ai-dock-card .ai-dock-upload > .ai-dock-dropzone {
    min-height: 120px;
  }
}

/* === 识谱历史记录区（在两卡下方）================================ */
.ai-import-panel .ai-history {
  max-width: 1100px;
  margin: 28px auto 0;
}
.ai-import-panel .ai-history-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 10px;
}
.ai-import-panel .ai-history-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-1);
  letter-spacing: 0.01em;
  margin: 0;
}
.ai-import-panel .ai-history-clear {
  font-size: 11.5px;
  color: var(--ink-2);
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 2px 6px;
  border-radius: var(--r-sm);
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.ai-import-panel .ai-history-clear:hover {
  color: var(--ink-0);
  background: var(--bg-2);
}
.ai-import-panel .ai-history-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ai-import-panel .ai-history-empty {
  font-size: 12px;
  color: var(--ink-2);
  opacity: 0.7;
  text-align: center;
  padding: 18px 8px;
  margin: 0;
  border: 1px dashed color-mix(in srgb, var(--ink-3) 22%, transparent);
  border-radius: var(--r-md);
}
.ai-import-panel .ai-history-item {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: var(--r-md);
  background: color-mix(in srgb, var(--bg-0) 75%, transparent);
  border: 1px solid color-mix(in srgb, var(--ink-3) 12%, transparent);
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
  cursor: pointer;
}
.ai-import-panel .ai-history-item:hover {
  background: var(--bg-0);
  border-color: color-mix(in srgb, var(--accent) 32%, transparent);
  box-shadow: 0 1px 4px color-mix(in srgb, var(--accent-ring) 50%, transparent);
}
.ai-import-panel .ai-history-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  height: 22px;
  padding: 0 6px;
  border-radius: 6px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  background: color-mix(in srgb, var(--accent-soft) 60%, transparent);
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
}
.ai-import-panel .ai-history-badge--audio {
  background: color-mix(in srgb, var(--lh) 18%, transparent);
  color: var(--lh);
  border-color: color-mix(in srgb, var(--lh) 35%, transparent);
  font-size: 13px;
}
.ai-import-panel .ai-history-badge--pdf {
  background: color-mix(in srgb, var(--rh) 18%, transparent);
  color: var(--rh);
  border-color: color-mix(in srgb, var(--rh) 35%, transparent);
}
.ai-import-panel .ai-history-name {
  font-size: 13px;
  color: var(--ink-0);
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.ai-import-panel .ai-history-meta {
  font-size: 11.5px;
  color: var(--ink-2);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.ai-import-panel .ai-history-action {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: none;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.ai-import-panel .ai-history-action:hover {
  background: var(--bg-2);
  color: var(--ink-0);
}
.ai-import-panel .ai-history-action--del:hover {
  color: #c44;
}

@keyframes ai-panel-fade {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* 兼容遗留 .ai-dock class（旧引用 / 测试快照不会立刻挂掉） */
.ai-dock[hidden] { display: none; }

.ai-dock-close {
  position: absolute;
  top: 12px;
  right: 16px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 1px solid var(--bg-3);
  background: var(--bg-0);
  color: var(--ink-1);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.ai-dock-close:hover {
  background: var(--bg-2);
  color: var(--ink-0);
  border-color: var(--bg-4);
}

.ai-dock-col {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.ai-dock-col [hidden] { display: none !important; }

/* 左栏：介绍 + 选项 ─────────────────────────────────────────── */
.ai-dock-intro {
  gap: 6px;
}
.ai-dock-icon {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  margin-bottom: 4px;
  box-shadow: 0 2px 6px var(--accent-ring);
}
.ai-dock-title {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: var(--ink-0);
  letter-spacing: -0.005em;
}
.ai-dock-sub {
  margin: 0 0 10px;
  font-size: 13px;
  color: var(--ink-1);
  opacity: 0.65;
}
.ai-dock-fields {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: auto;
}
.ai-dock-field {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  color: var(--ink-1);
}
.ai-dock-field > span {
  flex: 0 0 64px;
  font-weight: 600;
  color: var(--ink-0);
}
.ai-dock-field select,
.ai-dock-field input[type="number"] {
  flex: 1;
  background: var(--bg-0);
  border: 1px solid var(--bg-3);
  border-radius: var(--r-sm);
  padding: 6px 8px;
  font-size: 13px;
  color: var(--ink-0);
  font-family: inherit;
  min-width: 0;
}
.ai-dock-field select:focus,
.ai-dock-field input[type="number"]:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-ring);
}

/* 中栏：波形 + 播放 ────────────────────────────────────────── */
.ai-dock-waveform-col {
  align-items: stretch;
  justify-content: center;
}
.ai-dock-empty {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-0);
  border: 1px dashed var(--bg-3);
  border-radius: 12px;
  color: var(--ink-2);
  opacity: 0.65;
  font-size: 13px;
}
.ai-dock-waveform {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--bg-0);
  border: 1px solid var(--bg-3);
  border-radius: 12px;
  padding: 12px 14px;
  flex: 1;
}
.ai-dock-play {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  background: var(--accent);
  color: #fff;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-left: 2px;
  transition: background var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
  box-shadow: 0 2px 6px var(--accent-ring);
}
.ai-dock-play:hover {
  transform: scale(1.04);
}
.ai-dock-play.is-playing {
  padding-left: 0;
}
.ai-dock-time {
  font-size: 12px;
  color: var(--ink-1);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
  min-width: 38px;
  text-align: center;
}
#aiDockWaveCanvas {
  flex: 1;
  height: 56px;
  min-width: 0;
  background: linear-gradient(to right, var(--accent-soft), rgba(219, 125, 106, 0.04));
  border-radius: 6px;
}

/* 右栏：上传 / 进度 / 结果 / 错误 ───────────────────────────── */
.ai-dock-action {
  justify-content: center;
}
.ai-dock-upload,
.ai-dock-progress,
.ai-dock-result,
.ai-dock-error {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
}

/* 上传：dropzone + 主按钮 */
.ai-dock-dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  /* 装饰性虚线主题（ui-design.md §3.5）：1.5px dashed，半透明 ink，更细密器物感 */
  border: 1.5px dashed color-mix(in srgb, var(--ink-3) 38%, transparent);
  border-radius: 14px;
  padding: 18px 14px;
  background: color-mix(in srgb, var(--bg-0) 80%, transparent);
  color: var(--ink-1);
  cursor: pointer;
  transition:
    border-color var(--t-fast) var(--ease),
    background var(--t-fast) var(--ease),
    color var(--t-fast) var(--ease),
    box-shadow var(--t-fast) var(--ease);
  text-align: center;
}
.ai-dock-dropzone:hover,
.ai-dock-dropzone.is-dragover {
  border-color: var(--accent);
  background: linear-gradient(180deg, var(--accent-soft), color-mix(in srgb, var(--accent-soft) 50%, transparent));
  color: var(--ink-0);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 25%, transparent);
}
/* 上传完成 chip 状态：dropzone 收成单行，文件名 + 重选提示 */
.ai-dock-dropzone.is-loaded {
  flex-direction: row;
  flex: 0 0 auto;
  min-height: 0;
  padding: 10px 14px;
  gap: 8px;
  border-style: solid;
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: color-mix(in srgb, var(--accent-soft) 70%, transparent);
}
.ai-dock-dropzone.is-loaded .ai-dock-upload-icon { font-size: 14px; }
.ai-dock-dropzone.is-loaded .ai-dock-upload-text {
  flex: 1;
  text-align: left;
  font-size: 12.5px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.ai-dock-dropzone.is-loaded .ai-dock-upload-hint {
  font-size: 11px;
  color: var(--accent);
  opacity: 1;
  flex-shrink: 0;
}
.ai-dock-dropzone.is-loaded .ai-dock-upload-hint::before {
  content: "↻ ";
}

/* 高级选项折叠（默认隐藏，避免初次门槛） */
.ai-dock-options {
  margin-top: 2px;
}
.ai-dock-options[open] .ai-dock-options-summary {
  color: var(--ink-0);
}
.ai-dock-options-summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--ink-2);
  padding: 2px 0;
  user-select: none;
  transition: color var(--t-fast) var(--ease);
}
.ai-dock-options-summary::-webkit-details-marker { display: none; }
.ai-dock-options-summary::before {
  content: "›";
  display: inline-block;
  font-size: 14px;
  color: var(--ink-2);
  transition: transform var(--t-fast) var(--ease);
}
.ai-dock-options[open] .ai-dock-options-summary::before {
  transform: rotate(90deg);
}
.ai-dock-options-summary:hover { color: var(--ink-0); }
.ai-dock-options .ai-dock-fields {
  margin-top: 8px;
  padding-left: 6px;
}
.ai-dock-upload-icon {
  font-size: 22px;
  color: var(--accent);
  line-height: 1;
}
.ai-dock-upload-text {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-0);
}
.ai-dock-upload-hint {
  font-size: 11px;
  color: var(--ink-2);
  opacity: 0.8;
}

/* primary / secondary 按钮 */
.ai-dock-primary,
.ai-dock-secondary {
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  border-radius: var(--r-sm);
  padding: 8px 14px;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease);
  line-height: 1.2;
}
.ai-dock-primary {
  background: var(--accent);
  color: #fff;
  border: 1px solid var(--accent);
  box-shadow: 0 2px 4px var(--accent-ring);
}
.ai-dock-primary:hover:not([disabled]) {
  background: #c4664f;
  border-color: #c4664f;
}
[data-theme="dark"] .ai-dock-primary:hover:not([disabled]) {
  background: #f5ad9a;
  border-color: #f5ad9a;
}
.ai-dock-primary[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
  box-shadow: none;
}
.ai-dock-secondary {
  background: transparent;
  color: var(--ink-1);
  border: 1px solid var(--bg-3);
}
.ai-dock-secondary:hover {
  background: var(--bg-2);
  color: var(--ink-0);
  border-color: var(--bg-4);
}

/* 进度：spinner + 步骤勾选 */
.ai-dock-progress {
  align-items: flex-start;
}
.ai-dock-spinner {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 3px solid var(--bg-3);
  border-top-color: var(--accent);
  animation: ai-dock-spin 0.8s linear infinite;
}
@keyframes ai-dock-spin {
  to { transform: rotate(360deg); }
}
.ai-dock-progress-title {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-0);
}
.ai-dock-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
}
.ai-dock-step {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  color: var(--ink-2);
  line-height: 1.2;
}
.ai-dock-step-mark {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 2px solid var(--ink-3);
  background: transparent;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  color: #fff;
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.ai-dock-step.active {
  color: var(--ink-0);
  font-weight: 500;
}
.ai-dock-step.active .ai-dock-step-mark {
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.ai-dock-step.done {
  color: var(--ink-1);
}
.ai-dock-step.done .ai-dock-step-mark {
  background: var(--lh);
  border-color: var(--lh);
}
.ai-dock-step.done .ai-dock-step-mark::after {
  content: "✓";
  font-size: 9px;
  font-weight: 700;
  line-height: 1;
}

/* 结果：标题 / stats / warnings / actions */
.ai-dock-result-title {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-0);
}
.ai-dock-stats {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 12px;
  color: var(--ink-1);
  max-height: 96px;
  overflow-y: auto;
}
.ai-dock-stats li {
  padding: 3px 0;
  border-bottom: 1px dashed var(--bg-3);
}
.ai-dock-stats li:last-child { border-bottom: none; }
.ai-dock-warnings {
  background: rgba(229, 175, 60, 0.14);
  border: 1px solid rgba(229, 175, 60, 0.45);
  border-radius: var(--r-sm);
  padding: 6px 10px;
  font-size: 12px;
  color: var(--ink-0);
  max-height: 72px;
  overflow-y: auto;
}
[data-theme="dark"] .ai-dock-warnings {
  background: rgba(229, 175, 60, 0.10);
  border-color: rgba(229, 175, 60, 0.4);
}
.ai-dock-warnings ul {
  margin: 0;
  padding-left: 18px;
}
.ai-dock-warnings li { margin: 2px 0; }
.ai-dock-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.ai-dock-actions .ai-dock-primary,
.ai-dock-actions .ai-dock-secondary {
  flex: 1;
  min-width: 0;
  text-align: center;
}

/* 错误 */
.ai-dock-error-msg {
  color: var(--rh);
  font-size: 13px;
  font-weight: 500;
  line-height: 1.5;
  margin: 0;
}

/* 响应式：窄屏堆叠 */
@media (max-width: 900px) {
  .ai-dock {
    grid-template-columns: 1fr;
    gap: 12px;
    padding: 16px 18px;
    height: auto;
    max-height: 70vh;
    overflow-y: auto;
  }
  .ai-dock-intro .ai-dock-fields { margin-top: 6px; }
  .ai-dock-empty { min-height: 60px; }
}

/* ── 装饰动效系统（2026-05-07）──
   流动虚线 + 柔光 + 卡片阴影。供 score / toolbar / cards 复用。 */

:root {
  /* 柔光（叠在 box-shadow 上） */
  --glow-accent-soft:
    0 0 0 3px var(--accent-soft),
    0 0 18px 4px var(--accent-ring);
  --glow-accent-pulse:
    0 0 0 5px var(--accent-soft),
    0 0 28px 8px var(--accent-ring),
    0 4px 12px rgba(0,0,0,0.04);

  /* 卡片阴影（比 --e1 更柔，几乎看不见，仅区分层次） */
  --shadow-card:
    0 1px 2px rgba(0,0,0,0.04),
    0 6px 24px rgba(0,0,0,0.06),
    0 12px 36px rgba(0,0,0,0.04);
  --shadow-card-hover:
    0 2px 4px rgba(0,0,0,0.04),
    0 8px 24px rgba(0,0,0,0.06);

  /* 装饰虚线颜色（独立 token，便于暗色调） */
  --deco-dash-color: var(--ink-3);
  --deco-dash-color-strong: var(--ink-2);
}

[data-theme="dark"] {
  --glow-accent-soft:
    0 0 0 3px var(--accent-soft),
    0 0 18px 4px var(--accent-ring);
  --glow-accent-pulse:
    0 0 0 5px var(--accent-soft),
    0 0 28px 8px var(--accent-ring),
    0 4px 12px rgba(0,0,0,0.25);
  --shadow-card:
    0 1px 2px rgba(0,0,0,0.30),
    0 6px 24px rgba(0,0,0,0.22),
    0 12px 36px rgba(0,0,0,0.18);
  --shadow-card-hover:
    0 2px 4px rgba(0,0,0,0.30),
    0 8px 24px rgba(0,0,0,0.22);
  --deco-dash-color: var(--ink-3);
  --deco-dash-color-strong: var(--ink-2);
}

/* 流动虚线 keyframes */
@keyframes deco-dash-flow {
  to { stroke-dashoffset: -200; }
}
@keyframes deco-dash-flow-slow {
  to { stroke-dashoffset: -120; }
}

/* 柔光 pulse keyframes（1.4s 周期，避开常见 BPM 60/100/140 的整数倍） */
@keyframes accent-glow-pulse {
  0%, 100% {
    box-shadow:
      0 0 0 2px var(--accent-soft),
      0 0 10px 2px var(--accent-ring);
  }
  50% {
    box-shadow:
      0 0 0 4px var(--accent-soft),
      0 0 18px 4px var(--accent-ring);
  }
}

/* 装饰虚线工具类（用在 SVG <path> / <line> / <circle> 上） */
.deco-dash {
  stroke: var(--deco-dash-color);
  stroke-width: 1;
  stroke-dasharray: 2 5;
  fill: none;
  opacity: 0.55;
}
.deco-dash--strong {
  stroke: var(--deco-dash-color-strong);
  opacity: 0.75;
}
.deco-dash--flowing {
  animation: deco-dash-flow 14s linear infinite;
}
.deco-dash--flowing-slow {
  animation: deco-dash-flow-slow 22s linear infinite;
}

/* 装饰圆环（HTML <div>，纯 CSS 圆点环） */
.deco-ring {
  position: relative;
  display: inline-block;
}
.deco-ring::before {
  content: "";
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  border: 1px dashed var(--deco-dash-color);
  opacity: 0.5;
  pointer-events: none;
}

/* 卡片基类（其它 agent 后续会用） */
.card {
  background: var(--bg-0);
  border: 1px solid color-mix(in srgb, var(--ink-3) 25%, transparent);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-card);
  padding: 20px 24px;
  transition: box-shadow var(--t-med) var(--ease), transform var(--t-med) var(--ease);
}
.card:hover { box-shadow: var(--shadow-card-hover); }

/* 减少动效偏好：所有 deco 动画关闭 */
@media (prefers-reduced-motion: reduce) {
  .deco-dash--flowing, .deco-dash--flowing-slow { animation: none; }
  .accent-glow-pulse, .cell.playing[data-ri="0"]::after { animation: none; }
}

/* ── Inspector aside（2026-05-23：因侧栏插到 col 2，inspector 顺移到 col 4）── */
#inspector.app-inspector {
  grid-column: 4;
  grid-row: 1;
  background: var(--bg-1);
  border-left: 0;
  padding: 16px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

/* 设计图风格：每张卡有自己的微粉米底色（--bg-2），无边无阴影，柔大圆角 */
.inspector-card {
  padding: 14px 16px;
  background: var(--bg-2);
  border: 0;
  box-shadow: none;
  border-radius: var(--r-lg);
}
.inspector-card:hover { box-shadow: none; }

.inspector-card-head { margin-bottom: 8px; }
.inspector-card-title {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-2);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.inspector-card-body { font-size: 13px; color: var(--ink-1); }

.inspector-measure-num {
  font-size: 28px;
  font-weight: 600;
  color: var(--ink-0);
  line-height: 1;
}
.inspector-measure-num small { font-size: 14px; color: var(--ink-2); font-weight: 400; }
.inspector-loop-info { margin-top: 6px; font-size: 12px; color: var(--ink-2); }

.inspector-placeholder {
  padding: 12px;
  background: var(--bg-2);
  border-radius: var(--r-md);
  font-size: 12px;
  color: var(--ink-2);
  text-align: center;
}

.inspector-ai-btn {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 4px 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  text-align: left;
  color: var(--ink-0);
  font-family: inherit;
}
.inspector-ai-icon {
  width: 36px; height: 36px;
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft);
  color: var(--accent);
  border-radius: 50%;
  font-size: 16px;
}
.inspector-ai-text strong { display: block; font-size: 13px; }
.inspector-ai-text small { display: block; font-size: 11.5px; color: var(--ink-2); }

/* （2026-05-07 Wave 2C：手碟已从 inspector 移至 #bottom-area，旧规则删除） */

/* ── 曲谱结构卡（2026-05-07 v2：段落折叠 + 小节 chip 网格 + 播放头跟随）── */
.inspector-structure-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 360px;
  overflow-y: auto;
  margin: 0 -4px;
  padding: 0 4px;
  scrollbar-width: thin;
}
/* 整段（details / div for anonymous） */
.inspector-structure-section {
  margin: 0;
  padding: 0;
  border: 0;
}
.inspector-structure-section[open] > .inspector-structure-section-head .inspector-structure-caret {
  transform: rotate(0deg);
}
.inspector-structure-section:not([open]) > .inspector-structure-section-head .inspector-structure-caret {
  transform: rotate(-90deg);
}
.inspector-structure-section-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px;
  border-radius: var(--r-sm);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-1);
  cursor: pointer;
  list-style: none;
  user-select: none;
  transition: background var(--t-fast) var(--ease);
}
.inspector-structure-section-head::-webkit-details-marker { display: none; }
.inspector-structure-section-head:hover { background: var(--bg-2); }
.inspector-structure-caret {
  display: inline-block;
  width: 12px;
  font-size: 10px;
  color: var(--ink-2);
  text-align: center;
  transition: transform var(--t-fast) var(--ease);
}
.inspector-structure-section-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.inspector-structure-section-range {
  font-size: 10.5px;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.inspector-structure-section-count {
  min-width: 22px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--bg-2);
  color: var(--ink-2);
  font-size: 10px;
  font-weight: 600;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
/* 没有 section header 的匿名段：直接撑满，不缩进 */
.inspector-structure-section-anon { padding: 0; }

/* 小节 chip 网格 —— 自适应列宽，密度比线性列表高 4–5 倍 */
.inspector-structure-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(34px, 1fr));
  gap: 4px;
  margin-top: 4px;
  padding: 0 2px 2px;
}
.inspector-structure-section-anon > .inspector-structure-grid { margin-top: 0; padding: 0; }

.inspector-structure-chip {
  height: 26px;
  padding: 0 4px;
  border: 1px solid color-mix(in srgb, var(--ink-3, var(--ink-2)) 25%, transparent);
  border-radius: var(--r-sm);
  background: var(--bg-0);
  color: var(--ink-1);
  font: inherit;
  font-size: 11.5px;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.inspector-structure-chip:hover {
  background: var(--accent-soft);
  border-color: var(--accent-ring);
  color: var(--accent);
}
.inspector-structure-chip.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
}
/* 播放头：用蓝/青色描边 + 内发光，与 active（accent 实心）区分得开 */
.inspector-structure-chip.playing {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-ring);
}
.inspector-structure-chip.active.playing {
  background: var(--accent);
  color: #fff;
  box-shadow: 0 0 0 2px var(--accent-ring);
}
/* 变细分小节：右上角小角标 */
.inspector-structure-chip-variable {
  position: relative;
}
.inspector-structure-chip-variable::after {
  content: "";
  position: absolute;
  top: 3px;
  right: 3px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--ink-2);
}
.inspector-structure-chip.active.inspector-structure-chip-variable::after,
.inspector-structure-chip.playing.inspector-structure-chip-variable::after {
  background: currentColor;
}

/* ── Wave 2B：Inspector 播放控制卡 + 大圆下方 playStatus ── */
.practice-play-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
}
.practice-play-status {
  font-size: 10.5px;
  color: var(--ink-2);
  letter-spacing: 0.04em;
  height: 12px;
  line-height: 1;
}

.inspector-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
}
.inspector-row:first-child { margin-top: 0; }
.inspector-row-controls { gap: 6px; }
.inspector-label {
  flex: 0 0 auto;
  min-width: 36px;
  font-size: 11.5px;
  color: var(--ink-2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.inspector-value {
  flex: 0 0 36px;
  text-align: right;
  font-size: 12px;
  color: var(--ink-1);
  font-variant-numeric: tabular-nums;
}
/* 细分 / 拍数 stepper：数字被 [−] [+] 夹在中间，水平居中而不是默认右对齐
   （右对齐是给 #speedLabel "100%" 这类读数尾巴用的，stepper 中央值不一样）。 */
#subdivLabel,
#beatsLabel { text-align: center; }
.inspector-btn {
  padding: 4px 10px;
  background: var(--bg-0);
  border: 1px solid color-mix(in srgb, var(--ink-3) 25%, transparent);
  border-radius: var(--r-md);
  font-size: 12px;
  color: var(--ink-1);
  cursor: pointer;
  transition: background var(--t-fast) var(--ease);
}
.inspector-btn:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.inspector-btn:active, .inspector-btn.is-active {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
/* removed: .inspector-hand-mute (单手 mute UI 收到练习模式 footer，乐谱模式
   保留 ⌘K 命令入口；状态共享 localStorage["hpn.muteHands"]) */
.inspector-select {
  flex: 1;
  height: 28px;
  border: 1px solid color-mix(in srgb, var(--ink-3) 25%, transparent);
  background: var(--bg-0);
  border-radius: var(--r-md);
  padding: 0 8px;
  font-size: 12px;
  color: var(--ink-0);
}
.inspector-playback-slot .slider-speed { flex: 1; height: 4px; }
.inspector-metro-vol {
  position: relative;
}
.inspector-metro-vol summary {
  list-style: none;
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-0);
  border: 1px solid color-mix(in srgb, var(--ink-3) 25%, transparent);
  border-radius: var(--r-md);
  cursor: pointer;
  font-size: 12px;
}
.inspector-metro-vol summary::-webkit-details-marker { display: none; }
.inspector-metro-vol[open] > .metro-vol-pop,
.inspector-metro-vol > .metro-vol-pop {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  z-index: 50;
  background: var(--bg-0);
  border: 1px solid color-mix(in srgb, var(--ink-3) 25%, transparent);
  border-radius: var(--r-md);
  box-shadow: var(--e2);
  padding: 8px;
  min-width: 200px;
}
/* 选区变速：跟在「基础 BPM ♩=118」右侧，靠右贴齐；视觉上比 bpmDisplay 次要。 */
.inspector-tempo-range-btn {
  margin-left: auto;
  padding: 4px 10px;
  font-size: 11.5px;
  color: var(--ink-2);
  background: transparent;
  white-space: nowrap;
}

/* prev/next nav buttons disabled state */
.practice-topbar-center .practice-nav-btn[disabled] {
  opacity: 0.35;
  cursor: not-allowed;
}

/* ── 设计图风格（2026-05-07）：tile / beat dots / 速度 stepper / pill ── */

/* 顶部双 tile 行：当前小节 + 循环范围 — 两张独立的小卡 */
.inspector-tile-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.inspector-tile { padding: 12px 14px; }
.inspector-tile .inspector-card-head { margin-bottom: 4px; }
.inspector-tile-body {
  display: flex;
  align-items: baseline;
  gap: 4px;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.inspector-tile-num {
  font-size: 26px;
  font-weight: 600;
  color: var(--ink-0);
}
.inspector-tile-num-sm { font-size: 18px; }
.inspector-tile-sep { color: var(--ink-2); font-size: 18px; }
.inspector-tile-sub { color: var(--ink-2); font-size: 14px; }

/* card head 横向布局（标题左 + 数值右） */
.inspector-card-head-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
.inspector-card-meta {
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-0);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
.inspector-card-hint {
  margin-left: 8px;
  font-size: 10.5px;
  color: var(--ink-2);
  letter-spacing: 0.04em;
}

/* 速度 ⊖ slider ⊕ */
.inspector-speed-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.inspector-speed-row .slider-speed { flex: 1; height: 4px; }
.inspector-step-btn {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--ink-3) 28%, transparent);
  background: var(--bg-0);
  color: var(--ink-1);
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: inherit;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.inspector-step-btn:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.inspector-step-btn:active { transform: scale(0.94); }

/* pill 按钮（循环 / 模式切换风） */
.inspector-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 12px;
  background: var(--bg-0);
  border: 1px solid color-mix(in srgb, var(--ink-3) 25%, transparent);
  border-radius: 999px;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-1);
  cursor: pointer;
  font-family: inherit;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.inspector-pill:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.inspector-pill:active,
.inspector-pill.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.inspector-pill-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* AI 卡：整张卡作为大按钮命中，hover 与左栏 active 同色 */
.inspector-card-ai { cursor: pointer; transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease); }
.inspector-card-ai:hover { background: var(--accent); }
.inspector-card-ai:hover .inspector-ai-btn,
.inspector-card-ai:hover .inspector-ai-text strong,
.inspector-card-ai:hover .inspector-ai-text small { color: #fff; }
.inspector-card-ai:hover .inspector-ai-icon {
  background: rgba(255, 255, 255, 0.22);
  color: #fff;
}

/* 旧 .topbar-loop-btn / body.is-looping .topbar-loop-btn 规则已删——
   loop 按钮搬到 inspector「编辑工具」卡，active 视觉由 .inspector-tools-btn.is-active 接管。 */

/* ─────────────────────────────────────────────────────────────
   Inspector 重排（2026-05-07）：顶栏「更多」整段下沉
   ───────────────────────────────────────────────────────────── */

/* Inspector 内的小步进按钮（细分/拍数/速度 共用） */
.inspector-step-btn {
  width: 26px; height: 26px;
  border-radius: var(--r-sm);
  border: 1px solid color-mix(in srgb, var(--ink-3) 25%, transparent);
  background: var(--bg-0);
  color: var(--ink-1);
  cursor: pointer;
  font-size: 13px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background var(--t-fast) var(--ease);
}
.inspector-step-btn:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
/* step-btn 文字变体：保留同款边框 / 圆角 / 高度 / hover，仅宽度按内容撑开。
   给「拆分 / 复制前拍」这类用图示反而抽象的按钮用。 */
.inspector-step-btn.is-text {
  width: auto;
  padding: 0 8px;
  font-size: 11.5px;
}

/* Inspector 卡内 grid 按钮组 */
.inspector-card-grid {
  display: grid;
  gap: 4px;
  margin-top: 6px;
}
.inspector-card-grid-3 { grid-template-columns: repeat(3, 1fr); }
.inspector-card-grid-strike { grid-template-columns: repeat(3, 1fr); }

.inspector-grid-btn {
  padding: 6px 8px;
  border-radius: var(--r-sm);
  border: 1px solid color-mix(in srgb, var(--ink-3) 25%, transparent);
  background: var(--bg-0);
  color: var(--ink-1);
  font-size: 12px;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease);
}
.inspector-grid-btn:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.inspector-grid-btn.note-tool { font-weight: 600; font-family: ui-monospace, monospace; }

/* 速度行：slider 占满，按钮在两侧 */
.inspector-row-speed { gap: 4px; }
.inspector-row-speed .slider-speed { flex: 1; }
.inspector-row-speed .inspector-value { flex: 0 0 36px; }

/* 缩放行同样 */
.inspector-row-zoom { gap: 4px; }
.inspector-row-zoom .slider-zoom { flex: 1; }

/* 渐进加速练习内容缩进进 inspector */
.inspector-card #practicePreview.inspector-practice-preview {
  margin-top: 8px;
  padding: 6px 8px;
  background: var(--bg-1);
  border-radius: var(--r-sm);
  font-size: 11px;
  color: var(--ink-2);
}

/* 分隔线 */
.inspector-divider {
  border: 0;
  border-top: 1px solid color-mix(in srgb, var(--ink-3) 20%, transparent);
  margin: 12px 0;
}

/* 数拍 checkbox 行（编辑器 + 练习页共用）。
   v11（2026-05-23）：input 强制 accent-color: var(--lh) 鼠尾草绿，跟练习页 .inspector-toggle
   的渐进加速 checkbox 统一——原状两边一个浏览器默认蓝、一个无样式，现在都是绿。 */
.inspector-toggle-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--ink-1);
  margin-top: 6px;
  cursor: pointer;
}
.inspector-toggle-row input { margin: 0; }
.inspector-toggle-row input[type="checkbox"] { accent-color: var(--lh); }

/* 编辑工具卡：原 header 文件 / 编辑菜单下沉到 inspector 后用紧凑按钮列表展示。 */
.inspector-tools-body { display: flex; flex-direction: column; gap: 10px; }
.inspector-tools-group { display: flex; flex-direction: column; gap: 4px; }
.inspector-tools-label { font-size: 11px; color: var(--ink-2); letter-spacing: 0.04em; text-transform: uppercase; }
.inspector-tools-row { display: flex; flex-wrap: wrap; gap: 6px; }
.inspector-tools-btn {
  font-size: 12px;
  padding: 6px 10px;
  border-radius: var(--r-sm, 6px);
  background: var(--bg-1);
  border: 1px solid color-mix(in srgb, var(--ink-3) 25%, transparent);
  color: var(--ink-1);
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.inspector-tools-btn:hover {
  background: var(--bg-2);
  border-color: color-mix(in srgb, var(--ink-3) 50%, transparent);
  color: var(--ink-0);
}
.inspector-tools-btn-accent {
  background: var(--accent-soft, color-mix(in srgb, var(--accent) 15%, var(--bg-0)));
  border-color: color-mix(in srgb, var(--accent) 30%, transparent);
  color: var(--accent);
}
.inspector-tools-btn-accent:hover {
  background: color-mix(in srgb, var(--accent) 20%, var(--bg-0));
  color: var(--accent);
}
/* 循环 active 态：editor.js updateLoopBtnState() 给 #btnLoop 加 .is-active；
   inspector 内 loop 按钮复用 inspector-tools-btn 视觉，仅 active 时换 accent。 */
.inspector-tools-btn.is-active,
.inspector-tools-btn.is-active:hover {
  background: var(--accent-soft, color-mix(in srgb, var(--accent) 15%, var(--bg-0)));
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
  color: var(--accent);
}
.inspector-tools-label-btn { display: inline-flex; align-items: center; }

/* practice-toggle / practice-row 在 inspector 内紧凑化 */
.inspector-card .practice-toggle {
  display: flex; gap: 8px; cursor: pointer; padding: 4px 0;
}
.inspector-card .practice-toggle-text strong {
  display: block; font-size: 12.5px; color: var(--ink-0);
}
.inspector-card .practice-toggle-text small {
  display: block; font-size: 11px; color: var(--ink-2);
}
.inspector-card .practice-row {
  display: flex; align-items: center; gap: 6px; margin-top: 6px;
  font-size: 11.5px;
}
.inspector-card .practice-row-label { flex: 0 0 64px; color: var(--ink-2); }
.inspector-card .slider-practice { flex: 1; }
.inspector-card .practice-row-value { flex: 0 0 36px; text-align: right; color: var(--ink-1); }

