/* ───────────── Preview mixer ───────────── */ .mixer-column { min-width: 0; display: grid; grid-template-columns: repeat(6, minmax(68px, 1fr)); gap: 10px; } .lane-header { min-height: 190px; display: grid; grid-template-rows: auto 1fr; justify-items: center; position: relative; transition: opacity var(--t-base) var(--easing); color: var(--stem-color, #d8dde4); } .lane-header[data-stem="vocals"] { --stem-color: #e54249; } .lane-header[data-stem="drums"] { --stem-color: #f06a14; } .lane-header[data-stem="bass"] { --stem-color: #eab414; } .lane-header[data-stem="guitar"] { --stem-color: #5bbf50; } .lane-header[data-stem="piano"] { --stem-color: #7f45d8; } .lane-header[data-stem="other"] { --stem-color: #3e8dcf; } .lane-header[data-stem="original"] { --stem-color: #a8b0bd; } .lane-header + .lane-header { border-left: 1px solid var(--glass-line); } .lane-header.muted { opacity: 0.45; } .lane-stripe { display: none; } .lane-content { display: contents; } .lane-name-row { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; } .lane-icon { width: 29px; height: 29px; flex: 0 0 auto; color: var(--stem-color); filter: drop-shadow(0 0 10px color-mix(in srgb, currentColor 34%, transparent)); } .lane-icon-toggle { width: 42px; height: 42px; display: grid; place-items: center; padding: 0; border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--stem-color); cursor: pointer; opacity: 0.38; transition: opacity var(--t-base) var(--easing), border-color var(--t-base) var(--easing), background-color var(--t-base) var(--easing), transform var(--t-fast) var(--easing); } .lane-icon-toggle.active { opacity: 1; border-color: color-mix(in srgb, currentColor 24%, transparent); background: color-mix(in srgb, currentColor 8%, transparent); box-shadow: inset 0 0 18px color-mix(in srgb, currentColor 8%, transparent); } .lane-icon-toggle:hover:not(:disabled) { opacity: 1; transform: translateY(-1px); } .lane-icon-toggle:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; } .lane-icon-toggle:disabled { cursor: default; opacity: 0.25; } .lane-name { color: #d7dce3 !important; font-size: 14px; } .lane-controls { display: grid; grid-template-columns: 1fr; grid-template-rows: 106px; align-items: end; justify-items: center; gap: 10px; } .lane-mini-wave { display: none; } .lane-dl { display: none; color: #d8dde4; text-decoration: none; } .lane-knob { grid-column: 1 / -1; grid-row: 1; width: 48px; height: 104px; border-radius: 0; border: 0; background: repeating-linear-gradient(to bottom, rgba(148, 163, 184, 0.22) 0 1px, transparent 1px 12px), linear-gradient(90deg, transparent 0 44%, rgba(148, 163, 184, 0.2) 44% 56%, transparent 56% 100%); position: relative; cursor: ns-resize; /* --lane-pos: 0..1 = bottom..top. Default 0.5 = unity gain (vol=1 of LANE_VOLUME_MAX=2). JS rewrites this when volume changes. */ --lane-pos: 0.5; } /* Fader thumb. Travels vertically along the track based on --lane-pos. The travel envelope is 100% - 18px (the thumb's own height) so the thumb never overshoots the track edges. The transition is only for programmatic moves (Reset, dblclick, wheel) -- during an active drag we kill the transition (.lane-knob.dragging rule below) so the thumb tracks the cursor 1:1 instead of chasing it through an easing curve, which reads as a rigid/laggy fader. */ .lane-knob::before { content: ""; position: absolute; left: 50%; top: calc((1 - var(--lane-pos)) * (100% - 14px)); width: 30px; height: 14px; transform: translateX(-50%); border-radius: 3px; border: 1px solid #050505; background: linear-gradient(180deg, rgba(255, 255, 255, 0.2), transparent 42%), linear-gradient(180deg, #6a6a6a 0%, #2a2a2a 55%, #161616 100%); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), inset 0 -1px 0 rgba(0, 0, 0, 0.7), 0 0 0 1px color-mix(in srgb, currentColor 34%, transparent), 0 1px 2px rgba(0, 0, 0, 0.72); transition: top 120ms var(--easing); will-change: top; pointer-events: none; } .lane-knob.dragging::before { transition: none; } /* Slight grip cue while actively dragging -- thumb gets a tighter shadow ring so it feels "picked up". */ .lane-knob.dragging { cursor: grabbing; } .lane-knob-indicator { display: none; } .lane-knob.disabled { opacity: 0.45; pointer-events: none; } .ms-btn { width: 30px; height: 30px; border: 0; border-radius: 6px; background: rgba(255, 255, 255, 0.055); color: #d8dde4; font-family: var(--font-mono); font-size: 14px; font-weight: 700; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: background-color var(--t-base) var(--easing), transform var(--t-fast) var(--easing); } .ms-btn:hover { background: rgba(255, 255, 255, 0.1); } .ms-btn:active { transform: scale(0.92); } .ms-btn.mute.active { background: var(--danger); color: white; } .ms-btn.solo.active { background: var(--gold); color: #17130c; } .ms-btn:disabled { opacity: 0.38; pointer-events: none; } .lane-controls .ms-btn.mute { grid-column: 1; grid-row: 2; } .lane-controls .ms-btn.solo { grid-column: 2; grid-row: 2; } .lane-vu { display: none; } .app:not(.is-import) .preview-mixer-body { height: 100%; display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; padding-top: 0; } .app:not(.is-import) .mixer-column { height: 100%; grid-template-columns: repeat(var(--visible-track-count, 6), minmax(52px, 1fr)); gap: 0; } .app:not(.is-import) .lane-header { min-height: 0; height: 100%; grid-template-rows: 64px 1fr; padding: 7px 0 6px; overflow: hidden; } .app:not(.is-import) .lane-name-row { gap: 6px; } .app:not(.is-import) .lane-icon { width: 26px; height: 26px; } .app:not(.is-import) .lane-icon-toggle { width: 38px; height: 38px; } .app:not(.is-import) .lane-name { font-size: 12px; } .app:not(.is-import) .lane-controls { width: 100%; height: auto; min-height: 0; align-self: stretch; grid-template-columns: 1fr; grid-template-rows: 1fr; gap: 0; padding: 0 5px 38px; } .app:not(.is-import) .lane-knob { width: 42px; height: 100%; min-height: 0; justify-self: center; } .app:not(.is-import) .lane-vu { display: block; position: absolute; left: 50%; top: 72px; bottom: 48px; width: 12px; height: auto; transform: translateX(18px); border-radius: 2px; overflow: hidden; background: linear-gradient(to top, rgba(48, 197, 87, 0.14) 0 55%, rgba(225, 178, 46, 0.14) 55% 80%, rgba(214, 64, 64, 0.14) 80% 100%), rgba(4, 10, 15, 0.82); box-shadow: inset 0 0 0 1px rgba(148, 163, 184, 0.12); } .app:not(.is-import) .lane-dl { display: grid; place-items: center; position: absolute; left: 8px; right: 8px; bottom: 6px; height: 34px; transform: none; border: 1px solid color-mix(in srgb, var(--stem-color) 28%, rgba(148, 163, 184, 0.18)); border-radius: 8px; background: linear-gradient(180deg, color-mix(in srgb, var(--stem-color) 13%, transparent), transparent), rgba(255, 255, 255, 0.055); color: var(--stem-color); opacity: 0.9; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.035), 0 6px 14px rgba(0, 0, 0, 0.16); transition: opacity var(--t-base) var(--easing), background-color var(--t-base) var(--easing), border-color var(--t-base) var(--easing), transform var(--t-fast) var(--easing); } .app:not(.is-import) .lane-dl svg { width: 19px; height: 19px; stroke-width: 2.15; } .app:not(.is-import) .lane-dl:hover:not(.disabled) { opacity: 1; border-color: color-mix(in srgb, var(--stem-color) 58%, transparent); background: linear-gradient(180deg, color-mix(in srgb, var(--stem-color) 18%, transparent), transparent), rgba(255, 255, 255, 0.075); transform: translateY(-1px); } .app:not(.is-import) .lane-dl:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; } .app:not(.is-import) .lane-dl.disabled { opacity: 0.28; pointer-events: none; } .app:not(.is-import) .lane-vu::before { content: ""; position: absolute; left: 1px; right: 1px; top: 1px; bottom: 1px; background: repeating-linear-gradient(to top, transparent 0 3px, rgba(0, 0, 0, 0.4) 3px 5px), linear-gradient(to top, #24bf55 0 58%, #e1b22e 58% 80%, #d64040 80% 100%); clip-path: inset(calc(100% - var(--vu-level, 0%)) 0 0 0); transition: clip-path 30ms linear; } .app:not(.is-import) .lane-vu::after { content: ""; position: absolute; left: 1px; right: 1px; bottom: var(--vu-peak, 0%); height: 2px; background: rgba(255, 255, 255, 0.78); transition: bottom 80ms linear; } .app:not(.is-import) .master-strip { height: 100%; min-height: 0; grid-template-columns: 1fr; grid-template-rows: 72px 1fr; gap: 8px; overflow: hidden; } .app:not(.is-import) .master-strip .master-fader-track { height: calc(100% - 4px); min-height: 0; } .app:not(.is-import) .master-strip .master-fader-track::before, .app:not(.is-import) .master-strip .master-fader-track::after { display: none; }