/* Piano Key Viewer 样式表（拆分自 index.html 内联 <style>，纯搬运零改动） */
  :root {
    --bg: #0e1316;
    --panel: #161d21;
    --panel-2: #1b2429;
    --line: #263238;
    --text: #e6edf1;
    --text-dim: #93a1ab;
    --accent: #2dd4a7;
    --accent-bright: #7ff0c6;
    --danger: #f87171;
    --warn: #fbbf24;
    --kb-h: clamp(200px, 34vh, 330px);
  }
  * { box-sizing: border-box; margin: 0; padding: 0; }
  html, body { height: 100%; }
  body {
    background: radial-gradient(1200px 600px at 50% -10%, #1a2b31 0%, var(--bg) 55%);
    color: var(--text);
    font-family: system-ui, -apple-system, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;
    display: flex;
    flex-direction: column;
    padding: 18px 22px 22px;
    gap: 14px;
    min-width: 720px;
  }

  /* ===== 顶栏 ===== */
  header.app-header { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
  .brand h1 { font-size: 20px; font-weight: 700; letter-spacing: .3px; }
  .brand h1 em { font-style: normal; color: var(--accent); }
  .brand p { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
  .status-pill {
    display: inline-flex; align-items: center; gap: 8px;
    font-size: 12.5px; padding: 7px 14px; border-radius: 999px;
    background: var(--panel); border: 1px solid var(--line); white-space: nowrap;
  }
  .status-pill .dot { width: 9px; height: 9px; border-radius: 50%; background: #54626b; }
  .status-pill.ok .dot { background: var(--accent); box-shadow: 0 0 8px var(--accent); }
  .status-pill.warn .dot { background: var(--warn); box-shadow: 0 0 8px var(--warn); }
  .status-pill.err .dot { background: var(--danger); box-shadow: 0 0 8px var(--danger); }

  /* ===== 控制面板 ===== */
  .panel {
    display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
    background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
    padding: 10px 14px;
  }
  .ctrl-group { display: flex; align-items: center; gap: 8px; }
  .ctrl-label { font-size: 12px; color: var(--text-dim); }
  .range-btn {
    appearance: none; border: 1px solid var(--line); background: var(--panel-2);
    color: var(--text-dim); font-size: 12.5px; padding: 5px 12px; border-radius: 8px;
    cursor: pointer; transition: all .15s; white-space: nowrap;
  }
  a.range-btn { text-decoration: none; display: inline-block; }   /* 锚点按钮（返回主页） */
  .range-btn:hover { color: var(--text); border-color: #3a4a53; }
  .range-btn.active { background: rgba(45, 212, 167, .14); border-color: var(--accent); color: var(--accent-bright); }
  .range-btn.danger { background: rgba(248, 113, 113, .16); border-color: #f87171; color: #fca5a5; }
  .range-btn.danger:hover { color: #fecaca; border-color: #fca5a5; }
  .range-btn:disabled { opacity: .45; cursor: not-allowed; }
  .range-btn:disabled:hover { color: var(--text-dim); border-color: var(--line); }
  .rec-info { font-size: 12.5px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
  .rec-info.recording { color: #fca5a5; }
  .pedal { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--text-dim); }
  .pedal .dot { width: 10px; height: 10px; border-radius: 50%; background: #3a4249; transition: all .15s; }
  .pedal.on .dot { background: var(--accent); box-shadow: 0 0 10px var(--accent); }
  .pedal.on { color: var(--accent-bright); }
  .stat { font-size: 12.5px; color: var(--text-dim); margin-left: auto; }
  .stat b { color: var(--accent-bright); font-variant-numeric: tabular-nums; }

  details.devices { position: relative; font-size: 12.5px; }
  details.devices summary { cursor: pointer; color: var(--text-dim); user-select: none; }
  details.devices summary:hover { color: var(--text); }
  details.devices .device-box {
    position: absolute; right: 0; top: calc(100% + 8px); z-index: 20;
    min-width: 320px; max-width: 460px; max-height: 260px; overflow: auto;
    background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px;
    padding: 10px; box-shadow: 0 12px 30px rgba(0,0,0,.45);
    display: flex; flex-direction: column; gap: 6px;
  }
  .device-row { display: flex; align-items: center; gap: 8px; padding: 5px 8px; border-radius: 8px; }
  .device-row:hover { background: rgba(255,255,255,.04); }
  .device-row input { accent-color: var(--accent); }
  .device-row .d-name { flex: 1; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .device-row .d-manu { font-size: 11px; color: var(--text-dim); }
  .device-row .d-state { font-size: 11px; color: var(--text-dim); }
  .device-row .d-state.on { color: var(--accent-bright); }
  .device-empty { color: var(--text-dim); padding: 8px; }

  /* ===== 键盘 ===== */
  .kb-wrap { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 14px; }
  .kb-scroll { overflow-x: auto; }
  #keyboard {
    position: relative; height: var(--kb-h); min-width: 900px;
    user-select: none; -webkit-user-select: none; touch-action: none;
    border-radius: 8px; overflow: hidden;
    background: #0a0e10;
  }
  .key { position: absolute; top: 0; cursor: pointer; }
  .key.white {
    height: 100%;
    background: linear-gradient(180deg, #fbfcfd 0%, #f1f4f6 60%, #e3e9ec 100%);
    border-right: 1px solid #c3ccd2;
    border-radius: 0 0 5px 5px;
    box-shadow: inset 0 -6px 10px rgba(0,0,0,.06);
    transition: background .06s linear;
  }
  .key.black {
    height: 62%; z-index: 2;
    background: linear-gradient(180deg, #454f56 0%, #232a2f 70%, #14191d 100%);
    border-radius: 0 0 4px 4px;
    box-shadow: 0 4px 8px rgba(0,0,0,.5), inset 0 -3px 4px rgba(0,0,0,.4);
    transition: background .06s linear;
  }
  /* 按下高亮：力度映射颜色深浅（0.0 浅 → 1.0 深） */
  .key.white.active {
    background: linear-gradient(180deg, #8ff5cd 0%, hsl(163 76% calc(66% - var(--vel, .5) * 24%)) 100%);
    box-shadow: 0 0 18px rgba(45, 212, 167, .6), inset 0 -4px 8px rgba(0, 80, 60, .25);
  }
  .key.black.active {
    background: linear-gradient(180deg, hsl(163 62% calc(36% + var(--vel, .5) * 22%)) 0%, #0f3d2c 100%);
    box-shadow: 0 0 16px rgba(45, 212, 167, .65);
  }
  /* 延音踏板踩下时松键的半亮状态 */
  .key.white.sustained { background: linear-gradient(180deg, #d9f7ec 0%, #bdeadd 100%); }
  .key.black.sustained { background: linear-gradient(180deg, #2c4a40 0%, #1b3329 100%); }
  /* 键名徽标（按下时显示） */
  .key.active::after {
    content: attr(data-name);
    position: absolute; top: 5px; left: 50%; transform: translateX(-50%);
    font-size: 10px; font-weight: 700; color: #0b3b2e; white-space: nowrap;
    pointer-events: none; letter-spacing: .3px;
  }
  .key.black.active::after { color: #d9fff1; font-size: 9px; top: 3px; }
  .key-label {
    position: absolute; bottom: 5px; left: 0; right: 0; text-align: center;
    font-size: 9.5px; color: #9aa6ae; pointer-events: none; font-weight: 600;
  }
  .key.black .key-label { color: #5f6b73; }

  /* ===== 底部信息 ===== */
  .bottom { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
  .chord-box { display: inline-flex; align-items: center; gap: 8px; min-width: 170px; }
  .chord-name { font-size: 16px; font-weight: 700; color: var(--accent-bright); font-variant-numeric: tabular-nums; }
  .chord-notes { font-size: 11px; color: var(--text-dim); max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .vel-box { display: inline-flex; align-items: center; gap: 8px; }
  .vel-readout { font-size: 13px; color: var(--text); font-variant-numeric: tabular-nums; }
  .recent-title { font-size: 12px; color: var(--text-dim); }
  #recent-list { display: flex; gap: 6px; flex-wrap: wrap; }
  .chip {
    font-size: 11.5px; font-variant-numeric: tabular-nums;
    padding: 3px 9px; border-radius: 999px;
    background: rgba(45, 212, 167, .1); color: var(--accent-bright);
    border: 1px solid rgba(45, 212, 167, .28);
    transition: opacity .4s;
  }
  .hint { font-size: 11.5px; color: var(--text-dim); margin-left: auto; }

  /* ===== MIDI 调试面板 ===== */
  .dbg-panel {
    display: none; flex-direction: column; gap: 12px;
    background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
    padding: 14px;
  }
  .dbg-panel.open { display: flex; }
  .dbg-title { font-size: 12px; color: var(--text-dim); letter-spacing: .5px; font-weight: 600; }
  .dbg-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 8px; }
  .dbg-kv { background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; font-size: 12px; }
  .dbg-kv .k { display: block; font-size: 11px; color: var(--text-dim); margin-bottom: 2px; }
  .dbg-kv .v { color: var(--text); font-variant-numeric: tabular-nums; }
  .dbg-kv .v.ok { color: var(--accent-bright); }
  .dbg-kv .v.bad { color: var(--danger); }
  .dbg-table { width: 100%; border-collapse: collapse; font-size: 12px; }
  .dbg-table th { text-align: left; font-weight: 600; color: var(--text-dim); padding: 6px 10px; border-bottom: 1px solid var(--line); }
  .dbg-table td { padding: 6px 10px; border-bottom: 1px solid rgba(38, 50, 56, .55); font-variant-numeric: tabular-nums; }
  .dbg-table tr:last-child td { border-bottom: none; }
  .dbg-tag { display: inline-block; padding: 1px 7px; border-radius: 999px; font-size: 10.5px; font-weight: 700; }
  .dbg-tag.in { background: rgba(45, 212, 167, .15); color: var(--accent-bright); }
  .dbg-tag.out { background: rgba(251, 191, 36, .14); color: var(--warn); }
  .dbg-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 6px; }
  .dbg-dot.on { background: var(--accent); box-shadow: 0 0 6px var(--accent); }
  .dbg-dot.off { background: #54626b; }
  .dbg-dim { color: var(--text-dim); }
  .dbg-num { color: var(--accent-bright); }
  .dbg-test { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .dbg-test select {
    appearance: none; background: var(--panel-2); color: var(--text);
    border: 1px solid var(--line); border-radius: 8px; padding: 5px 10px; font-size: 12px;
  }
  .dbg-test select:disabled { opacity: .5; }
  .dbg-toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .dbg-log {
    height: 190px; overflow-y: auto;
    background: #0a0e10; border: 1px solid var(--line); border-radius: 10px;
    padding: 8px 10px; display: flex; flex-direction: column; gap: 3px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11.5px;
  }
  .dlog-row { display: flex; gap: 10px; align-items: baseline; white-space: nowrap; flex-shrink: 0; }
  .dlog-t { color: #5f6b73; }
  .dlog-dev { color: var(--text-dim); max-width: 150px; overflow: hidden; text-overflow: ellipsis; }
  .dlog-hex { font-weight: 600; }
  .dlog-info { color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; }
  .dlog-row.on .dlog-hex { color: var(--accent-bright); }
  .dlog-row.off .dlog-hex { color: #7c8a94; }
  .dlog-row.cc .dlog-hex { color: #7cc4f8; }
  .dlog-row.other .dlog-hex { color: var(--warn); }
  .dlog-empty { color: #5f6b73; font-style: italic; padding: 4px 2px; }

  /* ===== 跟练模式（音游式滚动态谱） ===== */
  .practice-bar { border-color: rgba(45, 212, 167, .35); background: linear-gradient(180deg, rgba(45, 212, 167, .07), var(--panel)); }
  .pract-select {
    appearance: none; background: var(--panel-2); color: var(--text);
    border: 1px solid var(--line); border-radius: 8px; padding: 5px 10px; font-size: 12.5px;
    cursor: pointer;
  }
  .pract-select:disabled { opacity: .5; cursor: not-allowed; }
  .rail-wrap {
    position: relative; height: 190px; min-width: 900px;
    background: linear-gradient(180deg, rgba(10, 14, 16, .92), rgba(10, 14, 16, .4) 72%, rgba(45, 212, 167, .08) 100%);
    border: 1px solid var(--line); border-bottom: none;
    border-radius: 10px 10px 0 0; overflow: hidden;
    margin-bottom: -1px;
  }
  .rail-wrap.hidden { display: none; }
  .rail-title {
    position: absolute; top: 8px; left: 10px; z-index: 3;
    font-size: 11px; color: var(--text-dim); letter-spacing: .5px;
    background: rgba(14, 19, 22, .6); padding: 2px 8px; border-radius: 6px; pointer-events: none;
  }
  .rnote {
    position: absolute; top: 0; z-index: 1;
    border-radius: 3px; pointer-events: none;
    opacity: .92; transition: opacity .25s;
    will-change: transform;
  }
  .rnote.white { background: linear-gradient(180deg, #c6f6e2, #6fd8ae); border: 1px solid rgba(45, 212, 167, .55); box-shadow: 0 0 6px rgba(45, 212, 167, .35); }
  .rnote.black { background: linear-gradient(180deg, #3a4a52, #151d21); border: 1px solid #5c707b; box-shadow: 0 0 6px rgba(140, 190, 205, .25); }
  .rnote.hit { box-shadow: 0 0 18px var(--accent-bright); opacity: 1; }
  .rnote.done { opacity: .06; }
  /* 左手伴奏轨道：蓝紫色调 + 半透明 + 描边更细，与右手绿色基调区分。
   * z-index 高于右手旋律，让左手音符视觉上"压"在右手上方。
   * 注意：左手伴奏没有唱名（视觉太乱），仅靠颜色区分。 */
  .rnote.rnote-bass {
    z-index: 2; opacity: .72; border-width: 1px; border-style: dashed;
  }
  .rnote.rnote-bass.white { background: linear-gradient(180deg, #d4d0ff, #7d6dd6); border-color: rgba(125, 109, 214, .65); box-shadow: 0 0 6px rgba(125, 109, 214, .4); }
  .rnote.rnote-bass.black { background: linear-gradient(180deg, #2d2548, #14102a); border-color: rgba(170, 156, 240, .55); box-shadow: 0 0 6px rgba(170, 156, 240, .35); }
  .rnote.rnote-bass.done { opacity: .05; }
  .rnote.rnote-bass.hit { box-shadow: 0 0 16px #a78bff; opacity: .9; }
  /* 滚动音符块内嵌简谱唱名（do/re/mi/.../ti）——居中底部对齐 */
  .rnote-solfege {
    position: absolute; left: 1px; right: 1px; bottom: 2px;
    text-align: center; line-height: 1;
    font-size: 9.5px; font-weight: 800; letter-spacing: 0;
    font-variant-numeric: tabular-nums;
    pointer-events: none; user-select: none;
    white-space: nowrap;
    padding: 1px 0; border-radius: 2px;
  }
  .rnote.white .rnote-solfege { color: #fff;}
  .rnote.black .rnote-solfege { color: #e8fff6; background: rgba(0, 0, 0, .28); }
  .rnote.hit .rnote-solfege { display: none; }   /* 命中瞬间隐藏，避免和 hit 发光抢视觉 */
  .rail-judge {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; height: 3px;
    background: linear-gradient(90deg, transparent, var(--accent) 20%, var(--accent-bright) 50%, var(--accent) 80%, transparent);
    box-shadow: 0 0 14px rgba(45, 212, 167, .8);
  }
  .rail-msg {
    position: absolute; left: 50%; top: 42%; transform: translate(-50%, -50%); z-index: 4;
    font-size: 30px; font-weight: 800; letter-spacing: 2px; pointer-events: none;
    text-shadow: 0 2px 14px rgba(0, 0, 0, .6); font-variant-numeric: tabular-nums;
  }
  .rail-msg.big { font-size: 40px; color: var(--accent-bright); }
  .rail-msg.good { color: #7ff0c6; }
  .rail-msg.ok { color: #7cc4f8; }
  .rail-msg.bad { color: var(--danger); }
  /* 下一个待按键的高亮提示（不覆盖按下高亮，用 outline） */
  .key.pract-next { outline: 2px solid var(--accent-bright); outline-offset: -2px; }
  /* 跟练模式 wait 状态：目标键额外高亮（闪动），提示"必须按这个音才会动"
  // 按用户反馈：去掉 box-shadow + 白键浅红背景，只保留 outline 脉冲，
  // 避免黑键看上去"变黑了"——边框（outline）足以传达提示。 */
  .key.follow-wait { animation: followWaitBlink .9s ease-in-out infinite; }
  @keyframes followWaitBlink {
    0%, 100% { outline-color: var(--danger); }
    50%      { outline-color: #ffb3b3; }
  }
  /* 白键 follow-wait：仅在原来 outline 基础上额外加 1px 内描边（白色），
  // 让浅色 outline 在白键上仍可见——避免"边框消失"。 */
  .key.white.follow-wait { box-shadow: inset 0 0 0 1px #fff; }
  /* 左手伴奏轨道的高亮：蓝色虚线 outline + 蓝色脉冲（区别于右手红色） */
  .key.pract-next-bass { outline: 2px solid #7d6dd6; outline-offset: -2px; outline-style: dashed; }
  .key.follow-wait-bass { animation: followWaitBlinkBass .9s ease-in-out infinite; }
  @keyframes followWaitBlinkBass {
    0%, 100% { outline-color: #4b39b8; }
    50%      { outline-color: #b8adff; }
  }
  .key.white.follow-wait-bass { box-shadow: inset 0 0 0 1px #fff; }
  .pract-result {
    position: fixed; inset: 0; z-index: 60;
    display: flex; align-items: center; justify-content: center;
    background: rgba(6, 10, 12, .66); backdrop-filter: blur(3px);
  }
  .pract-result.hidden { display: none; }
  .pract-result-card {
    width: min(420px, 92vw);
    background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
    padding: 26px 30px; text-align: center; box-shadow: 0 24px 60px rgba(0, 0, 0, .55);
    display: flex; flex-direction: column; gap: 12px; align-items: center;
  }
  .pract-result-card h2 { font-size: 20px; }
  .grade {
    width: 74px; height: 74px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    font-size: 38px; font-weight: 800; color: #06281d;
    background: linear-gradient(145deg, var(--accent-bright), var(--accent));
    box-shadow: 0 0 26px rgba(45, 212, 167, .55);
  }
  .pract-stats-line { display: flex; gap: 18px; font-size: 13px; color: var(--text-dim); }
  .pract-stats-line b { color: var(--accent-bright); }
  .pract-counts { display: flex; gap: 14px; font-size: 12.5px; }
  .pract-counts .c-good b { color: var(--accent-bright); }
  .pract-counts .c-ok b { color: #7cc4f8; }
  .pract-counts .c-bad b { color: var(--danger); }
  .pract-actions { display: flex; gap: 10px; margin-top: 6px; }

  /* ===== 视图切换 & 入口页 ===== */
  .hidden-view { display: none !important; }
  .entry-view {
    flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 30px; min-height: 44vh;
    container-type: inline-size;   /* 以可用宽度驱动入口卡片自适应列数 */
  }
  .entry-hero { text-align: center; }
  .entry-hero h2 { font-size: 30px; font-weight: 800; letter-spacing: .5px; }
  .entry-hero h2 em { font-style: normal; color: var(--accent); }
  .entry-hero p { color: var(--text-dim); margin-top: 10px; font-size: 13.5px; }
  /* 入口卡片：默认 1 列（每个独占一行）；容器 ≥560px 时 2 列（2×2）；
     容器 ≥1120px 时 4 张平分一行 */
  .entry-cards {
    display: grid; grid-template-columns: 1fr; gap: 22px; width: 100%;
  }
  .entry-card {
    width: auto; padding: 26px 24px 20px; border-radius: 16px; cursor: pointer;
    background: var(--panel); border: 1px solid var(--line);
    display: flex; flex-direction: column; gap: 10px; align-items: flex-start;
    transition: transform .15s, border-color .15s, box-shadow .15s;
  }
  .entry-card:hover {
    transform: translateY(-3px); border-color: var(--accent);
    box-shadow: 0 14px 34px rgba(0, 0, 0, .45);
  }
  .entry-card .ic { font-size: 30px; }
  .entry-card h3 { font-size: 17px; }
  .entry-card p { font-size: 12.5px; color: var(--text-dim); line-height: 1.65; }
  .entry-card .go { font-size: 12px; color: var(--accent-bright); margin-top: auto; }
  @container (min-width: 560px) {
    .entry-cards { grid-template-columns: repeat(2, 1fr); }
  }
  @container (min-width: 1120px) {
    .entry-cards { grid-template-columns: repeat(4, 1fr); }
  }

  /* ===== 识谱模式 ===== */
  .sight-panel { gap: 14px; }
  .sight-prompt {
    min-width: 230px; text-align: center; padding: 12px 26px; border-radius: 14px;
    background: var(--panel-2); border: 1px solid var(--line);
    display: flex; flex-direction: column; gap: 4px; align-items: center; justify-content: center;
    transition: border-color .15s, box-shadow .15s;
  }
  .sight-prompt .q { font-size: 40px; font-weight: 800; letter-spacing: 1px; font-variant-numeric: tabular-nums; }
  .sight-prompt .tip { font-size: 11.5px; color: var(--text-dim); }
  .sight-prompt.ok { border-color: var(--accent); box-shadow: 0 0 20px rgba(45, 212, 167, .25); }
  .sight-prompt.ok .q { color: var(--accent-bright); }
  .sight-prompt.bad { border-color: var(--danger); }
  .sight-prompt.bad .q { color: var(--danger); }
  .sight-options { display: flex; gap: 10px; flex-wrap: wrap; }
  .sight-opt { min-width: 88px; }
  .sight-opt.right { background: rgba(45, 212, 167, .16); border-color: var(--accent); color: var(--accent-bright); }
  .sight-opt.wrong { background: rgba(248, 113, 113, .16); border-color: var(--danger); color: #fca5a5; }
  .sight-fb { font-size: 13px; min-width: 160px; font-variant-numeric: tabular-nums; }
  .sight-fb.ok { color: var(--accent-bright); }
  .sight-fb.bad { color: var(--danger); }
  .key.sight-next { outline: 2px solid #7cc4f8; outline-offset: -2px; }

  /* ===== 识谱模式（五线谱） ===== */
  .sr-panel { gap: 14px; }
  .sr-stage {
    width: 100%; background: #0a0e10; border: 1px solid var(--line); border-radius: 10px;
    padding: 4px 12px 8px;
  }
  .staff-svg { display: block; width: 100%; height: auto; }
  .staff-svg .st-line { stroke: #93a1ab; stroke-width: 1.2; }
  .staff-svg .glyph { fill: #e6edf1; }
  .staff-svg .note { fill: #e6edf1; }
  .staff-svg .note.ghost { fill: #3a4a53; }
  .staff-svg .note.cur { fill: #0a0e10; stroke: var(--accent-bright); stroke-width: 2.2; }
  .staff-svg .note.new { fill: var(--accent-bright); }
  .staff-svg .note.ok { fill: #97c459; }
  .staff-svg .note.bad { fill: var(--danger); }
  .staff-svg .stem { stroke: #e6edf1; stroke-width: 1.6; }
  .staff-svg .stem.ghost { stroke: #3a4a53; }
  .staff-svg .stem.cur { stroke: var(--accent-bright); stroke-width: 2.2; }
  .staff-svg .stem.new { stroke: var(--accent-bright); }
  .staff-svg .stem.ok { stroke: #97c459; }
  .staff-svg .stem.bad { stroke: var(--danger); }
  .staff-svg .acc { fill: #e6edf1; }
  .staff-svg .acc.ghost { fill: #3a4a53; }
  .staff-svg .acc.cur { fill: var(--accent-bright); }
  .staff-svg .acc.new { fill: var(--accent-bright); }
  .staff-svg .acc.ok { fill: #97c459; }
  .staff-svg .acc.bad { fill: var(--danger); }
  .staff-svg .sr-hint-text { fill: var(--accent-bright); font-size: 15px; font-weight: 700; }
  .staff-svg .sr-empty { fill: var(--text-dim); font-size: 13px; }
  .key.sr-next { outline: 2px solid var(--warn); outline-offset: -2px; }

  /* ===== 唱谱模式 ===== */
  .sg-label { transition: opacity .35s; }
  .sg-label.hidden-l { opacity: 0; }
  .staff-svg .sg-label rect {
    fill: rgba(45, 212, 167, .13); stroke: rgba(45, 212, 167, .5); stroke-width: 1;
  }
  .staff-svg .sg-label text { fill: var(--accent-bright); font-size: 13px; font-weight: 700; }
  .staff-svg .sg-label.cur rect { fill: rgba(45, 212, 167, .3); }
  /* 弹琴看唱名：按住的琴键以唱名替代音名显示 */
  #keyboard.sg-mode .key.active::after { content: attr(data-sol); font-size: 13px; top: 6px; }
  #keyboard.sg-mode .key.black.active::after { font-size: 10px; top: 4px; }

  /* ===== 错音热力图（结算弹窗内 mini 键盘） ===== */
  .hm-box { width: 100%; display: flex; flex-direction: column; gap: 8px; }
  .hm-title { font-size: 12px; color: var(--text-dim); }
  .hm-kb { position: relative; height: 46px; border-radius: 6px; overflow: hidden; background: #0a0e10; }
  .hm-key { position: absolute; top: 0; }
  .hm-key.white { height: 100%; background: #dfe6ea; border-right: 1px solid #b7c2c8; border-radius: 0 0 3px 3px; }
  .hm-key.black { height: 62%; z-index: 2; background: #2a3338; border-radius: 0 0 2px 2px; }
  .hm-key.err { display: flex; align-items: flex-end; justify-content: center; font-size: 9px; font-weight: 700; color: #fff; }
  .hm-legend { font-size: 11px; color: var(--text-dim); }

  /* ===== 录音对比 ===== */
  details.cmp-panel { padding: 0; }
  details.cmp-panel summary { cursor: pointer; padding: 10px 14px; color: var(--text-dim); user-select: none; font-size: 12.5px; }
  details.cmp-panel summary:hover { color: var(--text); }
  details.cmp-panel[open] summary { border-bottom: 1px solid var(--line); }
  .cmp-body { display: flex; flex-direction: column; gap: 10px; padding: 12px 14px; }
  .cmp-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12.5px; }
  .cmp-row .legend-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; }
  .cmp-canvas-wrap { width: 100%; }
  #cmp-canvas { width: 100%; height: 200px; background: #0a0e10; border: 1px solid var(--line); border-radius: 10px; display: block; }
  .cmp-stats { font-size: 12px; color: var(--text-dim); font-variant-numeric: tabular-nums; line-height: 1.7; }
  .cmp-stats b { color: var(--text); }

  /* ===== 提示横幅 ===== */
  .banner {
    position: fixed; left: 50%; top: 16px; transform: translateX(-50%); z-index: 50;
    max-width: 640px; width: calc(100% - 40px);
    background: #241a14; border: 1px solid #6b4423; color: #fdd7ad;
    font-size: 13px; line-height: 1.6;
    padding: 10px 38px 10px 14px; border-radius: 10px;
    box-shadow: 0 12px 30px rgba(0,0,0,.5);
  }
  .banner.hidden { display: none; }
  .banner b { color: #ffd9a8; }
  .banner code { background: rgba(255,255,255,.08); padding: 1px 5px; border-radius: 4px; font-size: 12px; }
  .banner-x {
    position: absolute; top: 4px; right: 6px;
    width: 24px; height: 24px;
    appearance: none; border: 0; background: transparent;
    color: #fdd7ad; font-size: 17px; line-height: 1;
    border-radius: 6px; cursor: pointer;
    transition: background .15s, color .15s;
  }
  .banner-x:hover { background: rgba(255, 216, 168, .14); color: #ffe9cf; }

  /* ===== 站点导航桥接（.nav 来自站点 css/style.css，随页面深色变量自动适配）=====
     body 有 18px/22px 内边距，负外边距让 sticky 导航贴边全宽 */
  .nav { margin: -18px -22px 4px; }
  .nav .nav-logo { font-size: 20px; }
