/* [timeline.css] source: Pro.html lines 261-368, 565-620 (verbatim; responsive block must stay last) */
/* ---------- 时间线 ---------- */
/* 工具行（批 C 后补）：分组 + 统一 28px。
   28 不是一个新 token 档 —— 只在 .stageTop 作用域内把 --h/--h-sm 降到 28，
   于是行内所有控件（按钮 / 下拉 / 数字框 / 小方块按钮）自动统一到 28，且不动全局 3 档阶梯。
   分组靠 index.html 里的 .vsep 竖线：行内 gap 4px + 竖线自身 1px + 两侧各 4px = 组间视觉 8px。 */
.stageTop{--h:28px;--h-sm:28px;
  display:flex;align-items:center;gap:4px;padding:10px 16px 8px;border-bottom:1px solid var(--line);flex-wrap:wrap}
.stageTop .t1{font-size:12px;color:var(--mut);margin-right:auto;display:flex;gap:8px;align-items:center}
.vsep{flex:none;width:1px;height:24px;background:var(--hair-2);margin:0 4px}
.keyChip{font-size:11px;color:var(--acc);border:1px solid rgba(var(--acc-rgb),.4);padding:3px 9px;border-radius:20px;
  background:rgba(var(--acc-rgb),.08)}
.timeline{flex:1;overflow:auto;position:relative;background:
  linear-gradient(180deg,rgba(var(--txt-rgb),.02),transparent 40%),
  repeating-linear-gradient(0deg,rgba(var(--txt-rgb),.02) 0 1px,transparent 1px 3px);min-height:0}
.tlInner{padding:8px 16px 12px;min-width:min-content}.emptyTip{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;color:var(--dim);pointer-events:none;text-align:center}
/* 空态图标：尺寸与图标本体在 layout.css 的 .emptyTip .big（mask 图标）里 —— 原 font-size:52px 会覆盖
   layout.css 的 font-size:0 把 emoji 放出来，且 drop-shadow 属批 1 已废弃的辉光，故整条移除 */
.emptyTip b{color:var(--mut);font-size:15px}
.hint{font-size:12px;color:var(--dim);line-height:1.9}

/* ruler */
/* ruler：吸顶，不随编辑区上下滚动；左侧空白格随左侧名称列一起冻结 */
.ruler{display:grid;height:26px;border-radius:var(--r-xs);margin-bottom:2px;
  position:sticky;top:0;z-index:6;background:var(--ctl-bg);
  box-shadow:0 6px 10px -6px rgba(var(--bg0-rgb),.7)}
.ruler .rl{background:var(--ctl-bg2);color:var(--acc);font-size:11px;font-weight:700;font-family:var(--mono);
  display:flex;align-items:center;justify-content:center;border-right:1px solid var(--line);
  position:sticky;left:0;z-index:7;border-radius:var(--r-xs) 0 0 var(--r-xs)}
.ruler .rs{background:transparent}
.ruler .rs.bar{background:var(--ctl-bg);border-top:2px solid var(--acc3);border-right:1px solid var(--line);
  color:var(--ruler-bar-tx);
  font:600 9.5px var(--mono);display:flex;align-items:flex-start;justify-content:center;padding-top:1px}
/* 小节号左移到"小节线居中"：位移量由 JS 直接写死成像素（原来写的是 calc(var(--cw)/-2 + 2px)）。
   为什么不再用 --cw：--cw 定义在 #tlInner 上，被它引用的规则会让整棵时间线子树参与
   "自定义属性变更 → 样式失效重算"，主页面 2.2 万元素下改一次 --cw 要 800–900ms。
   小节号只是几十个元素，逐格写一个 px 变量远比整片重算便宜。 */
.ruler .rs.bar span{transform:translateX(var(--barTx,0px))}
.ruler .rs.beat{background:rgba(var(--txt-rgb),.04);border-right:1px solid var(--line);box-shadow:inset 0 -3px 0 rgba(var(--acc-rgb),.16)}
.ruler .rs.plain{background:transparent;border-right:1px solid var(--grid-line2)}
/* 打点：bar 显示小节号 */

/* 轨组：去掉 overflow:hidden，否则内部 sticky（左侧名称列/吸顶表头）会失效 */
/* 顶亮底暗的渐隐描边（::before 画 1px 渐变边，避免 border 在圆角处过重） */
.tgroup{display:flex;margin-bottom:8px;border-radius:var(--r);background:var(--card);
  border:1px solid transparent;background-clip:padding-box;position:relative;box-shadow:var(--shadow-1),var(--glow)}
.tgroup::before,.insBox::before{content:'';position:absolute;inset:0;border-radius:inherit;padding:1px;
  background:linear-gradient(180deg,var(--edging),rgba(var(--line-rgb),.85));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask-composite:exclude;pointer-events:none;z-index:1}
.tgColor{width:4px;flex:none;border-radius:var(--r) 0 0 var(--r);position:sticky;left:0;z-index:5}
.tgMain{flex:1;min-width:0;border-radius:0 var(--r) var(--r) 0}
.thead{height:34px;display:flex;align-items:center;gap:8px;padding:0 8px 0 10px;cursor:pointer;user-select:none;
  border-bottom:1px solid var(--line);border-radius:0 var(--r) 0 0;
  background-color:var(--card);background-image:linear-gradient(180deg,rgba(var(--txt-rgb),.05),transparent);
  position:sticky;top:28px;z-index:4}
.thead.sel{background-color:var(--sel-bg);background-image:linear-gradient(180deg,rgba(var(--acc-rgb),.12),transparent)}
/* 表头左侧信息（折叠键/图标/名称/角色/编号）：横向冻结，右侧控件仍随内容滚动 */
.theadLeft{display:flex;align-items:center;gap:8px;position:sticky;left:0;z-index:2;
  background-color:var(--card);box-shadow:var(--scroll-sh)}
.thead.sel .theadLeft{background-color:var(--sel-bg)}
.tgIcon{width:22px;height:22px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;font-size:11px;flex:none}
.roleTag{font-size:10px;padding:2px 7px;border-radius:20px;flex:none;letter-spacing:.5px;border:1px solid}
/* 轨道名输入：与 .numInp/.seedRow input 同一套（32 高 / --ctl-bg2 底 / --hair-2 边 / focus 内环） */
.tname{background:var(--ctl-bg2);border:1px solid var(--hair-2);color:var(--txt);font-size:var(--fs-body);font-weight:600;width:120px;height:var(--h);padding:0 7px;
  border-radius:var(--r-xs);outline:none;transition:background-color var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out),box-shadow var(--dur-fast) var(--ease-out)}
.tname:hover{border-color:var(--sig)}
.tname:focus{background:var(--ctl-bg2);border-color:var(--sig);box-shadow:inset 0 0 0 2px rgba(var(--acc-rgb),.35)}
.hchip{height:var(--h-sm);min-width:var(--h-sm);padding:0 7px;font-size:var(--fs-label);border-radius:var(--r-xs);border:1px solid var(--hair-2);background:var(--ctl-bg);
  color:var(--mut);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:2px;flex:none;
  transition:background-color var(--dur-fast) var(--ease-out),border-color var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out),box-shadow var(--dur-fast) var(--ease-out)}
.hchip:hover{border-color:var(--sig);color:var(--txt);background:var(--hover)}
.hchip.on{background:var(--warn);color:var(--on-acc);border-color:var(--warn)}
.hchip.solo.on{background:var(--good);color:var(--on-acc);border-color:var(--good)}
.hchip:disabled{opacity:.35}
.tgVol{width:64px}
.tgShift{display:flex;gap:2px;align-items:center;flex:none}
.tgShift .sc{height:21px;min-width:21px;padding:0 3px;font-size:10px}
.tgShift .octv{font:600 10px var(--mono);color:var(--acc);min-width:24px;text-align:center}
.tgFill{margin-left:auto;display:flex;align-items:center;gap:5px;flex:none}
.collapse{transform:rotate(0);transition:transform var(--dur-base) var(--ease-in-out)}
.tgroup.closed .collapse{transform:rotate(-90deg)}
.tgBody{padding:2px 0 6px}
.tgroup.closed .tgBody{display:none}

/* 行与格 */
.row{display:grid;align-items:center}
/* 左侧音符/鼓组名称列：横向冻结（不随音轨左右滚动），方便对照 */
.lab{height:100%;display:flex;align-items:center;justify-content:flex-end;gap:3px;padding-right:8px;
  font:600 9.5px var(--mono);color:var(--mut);white-space:nowrap;border-bottom:1px solid var(--grid-line);user-select:none;cursor:pointer;
  position:sticky;left:4px;z-index:3;background:var(--card);box-shadow:var(--scroll-sh)}
.lab:hover{color:var(--acc)}
.lab.root{color:var(--lab-root)}
.lab.off{color:var(--dim)}
.lab .fl{color:var(--dim)}
/* 网格格：底色一律由 --txt-rgb 的半透明罩叠在 --card 上派生 → 浅色主题自动反转。
   （FEAT-V6/T4：原为 color-mix(in srgb,var(--txt) N%, var(--card))，1.2 万格逐格做混色，
     切主题时同步重算 515ms；改成 rgba(var(--txt-rgb),N) 后为零计算。） */
.pc{height:100%;position:relative;border-right:1px solid var(--grid-line);border-bottom:1px solid var(--grid-line);cursor:crosshair;transition:background-color var(--dur-instant) var(--ease-out)}
.mel .pc{background:rgba(var(--txt-rgb),.03)}
.mel .pc.beat{background:rgba(var(--txt-rgb),.07)}
.mel .pc.bar{background:rgba(var(--txt-rgb),.11)}
.drum .pc{background:rgba(var(--txt-rgb),.04)}
.drum .pc.beat{background:rgba(var(--txt-rgb),.09)}
.drum .pc.bar{background:rgba(var(--txt-rgb),.14)}
.pc:hover{box-shadow:inset 0 0 0 1px rgba(var(--txt-rgb),.3)}
/* 音符格：直接用轨道色（原来再和 --card 混 8%，但 --tc 是 JS 注入的每轨色，
   混色会让每格依赖主题变量 → 切主题时全部失效重算）。视觉差异 8%，用 inset 描边补偿。 */
.pc.on{background:var(--tc);box-shadow:var(--cell-shadow)}
/* 拍/小节线的底色规则权重更高（.mel .pc.beat = 3 类），这里补同权重的音符色，
   否则拍线上的音符会被网格底色盖掉（主题派生色也一并生效） */
.mel .pc.on,.drum .pc.on{background:var(--tc)}
.pc.on.velH{filter:brightness(1.25);
  box-shadow:inset 0 0 8px rgba(var(--txt-rgb),.45),inset 0 0 0 1px rgba(var(--txt-rgb),.4)}
/* 正在播放的那一格：原来是 filter:brightness 闪（每帧重绘整格），改成 opacity 呼吸 —— 合成层动画，几乎零成本 */
.pc.on.playing{animation:blink var(--dur-fast) var(--ease-in-out) infinite alternate}
@keyframes blink{from{opacity:1}to{opacity:.62}}
.pc.playCol{outline:1px solid rgba(var(--txt-rgb),.55);outline-offset:-1px;z-index:2}
.melRowH{height:16px}
.melRows{padding:4px 0}
.drumRowH{height:24px}

/* ---- 升降号（acc ♯ / ♭）：格子右上角标记 + 轻度描边 + 焦点格；行标签灰字提示 ---- */
/* ♯/♭ 画在 ::before（.pc::before 此前无人用；.pc.tribar::after 是节奏细分标记，两者互不干扰） */
.pc.accUp::before,.pc.accDn::before{content:'';position:absolute;top:0;right:1px;font:700 9px/1.05 var(--mono);
  pointer-events:none;user-select:none}
.pc.accUp::before{content:'♯'}
.pc.accDn::before{content:'♭'}
.pc.on.accUp::before,.pc.on.accDn::before{color:rgba(0,0,0,.72)}      /* 音符格是亮色轨道色 → 用深字 */
.pc:not(.on).accUp::before,.pc:not(.on).accDn::before{color:var(--txt);opacity:.45}
/* 轻度染色：走 inset 描边，不用 background（避免与 .mel .pc.on 的轨道色权重打架） */
.pc.accUp,.pc.accDn{box-shadow:inset 0 0 0 1px rgba(var(--txt-rgb),.42)}
.pc.on.accUp,.pc.on.accDn{box-shadow:inset 0 0 0 1px rgba(0,0,0,.4),inset 0 0 10px rgba(0,0,0,.16)}
/* 焦点格 = 最近点中的那一格（Shift+↑/↓ 的作用目标）；用外环，与 .pc.playCol 的内环不同层 */
.pc.accFocus{outline:2px solid var(--ring);outline-offset:-2px;z-index:3}
/* 行标签上的升降提示：基础音名不变，只补一个灰色小记号（该行有音高被升降过） */
.lab .accHint{color:var(--dim);font-size:8px;font-family:var(--mono)}

/* ---- 右键菜单（升降号的兜底入口）：容器运行时创建，条目复用 layout.css 的 .mi ---- */
.pcMenu{position:fixed;left:0;top:0;z-index:260;min-width:186px;background:var(--ctl-bg);border:1px solid var(--line2);
  border-radius:var(--r);padding:6px;box-shadow:var(--shadow-2),var(--glow);display:none;opacity:0;transform:scale(.97);
  transform-origin:top left;transition:opacity var(--dur-fast) var(--ease-out),transform var(--dur-fast) var(--ease-out)}
.pcMenu.open{display:block;opacity:1;transform:none}
@starting-style{.pcMenu.open{opacity:0;transform:scale(.97)}}
.pcMenuHd{padding:5px 10px 6px;font:600 10px var(--mono);color:var(--dim);letter-spacing:var(--ls-wide);white-space:nowrap}
.pcMenu .accGly{width:16px;flex:none;text-align:center;font:700 12px var(--mono);color:var(--mut)}
.pcMenu .mi:hover .accGly{color:var(--txt)}
.pcMenu .pcSep{height:1px;background:var(--line2);margin:5px 4px}

/* 演奏中的小节光柱由 .playCol 控制 */

/* ---- 窗口适配 / 响应式 ---- */
.side.hidden{display:none}
.topbar{flex-wrap:wrap;height:auto;min-height:52px;padding:6px 12px;row-gap:6px}
.stageTop{flex-wrap:wrap}
@media (max-width:1280px){
  .brand b{display:none}
  .knobGrp .rangeW{width:88px}
}
@media (max-width:1080px){
  .side{width:300px}
  .vizBox{display:none}
  .metroBtn span,.loopSpan{display:none}
}
@media (max-width:860px){
  .side{width:270px}
  .acts{gap:5px}
  .btn{padding:0 9px}
  .seekLbl{min-width:78px;font-size:10px}
  .pinfo{gap:8px;font-size:10px}
}
@media (max-width:720px){
  .wrap{flex-direction:column}
  /* 窄屏同样保持"浮动覆盖"语义：从右侧滑出，宽度按视口收缩（不再是 46vh 的底栏，那与覆盖层语义冲突） */
  .side{width:min(88vw,300px);height:auto;top:0;bottom:0;left:auto;margin-top:0;
    border-left:1px solid var(--line);border-top:none}
  .sideBody{min-height:0}
  .topbar .brand{min-width:0}
  .pc{touch-action:none}
  .seekBar{padding:6px 10px 4px;gap:8px}
  .seekLbl{min-width:70px}
  .tabs button{padding:7px 10px;font-size:12px}
  .panel{padding:10px}
  .miniSel{height:var(--h);font-size:13px}
  .btn{min-height:var(--h-lg);font-size:13px}
  .acts{flex-wrap:wrap}
  .stageRowLbl{min-width:38px}
  .knobGrp{flex-wrap:wrap}
  .keyBar{gap:4px}
  .seqTabs{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .seqTabs::-webkit-scrollbar{display:none}
  .pinfo{flex-wrap:wrap}
  .helpLine{flex-wrap:wrap}
  .aiChipRow{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .aiChipRow::-webkit-scrollbar{display:none}
}
@media (max-width:480px){
  .wrap{padding:0}
  .stageBody{margin:0 2px}
  .labelCol{min-width:44px}
  .pianoRow .key{min-width:16px}
  .colHdr{font-size:9px}
  .logo{display:none}
  .badge{display:none}
  .miniLbl{display:none}
  .rangeW{flex:1;min-width:70px}
  .side{height:50vh}
}
