/* lab.css — /misc 杂物间: the hub page + the mixing desk. */
/* 杂物间各页的面板为 .surface-glass（ui.css），这里只写宽度与间距 */
.gm-card { z-index: 1; margin: 0 auto var(--gap-grid); max-width: var(--w-page); }
.gm-sub { margin: 0 0 10px; font: 700 13px/1.4 var(--font-display); color: var(--text2); letter-spacing: .04em; display: flex; align-items: baseline; gap: 8px; }
.gm-sub small { font: 11px/1.4 var(--font-sans); color: var(--text3); font-weight: 400; }
.gm-top { display: flex; align-items: center; gap: 14px; max-width: var(--w-page); margin: 18px auto var(--s-3); }
/* 与 .page-header 相同：页头标题到导航条的距离，桌面 28px、手机 18px */
@media (max-width: 600px) { .gm-top { margin-top: 6px; } }
/* 字号、字距、行高与 .page-header h1 一致（桌面 30px，手机 24px），保留返回钮与左对齐 */
.gm-top h1 { margin: 0; font: 700 30px/1.2 var(--font-display); letter-spacing: .06em; color: var(--text); flex: 1; }
@media (max-width: 600px) { .gm-top h1 { font-size: 24px; } }
/* 返回按钮为 .btn-outline.is-sm，特效开关为 .btn-icon（aria-pressed） */
.gm-top > .btn-icon[aria-pressed="false"] { opacity: .55; }
.gm-rules { max-width: var(--w-read); margin: 14px auto 0; font: 12px/1.7 var(--font-sans); color: var(--text3); }
.gm-rules p { margin: 0 0 4px; }

/* ── Hub ── */
.gm-hub { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: var(--gap-grid); max-width: var(--w-page); margin: 0 auto; }
.gm-tile { position: relative; display: flex; flex-direction: column; background: var(--l1-bg); border: var(--l1-border); border-radius: var(--r-panel); box-shadow: var(--l1-shadow); color: var(--text); text-decoration: none; transition: transform .2s, translate .2s, box-shadow var(--dur-base), border-color var(--dur-base); overflow: hidden; }/* Scoped to real cursors: on a touch screen :hover latches onto the last
   thing tapped and stays there until you tap something else, so a card you
   opened and closed sat there still lifted and glowing. Only the rules that
   move or light something up are guarded — a colour-only :hover latching is
   invisible, and wrapping those too would be 100+ rules of noise. */
@media (hover: hover) {

  /* The lift is written to the independent `translate` property, not to
     `transform`: these tiles carry [data-tilt], and tilt.js writes an inline
     `transform` that would win over this rule and eat the lift. `translate`
     composes with it, so a tilted tile is still a lifted tile. */
  a.gm-tile:hover { translate: 0 -3px; box-shadow: var(--card-shadow-hover); border-color: var(--border-hover); }
}
.gm-cover { position: relative; height: 150px; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.gm-tile-mixer .gm-cover { background: radial-gradient(circle at 30% 20%, #3a3a48, #17171c 70%); }
.gm-tile-room .gm-cover { background: linear-gradient(160deg, #ffd9a3, #ff9ccb 55%, #b28dff); }
[data-theme="dark"] .gm-tile-room .gm-cover { background: linear-gradient(160deg, #4a3140, #3d2650 55%, #241d4a); }
/* 浅色渐变封面上白色线稿对比度不足，取深蓝；深色主题的封面为深色渐变，回到白色 */
@media (hover: hover) {

  a.gm-tile:hover .disc-frost { transform: scale(1.08) rotate(-4deg); }
}
.gm-tile-gallery .gm-cover { background: radial-gradient(ellipse at 50% 120%, #4a3524, #16121a 65%); }
.gm-tile-blindbox .gm-cover { background: radial-gradient(circle at 50% 25%, #ffe3f1, #ffc6dd 45%, #b8a4ff 100%); }
[data-theme="dark"] .gm-tile-blindbox .gm-cover { background: radial-gradient(circle at 50% 25%, #4a2f52, #2a1c3a 60%, #171426); }
.gm-tile-fx .gm-cover { background: radial-gradient(circle at 50% 55%, #3b2f6e, #1b1836 55%, #0e0d1c 100%); }
.gm-tile-mc .gm-cover { background: linear-gradient(180deg, #8fd3ff 0%, #bfe8ff 55%, #6fbf3a 55%, #4c8f2a 100%); }
[data-theme="dark"] .gm-tile-mc .gm-cover { background: linear-gradient(180deg, #16223f 0%, #2a3f66 55%, #2f6b22 55%, #23501a 100%); }
.gm-body { flex: 1; display: flex; flex-direction: column; gap: 6px; padding: 16px 18px 16px; }
.gm-body b { font: 700 19px/1.3 var(--font-display); }
.gm-body small { font: 12px/1.7 var(--font-sans); color: var(--text3); text-wrap: pretty; }
.gm-body .nowrap { white-space: nowrap; }
/* 状态标记为 .badge-solid */
.gm-body em { align-self: flex-start; margin-top: auto; font-style: normal; --badge-pad: 2px 10px; }
.gm-body small { margin-bottom: 4px; }
/* ── Mixing desk ── */
.gm-mixpage .gm-card { padding: 14px 16px 16px; }
/* overflow: auto 会裁掉焦点环（2px 描边加 2px 偏移，共 4px）：四周留 4px 内边距，外侧用负外边距抵消，版面位置不变 */
.mix-src { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: -4px -4px 6px; padding: 4px; max-height: 138px; overflow: auto; }
.mix-transport { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.mix-seek { flex: 1 1 160px; height: 6px; border-radius: 3px; background: rgba(var(--blue-rgb), .15); position: relative; cursor: pointer; overflow: hidden; }
.mix-seek i { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: var(--accent-fill); border-radius: 3px; }
.mix-seek.off { opacity: .35; cursor: default; }
.mix-time { font: 12px monospace; color: var(--text3); white-space: nowrap; }
.mix-tg { border: var(--bw) solid var(--border); background: var(--surface); border-radius: var(--r-full); width: 34px; height: 34px; cursor: pointer; font-size: 14px; opacity: .55; transition: transform var(--dur-fast), opacity var(--dur-base), border-color var(--dur-base), background-color var(--dur-base), color var(--dur-base), box-shadow var(--dur-base); }
.mix-tg:active:not(:disabled) { transform: var(--ui-press, scale(.97)); }
.mix-tg[aria-pressed="true"] { opacity: 1; border-color: var(--blue); box-shadow: 0 0 0 2px rgba(var(--blue-rgb), .2); }
.mix-tg:disabled { opacity: .25; cursor: not-allowed; }
.mix-now { font: 12px var(--font-sans); color: var(--text3); flex-basis: 100%; }
.mix-media { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.mix-vizwrap { position: relative; border-radius: var(--r-md); overflow: hidden; background: #0b0a14; }
.mix-viz { display: block; width: 100%; height: 130px; }
.mix-av { position: absolute; left: 50%; top: 50%; width: 64px; height: 64px; margin: -32px 0 0 -32px; border-radius: 50%; border: 3px solid #fff; box-shadow: 0 0 20px rgba(255,255,255,.5); pointer-events: none; will-change: transform; }
.mix-presets { display: flex; flex-wrap: wrap; gap: 6px; }
/* Effect rack: a hardware panel (dark, screws in the corners, a power LED) plus knobs */
.mix-groups { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 12px; }
.mix-group { min-width: 0; }
.mix-group { --panel: #26262e; position: relative; color: #d8d8e0; border-radius: 10px; padding: 10px 12px 12px; border: 1px solid #0b0b10;
  background: radial-gradient(circle at 9px 9px, #8a8a96 2px, #3a3a44 2.6px, transparent 3.6px), radial-gradient(circle at calc(100% - 9px) 9px, #8a8a96 2px, #3a3a44 2.6px, transparent 3.6px), radial-gradient(circle at 9px calc(100% - 9px), #8a8a96 2px, #3a3a44 2.6px, transparent 3.6px), radial-gradient(circle at calc(100% - 9px) calc(100% - 9px), #8a8a96 2px, #3a3a44 2.6px, transparent 3.6px), repeating-linear-gradient(90deg, #ffffff05 0 1px, transparent 1px 3px), linear-gradient(#2e2e37, #1d1d23);
  box-shadow: inset 0 1px 0 #ffffff1a, inset 0 -1px 0 #00000080, 0 8px 20px #0007; display: flex; flex-direction: column; gap: 6px; }
.mix-group .gm-sub { color: #f0f0f4; text-transform: uppercase; letter-spacing: .14em; font: 700 11px/1.4 var(--font-display); margin: 0 0 6px; padding: 0 0 6px 8px; border-bottom: 1px solid #ffffff14; text-shadow: 0 1px 0 #000; }
.mix-group .gm-sub small { text-transform: none; letter-spacing: 0; color: #8a8a96; font: 10px/1.4 var(--font-sans); }
.mix-knobs, .mix-band { display: grid; grid-template-columns: repeat(auto-fill, minmax(66px, 1fr)); gap: 6px 2px; }
.mix-group > label, .mix-band > label { display: grid; grid-template-columns: 1fr; gap: 2px; font: 12px/1.3 var(--font-sans); color: #c8c8d2; }
.mix-group label > span { display: flex; align-items: baseline; gap: 3px; }
.mix-group label b { color: #ffd166; font: 12px monospace; margin-left: auto; text-shadow: 0 0 6px #ffd16688; }
.mix-group label > span u { text-decoration: none; color: #8a8a96; font: 10px monospace; min-width: 20px; }
.mix-group label small { color: #8a8a96; font-size: 10px; margin-left: 6px; }
.mix-group input[type="range"] { width: 100%; accent-color: #ff8fc2; margin: 0; height: 22px; }
.mix-group label.off { opacity: .35; pointer-events: none; }
.mix-group label.dim { opacity: .45; }
.mix-group label.dim .dial { filter: grayscale(1); }
/* Knobs */
.mix-group label.knob { position: relative; display: flex; flex-direction: column; align-items: center; gap: 1px; text-align: center; padding: 2px 0; }
label.knob > span:not(.dial) { order: 2; flex-direction: column; align-items: center; gap: 0; font-size: 10px; color: #b0b0bc; line-height: 1.25; }
label.knob > span b { margin: 0; font-size: 11px; }
label.knob > span u { min-width: 0; }
label.knob > span small { margin: 0; }
label.knob input[type="range"] { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
label.knob:focus-within .dial { box-shadow: 0 3px 6px #000a, inset 0 1px 0 #ffffff33, 0 0 0 2px #ff8fc2aa; }
.dial { --v: 0; position: relative; width: 44px; height: 44px; border-radius: 50%; cursor: ns-resize; touch-action: none; background: radial-gradient(circle at 50% 35%, #5a5a66, #2a2a32 65%, #17171c); box-shadow: 0 3px 6px #000a, inset 0 1px 0 #ffffff33, inset 0 -2px 3px #0008; margin: 5px 0 3px; }
.dial::before { content: ''; position: absolute; inset: -6px; border-radius: 50%; background: conic-gradient(from 225deg, #ff8fc2 0 calc(var(--v) * 270deg), #3a3a44 calc(var(--v) * 270deg) 270deg, transparent 270deg 360deg); -webkit-mask: radial-gradient(circle, transparent 66%, #000 67%); mask: radial-gradient(circle, transparent 66%, #000 67%); }
.dial.bi::before { background: conic-gradient(from 225deg, #3a3a44 0 min(135deg, calc(var(--v) * 270deg)), #ff8fc2 min(135deg, calc(var(--v) * 270deg)) max(135deg, calc(var(--v) * 270deg)), #3a3a44 max(135deg, calc(var(--v) * 270deg)) 270deg, transparent 270deg 360deg); }
.dial::after { content: ''; position: absolute; left: 50%; top: 4px; width: 3px; height: 14px; margin-left: -1.5px; border-radius: 2px; background: #fff; box-shadow: 0 0 4px #fff8; transform-origin: 50% 18px; transform: rotate(calc(-135deg + var(--v) * 270deg)); }
label.turning .dial { background: radial-gradient(circle at 50% 35%, #6a6a78, #30303a 65%, #17171c); }
/* Dropdowns / switches */
.mix-band .bn select, .mix-sel select { font: 11px var(--font-sans); border: 1px solid #0b0b10; border-radius: 4px; background: #15151a; color: #e8e8ee; padding: 2px 6px; box-shadow: inset 0 1px 2px #000; }
.mix-sel { display: flex !important; align-items: center; gap: 8px; font: 11px var(--font-sans); color: #b0b0bc; grid-column: 1 / -1; }
.mix-sel select { flex: 1; }
.mix-chk { display: flex !important; align-items: center; gap: 8px; grid-column: 1 / -1; font: 11px var(--font-sans); color: #b0b0bc; }
.mix-group > .mix-chk, .mix-group > .mix-sel { gap: 8px; }
.mix-chk input { appearance: none; width: 30px; height: 16px; border-radius: 8px; background: #15151a; box-shadow: inset 0 1px 3px #000; position: relative; cursor: pointer; margin: 0; }
.mix-chk input::after { content: ''; position: absolute; left: 2px; top: 2px; width: 12px; height: 12px; border-radius: 50%; background: #666; transition: left .15s, background var(--dur-base); }
.mix-chk input:checked::after { left: 16px; background: #ff8fc2; box-shadow: 0 0 6px #ff8fc2; }
/* EQ curve + five bands */
.mix-eqviz { display: block; width: 100%; height: 150px; border-radius: 6px; background: #0b0a14; margin-bottom: 6px; touch-action: none; cursor: default; box-shadow: inset 0 0 0 1px #ffffff10; }
.mix-bands { display: grid; grid-template-columns: repeat(5, 1fr); gap: 6px; }
.mix-band { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; background: #00000030; border-radius: 6px; padding: 4px 4px 2px; box-shadow: inset 0 1px 0 #00000060; }
.mix-band .bn { grid-column: 1 / -1; font: 700 10px/1.4 var(--font-sans); color: #b0b0bc; display: flex; align-items: center; gap: 6px; padding: 0 2px; }
.mix-band .bn select { flex: 1; font-size: 10px; padding: 1px 4px; }
.mix-band .dial { width: 34px; height: 34px; }
.mix-band .dial::after { height: 11px; transform-origin: 50% 13px; }
/* Meters */
.mix-meters { display: grid; grid-template-columns: auto 1fr; gap: 4px 8px; align-items: center; font: 10px monospace; color: #8a8a96; grid-column: 1 / -1; }
.mix-meter { height: 10px; border-radius: 3px; background: #0b0a14; position: relative; overflow: hidden; box-shadow: inset 0 1px 2px #000; }
.mix-meter i { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: repeating-linear-gradient(90deg, transparent 0 1px, #0008 1px 2px), linear-gradient(90deg, #35d06a 0 70%, #f0a020 70% 90%, #ff4d4d 90%); }
.mix-meter.gr i { left: auto; right: 0; background: repeating-linear-gradient(90deg, transparent 0 1px, #0008 1px 2px), linear-gradient(#ff8fc2, #ff8fc2); }
.mix-meter.gr { background: #1a1424; }
.mix-meter em { position: absolute; top: 0; bottom: 0; width: 2px; background: #fff; }
/* Power button / peak / A-B */
.mix-pow { width: 14px; height: 14px; border-radius: 50%; border: 2px solid #55555f; background: #1a1a20; padding: 0; cursor: pointer; margin-right: 8px; position: relative; top: 1px; flex: none; box-shadow: inset 0 1px 2px #000; transition: transform var(--dur-fast), border-color var(--dur-base), background-color var(--dur-base), box-shadow var(--dur-base); }
.mix-pow:active { transform: var(--ui-press, scale(.97)); }
/* 命中区外扩到 28px，可见尺寸不变 */
.mix-pow::after { content: ''; position: absolute; inset: -7px; }
.mix-pow[aria-pressed="true"] { border-color: #35d06a; background: #35d06a; box-shadow: 0 0 8px #35d06a, inset 0 1px 0 #fff8; }
.mix-group.byp > :not(.gm-sub) { opacity: .35; }
.mix-group.byp .mix-eqviz { opacity: .6; }
.mix-wide { grid-column: 1 / -1; }
.mix-peak { font: 10px monospace; color: #8a8a96; display: flex; gap: 6px; align-items: center; }
.mix-peak b { color: #ffd166; font-size: 12px; min-width: 40px; text-align: right; text-shadow: 0 0 6px #ffd16688; }
.mix-peak i { font-style: normal; font-weight: 700; padding: 0 5px; border-radius: 3px; background: #2a2a33; color: #9a9aa6; }
.mix-peak i.on { background: #ff4d4d; color: #fff; box-shadow: 0 0 8px #ff4d4d; }
.mix-ab { display: inline-flex; gap: 4px; }
.mix-tg.on { opacity: 1; border-color: var(--blue); background: var(--accent-fill); color: var(--on-accent); }
@media (max-width: 720px) { .mix-bands { grid-template-columns: repeat(2, 1fr); } .mix-groups { grid-template-columns: minmax(0, 1fr); } .mix-wide { grid-column: auto; } .mix-knobs { grid-template-columns: repeat(auto-fill, minmax(60px, 1fr)); } .mix-band { grid-template-columns: repeat(3, 1fr); } }
/* ── Mixing desk v3: rack heads (LED, move, drag), EQ solo, BPM / morph / undo on the transport, preset grouping, LFO indicators ── */
.mix-group .gm-sub { display: flex; align-items: center; gap: 6px; cursor: grab; }
.mix-group .gm-sub .mix-title { flex: none; }
.mix-group .gm-sub small { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mix-led { --lv: 0; width: 8px; height: 8px; border-radius: 50%; margin-left: auto; flex: none; background: hsl(calc(120 - var(--lv) * 120), 90%, calc(20% + var(--lv) * 35%)); box-shadow: 0 0 calc(var(--lv) * 8px) hsl(calc(120 - var(--lv) * 120), 90%, 55%); transition: background .05s; }
.mix-led.hot { background: #ff2d2d; box-shadow: 0 0 10px #ff2d2d; }
.mix-ord { display: inline-flex; gap: 2px; flex: none; }
.mix-ord button { position: relative; width: 18px; height: 16px; border: 1px solid #0b0b10; border-radius: 3px; background: #15151a; color: #8a8a96; font-size: 8px; cursor: pointer; padding: 0; line-height: 1; transition: transform var(--dur-fast), color var(--dur-base), background-color var(--dur-base); }
.mix-ord button:active { transform: var(--ui-press, scale(.97)); }
/* 命中区向外扩 4px，可见尺寸不变 */
.mix-ord button::after, .mix-solo::after, .mix-vizmode button::after, .mix-row .x::after { content: ''; position: absolute; inset: -4px; }
.mix-ord button:hover { color: #fff; }
.mix-group.dragging { opacity: .5; }
.mix-group.over { outline: 2px dashed #ff8fc2; outline-offset: 2px; }
.mix-pair { display: flex; gap: 8px; flex-wrap: wrap; }
.mix-pair .mix-sel { flex: 1; grid-column: auto; min-width: 120px; }
.mix-sel select { max-width: 100%; }
.mix-hold { border: 0; border-radius: 6px; background: linear-gradient(#ff8fc2, #d4327a); color: #fff; font: 700 13px var(--font-display); padding: 10px; cursor: pointer; box-shadow: 0 4px 0 #7a0a3a, inset 0 1px 0 #fff6; user-select: none; -webkit-user-select: none; touch-action: none; transition: transform .08s, box-shadow .08s; }
.mix-hold.on, .mix-hold:active { transform: translateY(3px); box-shadow: 0 1px 0 #7a0a3a; }
.mix-solo { position: relative; margin-left: auto; width: 22px; height: 20px; transition: transform var(--dur-fast), background-color var(--dur-base), color var(--dur-base), box-shadow var(--dur-base); border: 1px solid #0b0b10; border-radius: 3px; background: #15151a; color: #8a8a96; font: 700 9px monospace; cursor: pointer; padding: 0; }
.mix-solo:active { transform: var(--ui-press, scale(.97)); }
.mix-solo.on { background: #ffd166; color: #000; box-shadow: 0 0 6px #ffd166; }
.mix-eqbar { display: flex; align-items: center; gap: 4px; margin-bottom: 4px; font: 10px var(--font-sans); color: #8a8a96; }
.mix-eqbar .mix-tg { width: auto; height: 22px; padding: 0 8px; font: 700 10px monospace; border-color: #0b0b10; background: #15151a; color: #8a8a96; }
.mix-eqbar .mix-tg.on { color: #fff; background: #ff8fc2; border-color: #ff8fc2; }
.mix-eqpre { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; }
.mix-eqpre select { font: 11px var(--font-sans); border: 1px solid #0b0b10; border-radius: 4px; background: #15151a; color: #e8e8ee; padding: 2px 6px; }
.mix-tune { display: flex; align-items: baseline; gap: 8px; background: #0b0a14; border-radius: 6px; padding: 4px 10px; box-shadow: inset 0 1px 3px #000; }
.mix-note { font: 700 18px monospace; color: #ffd166; text-shadow: 0 0 8px #ffd16688; min-width: 90px; }
.mix-tune small { color: #8a8a96; font-size: 10px; }
.dial.modd::after { box-shadow: 0 0 4px #fff8, 0 0 0 1px #ffd166; }
.dial.modd { background: radial-gradient(circle at 50% 35%, #5a5a66, #2a2a32 65%, #17171c), conic-gradient(from 225deg, transparent calc(var(--m) * 270deg), #ffd166 calc(var(--m) * 270deg), transparent calc(var(--m) * 270deg + 3deg)); }
.dial.modd::before { background: conic-gradient(from 225deg, #ff8fc2 0 calc(var(--v) * 270deg), #3a3a44 calc(var(--v) * 270deg) 270deg, transparent 270deg 360deg), conic-gradient(from 225deg, transparent calc(var(--m) * 270deg - 2deg), #ffd166 calc(var(--m) * 270deg - 2deg) calc(var(--m) * 270deg + 2deg), transparent calc(var(--m) * 270deg + 2deg)); background-blend-mode: normal; }
.mix-transport { row-gap: 8px; }
.mix-bpm { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
@media (max-width: 600px) {
  .mix-transport { gap: 8px; }
  .mix-bpm { flex: 1 1 100%; }
  .knob-inline { flex: 1 1 140px; }
  .mix-ab { flex: 1 1 100%; }
  #mixMorph { flex: 1; width: auto; min-width: 44px; }
}
.knob-inline { display: inline-flex; align-items: center; gap: 6px; font: 11px monospace; color: var(--text3); white-space: nowrap; }
.knob-inline b { color: var(--blue2); margin-left: 4px; }
/* 标签定宽，BPM 与 Tempo 两个滑块的起点对齐 */
.knob-inline > span { flex: none; width: 72px; }
.knob-inline input[type="range"] { flex: 1; width: 70px; min-width: 56px; }
.mix-ab { display: inline-flex; gap: 4px; align-items: center; }
#mixMorph { width: 60px; }
/* 传输区滑块：轨道 6px，滑块头 16px，浅色轨道与 .mix-seek 一致 */
.mix-transport input[type="range"] { -webkit-appearance: none; appearance: none; height: 16px; margin: 0; background: transparent; cursor: pointer; }
.mix-transport input[type="range"]::-webkit-slider-runnable-track { height: 6px; border-radius: 3px; background: rgba(var(--blue-rgb), .18); }
.mix-transport input[type="range"]::-moz-range-track { height: 6px; border-radius: 3px; background: rgba(var(--blue-rgb), .18); }
.mix-transport input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 16px; height: 16px; margin-top: -5px; border-radius: 50%; border: 2px solid #fff; background: var(--blue); box-shadow: 0 1px 3px rgba(0,0,0,.28); }
.mix-transport input[type="range"]::-moz-range-thumb { box-sizing: border-box; width: 16px; height: 16px; border-radius: 50%; border: 2px solid #fff; background: var(--blue); box-shadow: 0 1px 3px rgba(0,0,0,.28); }
.mix-transport input[type="range"]:focus-visible { outline: none; }
.mix-transport input[type="range"]:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px rgba(var(--blue-rgb), .32); }
.mix-transport input[type="range"]:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 3px rgba(var(--blue-rgb), .32); }
.mix-transport .btn-icon svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
/* 触屏：32px 图标钮与 30px 文字钮的命中区向外扩 6px，可见尺寸不变 */
@media (pointer: coarse) {
  .mix-transport :is(.btn-icon, .btn-outline) { position: relative; }
  .mix-transport :is(.btn-icon, .btn-outline)::after { content: ''; position: absolute; inset: -6px -3px; }
  .mix-transport input[type="range"] { height: 28px; }
}
.mix-hist { display: inline-flex; gap: 4px; }
/* 撤销/重做、MIDI、BYP 作为一组整体换行，避免 BYP 单独落在一行 */
.mix-tail { display: inline-flex; align-items: center; gap: 10px; flex: none; }
.mix-vizmode { position: absolute; left: 8px; top: 6px; display: flex; gap: 4px; }
.mix-vizmode button { position: relative; border: 1px solid #ffffff22; background: #00000066; color: #aaa; font: 10px var(--font-sans); border-radius: 4px; padding: 4px 8px; cursor: pointer; transition: transform var(--dur-fast), color var(--dur-base), border-color var(--dur-base); }
.mix-vizmode button:active { transform: var(--ui-press, scale(.97)); }
.mix-vizmode button.on { color: #fff; border-color: #ff8fc2; }
.mix-lufs { position: absolute; right: 8px; top: 6px; display: flex; gap: 10px; font: 10px monospace; color: #aaa; }
.mix-lufs b { color: #ffd166; }
.mix-pgroup { font: 700 11px var(--font-sans); color: var(--text2); letter-spacing: .08em; text-transform: uppercase; align-self: center; margin: 0 4px 0 6px; flex-basis: auto; }
.mix-pgroup:first-child { margin-left: 0; }
.mix-presets { align-items: center; }
.mix-pdesc { margin-top: 8px; font: 12px/1.6 var(--font-sans); color: var(--text2); }
.mix-pdesc:empty { display: none; }
.mix-pdesc a { color: var(--blue2); }
.mix-pactions { margin-left: auto; display: inline-flex; gap: 6px; flex: none; }
.gm-card > .gm-sub { flex-wrap: wrap; }
.mix-user { margin-top: 10px; display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.mix-user .mix-presets { flex-basis: 100%; }
#mixPname { width: 160px; --field-r: var(--r-pill); --field-fs: 12px; --field-pad: 5px 12px; }
/* 直播源用危险色，作为组件令牌传给 pill-soft */
#mixSources > [data-src="live"]:not(.is-on) { --pill-soft-border: var(--danger); --pill-soft-fg: var(--danger); }
#mixSources > .pill-soft { max-width: 240px; overflow: hidden; text-overflow: ellipsis; }
#mixSources em { font-style: normal; font-size: 11px; opacity: .8; }
.mix-user .mix-presets button i { font-style: normal; margin-left: 4px; opacity: .65; }
.mix-user .mix-presets button i:hover { color: #ff4d4d; }
.mix-seek em { position: absolute; top: 0; bottom: 0; background: rgba(255,209,102,.35); border-left: 2px solid #ffd166; border-right: 2px solid #ffd166; pointer-events: none; z-index: 1; }
.mix-seek i { z-index: 0; }
[data-val] { cursor: text; }
[data-val] input { width: 54px; font: 11px monospace; background: #0b0a14; color: #ffd166; border: 1px solid #ff8fc2; border-radius: 3px; padding: 0 3px; }
@media (max-width: 720px) { .mix-vizmode { top: auto; bottom: 6px; } }
.mix-hold small { display: block; font: 10px var(--font-sans); opacity: .8; font-weight: 400; }
.mix-hold:disabled { opacity: .35; cursor: not-allowed; transform: none; box-shadow: 0 4px 0 #7a0a3a; }

/* ── Faders (levels use faders, everything else knobs) ── */
label.isfader.knob .dial { display: none; }
.fader { --v: 0; position: relative; width: 30px; height: 112px; margin: 6px 0 4px; border-radius: 4px; cursor: ns-resize; touch-action: none; background: linear-gradient(90deg, transparent 0 12px, #0b0a14 12px 18px, transparent 18px), repeating-linear-gradient(180deg, transparent 0 9px, #ffffff22 9px 10px); box-shadow: inset 0 0 0 1px #00000040; }
.fader::before { content: ''; position: absolute; left: 12px; width: 6px; bottom: 6px; height: calc(var(--v) * 100px); background: #ff8fc2; border-radius: 3px; opacity: .55; }
.fader.bi::before { display: none; }
.fader::after { content: ''; position: absolute; left: 1px; width: 28px; height: 18px; bottom: calc(var(--v) * 94px); border-radius: 3px; background: linear-gradient(#f4f4f8, #b8b8c4 50%, #8f8f9c); box-shadow: 0 2px 4px #000a, inset 0 1px 0 #fff, inset 0 -1px 0 #0006; background-image: linear-gradient(#f4f4f8, #b8b8c4 50%, #8f8f9c), linear-gradient(#ff8fc2, #ff8fc2); background-size: 100% 100%, 22px 2px; background-position: 0 0, 3px 8px; background-repeat: no-repeat; }
label.turning .fader::after { background: linear-gradient(#fff, #c8c8d2 50%, #9f9fac); }
/* ── Turntable ── */
.mix-deckwrap { display: grid; grid-template-columns: 220px 1fr; gap: 16px; align-items: center; }
.mix-platter { width: 220px; height: 220px; border-radius: 50%; cursor: grab; touch-action: none; box-shadow: 0 8px 20px #000a, 0 0 0 4px #17171c, 0 0 0 5px #3a3a44; user-select: none; -webkit-user-select: none; }
.mix-platter.grab { cursor: grabbing; }
.mix-deckctl { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.mix-deckread { display: flex; gap: 14px; align-items: center; font: 11px var(--font-sans); color: #b0b0bc; flex-wrap: wrap; }
.mix-deckread b { font: 700 14px monospace; color: #ffd166; text-shadow: 0 0 6px #ffd16688; }
.mix-deckmode { font: 700 11px monospace; letter-spacing: .1em; padding: 2px 8px; border-radius: 3px; background: #ff3b5c; color: #fff; box-shadow: 0 0 8px #ff3b5c; }
.mix-deckmode.deck { background: #35d06a; box-shadow: 0 0 8px #35d06a; color: #000; }
.mix-deckbtns { display: flex; gap: 8px; flex-wrap: wrap; }
.mix-deckbtns .mix-hold { height: 34px; padding: 0 16px; font-size: 12px; border-radius: var(--r-full); }
.mix-deckbtns .mix-tg { width: auto; height: 34px; padding: 0 12px; font: 700 12px var(--font-sans); opacity: 1; border-color: #0b0b10; background: #15151a; color: #e8e8ee; }
.mix-deckbtns .mix-tg[aria-pressed="true"] { background: #ffd166; color: #000; border-color: #ffd166; }
.mix-deck .mix-knobs { grid-template-columns: repeat(auto-fill, minmax(70px, 1fr)); }
@media (max-width: 560px) { .mix-deckwrap { grid-template-columns: 1fr; justify-items: center; } .mix-deckctl { width: 100%; } }
/* ── 3D space radar ── */
.mix-spacewrap { display: grid; grid-template-columns: 220px 1fr; gap: 16px; align-items: start; }
.mix-radar { width: 220px; height: 220px; border-radius: 50%; cursor: crosshair; touch-action: none; box-shadow: 0 8px 20px #000a, 0 0 0 4px #17171c, 0 0 0 5px #2c4a3a; user-select: none; -webkit-user-select: none; }
.mix-radar.grab { cursor: grabbing; }
.mix-space .mix-knobs { grid-template-columns: repeat(auto-fill, minmax(70px, 1fr)); }
@media (max-width: 560px) { .mix-spacewrap { grid-template-columns: 1fr; justify-items: center; } }

/* ── Rack instances: + / ×, index, the add-module strip ── */
.mix-nth { font: 700 10px monospace; color: #ffd166; font-style: normal; margin-left: -2px; }
.mix-ord button[data-act="dup"], .mix-ord button[data-act="del"] { font-size: 11px; font-weight: 700; }
.mix-ord button[data-act="del"]:hover { color: #ff4d4d; }
.mix-addbar .mix-tg { width: auto; height: 28px; padding: 0 10px; font: 12px var(--font-sans); opacity: 1; }
.mix-static { margin-top: 0; }
#mixTypes[hidden] { display: none !important; }
.mix-transport .knob-inline b { min-width: 28px; display: inline-block; text-align: right; }
.mix-eqbar { flex-wrap: wrap; }
.mix-group .gm-sub { flex-wrap: wrap; }
.mix-deckread b { white-space: nowrap; }
.mix-chain-pill.byp { opacity: .4; text-decoration: line-through; }
.mix-group.flash { outline: 2px solid #ff8fc2; outline-offset: 2px; }

/* ── Workspace: module library on the left, the chain on the right; only the selected unit is shown below ── */
.mix-work { display: grid; grid-template-columns: 240px 1fr; gap: 16px; }
/* 标题与说明各占一行，两列的列表起点一致；标题不参与收缩 */
.mix-lib .gm-sub, .mix-listwrap .gm-sub { margin-bottom: 8px; flex-wrap: wrap; row-gap: 0; }
.mix-lib .gm-sub > span, .mix-listwrap .gm-sub > span { flex: none; white-space: nowrap; }
.mix-lib .gm-sub small, .mix-listwrap .gm-sub small { flex-basis: 100%; }
.mix-libgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.mix-libitem { border: var(--bw) solid var(--card-border); background: var(--card-bg); color: var(--text); border-radius: var(--r-md); padding: 8px 8px; font: 700 12px/1.3 var(--font-sans); cursor: grab; user-select: none; -webkit-user-select: none; touch-action: none; text-align: left; display: flex; flex-direction: column; gap: 2px; transition: transform var(--dur-fast), border-color var(--dur-base), opacity var(--dur-base); }
.mix-libitem:active { transform: var(--ui-press, scale(.97)); }
.mix-libitem small { font: 10px/1.3 var(--font-sans); color: var(--text3); font-weight: 400; }
.mix-libitem:hover { border-color: var(--border-hover); }
.mix-libitem.used { opacity: .45; }
.mix-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; min-height: 40px; }
.mix-list:empty { min-height: 0; }
.mix-row { display: flex; align-items: center; gap: 8px; padding: 7px 10px; border-radius: var(--r-md); background: linear-gradient(#2e2e37, #1d1d23); color: #e8e8ee; border: 1px solid #0b0b10; box-shadow: inset 0 1px 0 #ffffff14; cursor: grab; user-select: none; -webkit-user-select: none; touch-action: none; font: 12px var(--font-sans); }
.mix-row .h { color: #55555f; font: 14px monospace; letter-spacing: -2px; flex: none; }
.mix-row .n { font: 700 11px monospace; color: #ff8fc2; background: #0b0a14; border-radius: 4px; padding: 1px 5px; flex: none; }
.mix-row .t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 700; letter-spacing: .04em; }
.mix-row .t small { color: #8a8a96; font-weight: 400; margin-left: 6px; }
.mix-row .mix-led { margin-left: 0; }
.mix-row .mix-pow { margin: 0; }
.mix-row .x { position: relative; border: 0; background: none; color: #8a8a96; font: 700 13px/1 monospace; cursor: pointer; padding: 4px 6px; transition: transform var(--dur-fast), color var(--dur-base); }
.mix-row .x:active { transform: var(--ui-press, scale(.97)); }
.mix-row .x:hover { color: #ff4d4d; }
/* 触屏：机架小钮的命中区外扩到 36px 高（相邻钮之间的外扩不互相重叠），可见尺寸不变 */
@media (pointer: coarse) {
  .mix-ord button::after { inset: -8px -1px; }
  .mix-solo::after { inset: -8px -2px; }
  .mix-row .x::after { inset: -8px -2px; }
  .mix-pow::after { inset: -10px -4px; }
  /* 页签紧贴 .mix-vizwrap 的上或下边（overflow: hidden，6px 处被裁），另一侧多扩一些，总高保持 32px 以上 */
  .mix-vizmode button::after { inset: -10px -2px; }
}
.mix-row.sel { border-color: #ff8fc2; box-shadow: 0 0 0 2px rgba(255,143,194,.25), inset 0 1px 0 #ffffff14; }
.mix-row.byp { opacity: .55; } .mix-row.byp .t { text-decoration: line-through; }
.mix-row.ghost { opacity: .35; }
.mix-row.ins { box-shadow: 0 -4px 0 -1px #ff8fc2, inset 0 1px 0 #ffffff14; }
.mix-row.ins-after { box-shadow: 0 4px 0 -1px #ff8fc2, inset 0 1px 0 #ffffff14; }
.mix-list.ins-empty { min-height: 40px; outline: 2px dashed #ff8fc2; outline-offset: 2px; border-radius: var(--r-md); }
.mix-list.dropping { cursor: grabbing; }
.mix-dragghost { position: fixed; z-index: 9999; pointer-events: none; padding: 7px 12px; border-radius: var(--r-md); background: #26262e; color: #fff; font: 700 12px var(--font-sans); box-shadow: 0 8px 20px #0008; border: 1px solid #ff8fc2; transform: translate(-50%, -50%); }
.mix-empty { font: 12px var(--font-sans); color: var(--text3); padding: 14px; border: 1px dashed var(--border); border-radius: var(--r-md); text-align: center; }
.mix-empty[hidden] { display: none; }
.mix-panelcard { padding: 12px 14px 14px; }
.mix-panels .mix-group { display: none; }
.mix-panels .mix-group.sel { display: flex; }
.mix-nopanel { font: 12px var(--font-sans); color: var(--text3); text-align: center; padding: 18px; }
.mix-nopanel[hidden] { display: none; }
.mix-ord button { width: auto; padding: 0 8px; font: 11px var(--font-sans); height: 20px; }
@media (max-width: 720px) { .mix-work { grid-template-columns: 1fr; } .mix-libgrid { grid-template-columns: repeat(3, 1fr); } .mix-libitem { padding: 6px; font-size: 11px; min-height: 36px; justify-content: center; } .mix-libitem small { display: none; } }
/* 应援席 tile: a dark stage with a row of little penlight dots along the bottom */
.gm-tile-seat .gm-cover { background: linear-gradient(180deg, #0B1020 0%, #101B33 100%); }
.gm-tile-seat .gm-cover::after { content: ""; position: absolute; left: 10%; right: 10%; bottom: 18%; height: 6px; border-radius: 3px;
  background: repeating-linear-gradient(90deg, #FF6FB1 0 6px, transparent 6px 14px, #5EE7FF 14px 20px, transparent 20px 28px, #FFD166 28px 34px, transparent 34px 42px); opacity: .85; }

/* 减少动态效果：取消入口卡片的上浮与圆盘旋转，以及传输区与机架按钮的位移 */
@media (prefers-reduced-motion: reduce) {
  .gm-tile, .disc-frost { transition: none; }
  a.gm-tile:hover { translate: none; }
  a.gm-tile:hover .disc-frost { transform: none; }
  .mix-tg, .mix-pow, .mix-ord button, .mix-solo, .mix-vizmode button, .mix-row .x, .mix-libitem, .mix-hold { transition: none; }
  .mix-tg:active, .mix-pow:active, .mix-ord button:active, .mix-solo:active, .mix-vizmode button:active, .mix-row .x:active, .mix-libitem:active { transform: none; }
}

/* ── 杂物间入口：默认主题下为编辑式列表 ──────────────────────────────
   一行一个入口：大号描边编号、标题、说明、封面缩略图、状态。其余皮肤保持
   卡片网格（它们各自改写 .gm-tile 的面）。标记不变：编号由 CSS 计数器生成，
   .gm-body 用 display: contents 让标题、说明、状态直接参与网格。
   [data-tilt] 的倾斜与高光只适合卡片，这里关闭。 */
html:not([data-skin]) .gm-hub { display: block; counter-reset: gm-n; border-top: 1px solid var(--border); }
html:not([data-skin]) .gm-tile {
  counter-increment: gm-n;
  display: grid;
  grid-template-columns: 88px minmax(0, 1.1fr) minmax(0, 1.7fr) 152px 104px;
  align-items: center; column-gap: var(--s-4);
  padding: 22px 6px;
  background: none; border: 0; border-bottom: 1px solid var(--border); border-radius: 0; box-shadow: none;
  transform: none !important;
  transition: background-color var(--dur-base);
}
html:not([data-skin]) .gm-tile > .tilt-edge, html:not([data-skin]) .gm-tile::after { display: none; }
html:not([data-skin]) .gm-tile::before {
  content: counter(gm-n, decimal-leading-zero);
  font: 700 46px/1 var(--font-display); font-variant-numeric: tabular-nums;
  color: transparent; -webkit-text-stroke: 1px var(--border-hover, var(--border));
  transition: -webkit-text-stroke-color var(--dur-base);
}
html:not([data-skin]) .gm-body { display: contents; }
html:not([data-skin]) .gm-body b { grid-column: 2; font-size: 22px; letter-spacing: .03em; }
html:not([data-skin]) .gm-body small { grid-column: 3; margin: 0; font-size: 13px; }
html:not([data-skin]) .gm-body em { grid-column: 5; grid-row: 1; justify-self: end; align-self: center; margin: 0; }
html:not([data-skin]) .gm-cover {
  grid-column: 4; grid-row: 1; height: 64px; border-radius: var(--r-sm);
  border: 1px solid var(--border);
}
html:not([data-skin]) .gm-cover .disc-frost { transform: scale(.62); }
@media (hover: hover) {
  html:not([data-skin]) a.gm-tile:hover { translate: none; box-shadow: none; border-color: var(--border); background: linear-gradient(90deg, rgba(var(--blue-rgb), .08), transparent 75%); }
  html:not([data-skin]) a.gm-tile:hover::before { -webkit-text-stroke-color: var(--blue); }
  html:not([data-skin]) a.gm-tile:hover .disc-frost { transform: scale(.7); }
}
@media (max-width: 860px) {
  html:not([data-skin]) .gm-tile { grid-template-columns: 56px minmax(0, 1fr) auto; row-gap: 4px; padding: 18px 2px; column-gap: var(--s-3); }
  html:not([data-skin]) .gm-tile::before { grid-row: span 2; font-size: 34px; }
  html:not([data-skin]) .gm-cover { display: none; }
  html:not([data-skin]) .gm-body b { grid-column: 2; grid-row: 1; font-size: 19px; }
  html:not([data-skin]) .gm-body em { grid-column: 3; grid-row: 1; }
  html:not([data-skin]) .gm-body small { grid-column: 2 / -1; grid-row: 2; }
}
