/* style.css — 简谱工坊 (亮色主题) */
:root{
  --bg:#f5f6f8;
  --panel:#ffffff;
  --border:#e3e6ea;
  --text:#2b2f36;
  --muted:#8a909a;
  --accent:#2f6df0;
  --accent-soft:#e8f0ff;
  --danger:#e0533d;
  --shadow:0 1px 3px rgba(0,0,0,.06),0 4px 12px rgba(0,0,0,.04);
}
*{box-sizing:border-box;margin:0;padding:0}
body{
  font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif;
  background:var(--bg);color:var(--text);height:100vh;display:flex;flex-direction:column;
  padding-bottom:52px;   /* 给底部固定走带栏留出空间,避免遮住内容 */
}

/* 顶栏 */
.topbar{
  display:flex;align-items:center;justify-content:space-between;
  padding:10px 18px;background:var(--panel);border-bottom:1px solid var(--border);
  box-shadow:var(--shadow);z-index:10;
}
.brand{display:flex;align-items:center;gap:8px}
.logo{font-size:22px;color:var(--accent)}
.title{font-size:17px;font-weight:600;letter-spacing:.5px}
.toolbar{display:flex;gap:8px}
.tb-btn{
  border:1px solid var(--border);background:#fff;color:var(--text);
  padding:7px 14px;border-radius:8px;font-size:13px;cursor:pointer;transition:.15s;
}
.tb-btn:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
.tb-danger:hover{border-color:var(--danger);color:var(--danger);background:#fdeceA}

/* 布局 */
.layout{flex:1;display:grid;grid-template-columns:230px 1fr 220px;gap:14px;padding:14px;overflow:hidden}
.panel{
  background:var(--panel);border:1px solid var(--border);border-radius:12px;
  padding:14px;box-shadow:var(--shadow);overflow-y:auto;
}
.panel-h{font-size:13px;color:var(--muted);font-weight:600;margin:14px 0 8px;
  text-transform:uppercase;letter-spacing:.5px}
.panel-h:first-child{margin-top:0}
.hint{font-size:12px;color:var(--muted);margin-bottom:10px;line-height:1.5}

.field{display:flex;flex-direction:column;gap:5px;margin-bottom:12px;font-size:13px}
.field span{color:var(--muted)}
.field input,.field select{
  border:1px solid var(--border);border-radius:7px;padding:7px 9px;font-size:13px;
  background:#fff;color:var(--text);
}
.field input:focus,.field select:focus{outline:none;border-color:var(--accent)}

/* 符号面板 */
.symbol-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
.sym{
  border:1px solid var(--border);border-radius:8px;padding:9px 6px;text-align:center;
  font-size:12px;cursor:grab;background:#fff;user-select:none;transition:.15s;line-height:1.4;
}
.sym:hover{border-color:var(--accent);background:var(--accent-soft);color:var(--accent)}
.sym:active{cursor:grabbing}
/* 当前画笔时值高亮 */
.sym.pen-active{
  border-color:var(--accent);background:var(--accent);color:#fff;font-weight:600;
  box-shadow:0 2px 6px rgba(47,109,240,.3);
}
.sym.pen-active:hover{color:#fff;background:var(--accent)}

/* 中间舞台 */
/* 中间舞台:上下分屏(上简谱 + 走带栏 + 下卷帘窗),各自可滚动 */
.stage{overflow:auto;display:flex;flex-direction:column;gap:10px;padding:10px;align-items:center}
/* 简谱纸:标准 A4 比例(210×297mm ≈ 794×1123px @96dpi),固定尺寸像真实纸张 */
/* #score 现在是"多页容器"(纯壳),内部由 render 生成一张或多张 .score A4 纸。 */
.score-pages{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:14px}
.stage > .score-pages > .score{flex:0 0 auto;overflow:visible}
.score{
  background:#fff;border:1px solid var(--border);border-radius:4px;
  box-shadow:var(--shadow);
  width:794px;height:1123px;max-width:100%;
  padding:48px 27px 40px;
}
/* 多页:每页都是一张独立 A4 纸,靠 .stage 的 gap 天然分隔;续页(第2页起)只有谱面无谱头。 */
.score-cont{margin-top:4px}
/* 谱头左右内缩 = 谱面小节线左边距 MARGIN_X(28px),让标题区与谱面严格左右对齐。 */
.score-meta{padding:0 28px;text-align:center;margin-bottom:32px}
.score-title{font-size:24px;font-weight:700;margin-bottom:8px}
/* 谱头两栏:左栏 = 调号/拍号 + 速度(纵向堆叠);右栏(右上角)= 作词/作曲/制谱。 */
.score-head{display:flex;justify-content:space-between;align-items:flex-start;
  font-size:15px;color:var(--text);font-weight:600}
.score-head-left{display:flex;flex-direction:column;gap:2px;text-align:left}
.score-head-right{display:flex;flex-direction:column;gap:2px;text-align:right;
  font-size:13px;font-weight:500}
.meta-key-time{font-weight:600}
/* 速度标记:列于调号/拍号下方一行(简谱惯例:速度紧挨拍号)。 */
.meta-tempo{font-weight:500;font-size:13px;color:var(--text)}
/* 表情/情绪/力度术语:标题区下方,左对齐,偏斜体(音乐术语惯例)。 */
.score-expr{text-align:left;font-style:italic;font-size:14px;color:var(--text);margin-top:4px}

/* ===== 坐标画布:所有元素绝对定位 ===== */
.canvas{position:relative;margin:0 auto}

/* —— 数字本体:固定等宽盒子,框只框它;默认无框,选中/悬停才浅色细框 ——
   宽度统一由 JS 按 CFG.NOTE_W 设定(不随 1/5/8 等字形宽度变化)。 */
.el-num{
  position:absolute;font-weight:500;line-height:1;
  display:flex;align-items:center;justify-content:center;  /* 数字在固定盒内居中 */
  text-align:center;cursor:pointer;
  border-radius:4px;
  border:1.5px solid transparent;   /* 占位,避免悬停时尺寸跳动 */
  box-sizing:border-box;
  transition:background .1s,border-color .1s;
}
.el-num:hover{background:var(--accent-soft);border-color:rgba(47,109,240,.35)}
.el-num.selected{background:var(--accent-soft);border-color:var(--accent)}
.el-num.drop-hover{background:#fff4d6;border-color:#f0a92f}
/* 播放中正在发声的音符:绿色高亮,区别于蓝色"选中"。播放头扫到哪就亮到哪。 */
.el-num.playing{background:#d8f5e0;border-color:#28a745;color:#1a7431}
/* 自动补拍的占位休止符:淡色、不可交互(提示"这里缺拍,输入即顶掉") */
.el-num.filler{color:#c2c7cf;cursor:pointer}
.el-num.filler:hover{background:var(--accent-soft);border-color:rgba(47,109,240,.25)}

/* —— 八度点:直径由 JS 按 OCT_DOT_R*2 动态设定 —— */
.el-octdot{position:absolute;border-radius:50%;background:var(--text)}

/* —— 升降号 —— */
.el-acc{position:absolute;font-size:12px;color:var(--text);line-height:1}

/* —— 附点(增时) —— */
.el-augdot{position:absolute;font-size:20px;line-height:0;color:var(--text)}

/* —— 减时线:一段贴音符下方的横线 —— */
.el-ul{position:absolute;height:1.5px;background:var(--text);border-radius:1px}

/* —— 增时线 "—" —— */
.el-dash{position:absolute;font-size:18px;line-height:1;color:var(--text);width:17px;text-align:center;display:flex;align-items:center;justify-content:center}

/* —— 小节线:细竖线,高度由 JS 设定。与音符严格共享基线 y,视觉居中。 —— */
.el-bar{
  position:absolute;width:1px;border-radius:0.5px;
  background:var(--muted);user-select:none;
}
.el-bar.auto{background:#c8ccd3}
.el-bar.edge{background:var(--text)}
/* 终止线/反复记号里的粗竖线 */
.el-bar.thick{width:3px;background:var(--text);border-radius:1px}
/* 反复记号的两个圆点 */
.el-repeat-dot{position:absolute;width:3px;height:3px;border-radius:50%;
  background:var(--text);transform:translate(-50%,-50%)}

/* —— 谱中拍号标记:分子/分母竖排(简谱惯例,无分数横线)。与音符共享基线 y —— */
.el-timesig{position:absolute;display:flex;flex-direction:column;align-items:center;
  justify-content:center;line-height:1;font-weight:700;color:var(--text);
  transform:translate(-50%,-50%)}
.el-timesig .ts-num{font-size:13px}
.el-timesig .ts-den{font-size:13px;margin-top:1px}

/* —— 歌词:一字一框,与音符同宽的稳定盒;空字也保持可点击命中区 —— */
.el-lyric{
  position:absolute;line-height:1.2;
  display:flex;align-items:center;justify-content:center;
  box-sizing:border-box;color:var(--text);cursor:text;
  border-radius:4px;
  border:1px solid transparent;
  transition:border-color .1s,background .1s;
}
.el-lyric:hover{border-color:rgba(47,109,240,.4);background:var(--accent-soft)}
/* 空歌词:盒子照样占位(JS 给定宽高),底部一条虚线提示"点这里填词" */
.el-lyric.empty{color:transparent}
.el-lyric.empty::after{
  content:"";position:absolute;left:50%;bottom:2px;transform:translateX(-50%);
  width:60%;border-bottom:1px dashed #c5cad2;
}
/* 歌词行内编辑框:与歌词框同位(transform 居中对齐 centerEl),自带文字光标、
   原生支持中文输入法。宽度略放宽以容纳整字与光标。 */
.el-lyric-input{
  position:absolute;transform:translate(-50%,-50%);
  width:22px;text-align:center;padding:0;line-height:1.2;
  border:1px solid var(--accent);border-radius:4px;
  background:#fff;color:var(--text);outline:none;
  box-sizing:border-box;
}

/* —— 光标 —— */
.el-cursor{
  position:absolute;width:2px;height:32px;background:var(--accent);
  animation:blink 1s step-start infinite;pointer-events:none;
}
@keyframes blink{50%{opacity:0}}

/* —— 连音线 / 延音线:覆盖全画布的 SVG 层(不拦截鼠标)—— */
.slur-layer{position:absolute;left:0;top:0;pointer-events:none;overflow:visible}
.slur-path{fill:none;stroke:var(--text);stroke-width:1.3;stroke-linecap:round}

/* 右栏键盘 */
.kbd-list{list-style:none;font-size:12.5px;line-height:2.1;color:var(--text)}
.kbd-list kbd{
  background:#f0f2f5;border:1px solid var(--border);border-bottom-width:2px;
  border-radius:5px;padding:1px 6px;font-size:11px;font-family:inherit;
}
.cur-info{font-size:12.5px;color:var(--text);background:#f7f8fa;border:1px solid var(--border);
  border-radius:8px;padding:10px;line-height:1.6;min-height:42px}

/* 状态栏 */
/* ===== 底部悬浮走带栏(Logic 风格,固定 bottom)===== */
/* 固定在视口底部,横跨整宽;各分组左中右排布。body 底部预留出它的高度。 */
.transport-bar{
  position:fixed;left:0;right:0;bottom:0;z-index:50;
  display:flex;align-items:center;gap:14px;
  height:52px;padding:0 16px;
  background:var(--panel);border-top:1px solid var(--border);
  box-shadow:0 -2px 10px rgba(0,0,0,.06);
}
.tp-group{display:flex;align-items:center;gap:8px}
/* 小节/拍导航居中,状态栏推到最右 */
.tp-readout{margin-left:8px}
.tp-status-wrap{margin-left:auto;color:var(--muted);font-size:12px;
  max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.tp-btn{
  border:1px solid var(--border);background:#fff;color:var(--text);
  padding:6px 12px;border-radius:7px;font-size:13px;cursor:pointer;transition:.15s;
}
.tp-btn:hover{border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
/* 圆形走带图标键(播放/停止/录制)——Logic 感 */
.tp-icon{
  width:34px;height:34px;padding:0;border-radius:50%;
  display:flex;align-items:center;justify-content:center;font-size:13px;line-height:1;
}
.tp-rec{color:var(--danger)}
/* 激活态:播放/节拍器蓝、录制红 */
.tp-btn.recording{border-color:var(--danger);background:var(--danger);color:#fff;font-weight:600}
.tp-btn.active{border-color:var(--accent);background:var(--accent);color:#fff;font-weight:600}
.tp-field{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--muted)}
.tp-field input{
  width:60px;border:1px solid var(--border);border-radius:6px;padding:5px 7px;
  font-size:13px;background:#fff;color:var(--text);
}
.tp-field input:focus{outline:none;border-color:var(--accent)}
/* 小节:拍 导航读数(等宽数字,像走带计数器) */
.tp-pos{font-size:15px;font-weight:700;color:var(--text);
  font-variant-numeric:tabular-nums;min-width:52px;text-align:center;
  background:#f7f8fa;border:1px solid var(--border);border-radius:7px;padding:4px 10px}
.tp-time{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums;min-width:36px}
.tp-oct{font-size:13px;color:var(--text);background:#f7f8fa;border:1px solid var(--border);
  border-radius:7px;padding:5px 10px;font-weight:600}

/* ===== 钢琴卷帘窗 ===== */
.pianoroll-wrap{
  flex:1 1 auto;overflow:auto;background:var(--panel);
  border:1px solid var(--border);border-radius:10px;box-shadow:var(--shadow);
}
.pianoroll{position:relative}
.pr-canvas{position:relative;background:#fff}
/* 泳道背景:交替底色便于读行 */
.pr-lane{position:absolute;background:#fff}
.pr-lane.alt{background:#f7f8fa}
/* 左侧音级标签 */
.pr-lane-label{
  position:absolute;display:flex;align-items:center;justify-content:center;
  font-size:12px;font-weight:600;color:var(--muted);
  background:#f0f2f5;border-right:1px solid var(--border);
}
/* 竖向网格:拍线细、小节线深 */
.pr-gridline{position:absolute;width:1px;background:#eceef1}
.pr-gridline.bar{background:#c8ccd3}
/* 音符块 */
.pr-note{
  position:absolute;display:flex;align-items:center;justify-content:center;
  background:var(--accent-soft);border:1px solid var(--accent);
  border-radius:4px;font-size:12px;font-weight:600;color:var(--accent);
  cursor:pointer;box-sizing:border-box;transform:translateX(0);
}
.pr-note:hover{background:#d7e6ff}
.pr-note.selected{background:var(--accent);color:#fff}
/* 音符块上的八度点 */
.pr-note-oct{position:absolute;border-radius:50%;background:var(--accent);
  transform:translate(-50%,-50%)}
/* 休止符:淡色横条 */
.pr-rest{position:absolute;height:2px;background:#c2c7cf;border-radius:1px}
/* 播放头 */
.pr-playhead{position:absolute;width:2px;background:var(--danger);pointer-events:none;z-index:5}

/* ===== 新版本提示条 ===== */
/* 检测到已部署新版本时从顶部滑入,提示测试人员刷新。固定顶部、居中、层级最高。 */
.update-toast{
  position:fixed;top:16px;left:50%;transform:translateX(-50%) translateY(-140%);
  z-index:200;display:flex;align-items:center;gap:14px;
  padding:10px 14px;border-radius:10px;
  background:var(--accent);color:#fff;font-size:13px;
  box-shadow:0 6px 24px rgba(47,109,240,.35);
  transition:transform .35s cubic-bezier(.2,.8,.2,1);
}
.update-toast.show{transform:translateX(-50%) translateY(0)}
.update-toast .ut-msg{font-weight:500}
.update-toast .ut-refresh{
  border:none;background:#fff;color:var(--accent);font-weight:600;
  padding:6px 14px;border-radius:7px;font-size:13px;cursor:pointer;
}
.update-toast .ut-refresh:hover{background:#eef3ff}
.update-toast .ut-close{
  border:none;background:transparent;color:#fff;opacity:.8;
  font-size:18px;line-height:1;cursor:pointer;padding:0 2px;
}
.update-toast .ut-close:hover{opacity:1}
