9 CSS 3D Designs06 / 09
Modular Synth Controls
A dark anodized panel with four interaction systems working simultaneously: push buttons with 3D translateY press travel and colored LED dots, toggle switches with a spring-overshoot thumb animation, six vertical faders with drag-to-set handles + fill bars + real-time value readouts, and dual VU meters with color-coded segments (cyan → amber → red) animating continuously. A readout bar at the top updates live as controls change. Share Tech Mono + Rajdhani. Best for audio production apps, game HUDs, creative dashboards, hardware-inspired control panels.
Published
The code
<section class="cd-syn" aria-label="Modular synth control panel demo">
<div class="card">
<div class="panel">
<div class="readout">
<div class="readout-item">
<div class="readout-key">Mode</div>
<div class="readout-val" data-cd-syn-mode>STUDIO</div>
</div>
<div class="readout-item">
<div class="readout-key">Master</div>
<div class="readout-val" data-cd-syn-master>87</div>
</div>
<div class="readout-item">
<div class="readout-key">BPM</div>
<div class="readout-val" data-cd-syn-bpm>124</div>
</div>
<div class="readout-item">
<div class="readout-key">Status</div>
<div class="readout-val live">LIVE</div>
</div>
</div>
<div class="main-layout">
<div class="left-controls">
<div class="section">
<div class="section-label">Transport</div>
<div class="btn-row">
<button class="push-btn" type="button" data-action="play">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Play</span></span>
</button>
<button class="push-btn active" type="button" data-action="rec">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Rec</span></span>
</button>
<button class="push-btn" type="button" data-action="stop">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Stop</span></span>
</button>
<button class="push-btn active" type="button" data-action="loop">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Loop</span></span>
</button>
<button class="push-btn" type="button" data-action="fx">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">FX</span></span>
</button>
</div>
</div>
<div class="section">
<div class="section-label">Routing</div>
<div class="toggle-row">
<div class="toggle-unit">
<button class="toggle-sw on" type="button" data-toggle="mono" style="--led-col:#00e8cc">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Mono</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw" type="button" data-toggle="reverb" style="--led-col:#c060ff">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Reverb</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw on" type="button" data-toggle="eq" style="--led-col:#ffaa00">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">EQ</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw" type="button" data-toggle="comp" style="--led-col:#ff3840">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Comp</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw on" type="button" data-toggle="gate" style="--led-col:#00e060">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Gate</span>
</div>
</div>
</div>
<div class="section">
<div class="section-label">Channel Mix</div>
<div class="fader-row" data-cd-syn-faderrow></div>
</div>
</div>
<div class="right-controls">
<div class="section-label rl">Level</div>
<div class="vu-row" data-cd-syn-vurow></div>
</div>
</div>
</div>
</div>
</section><section class="cd-syn" aria-label="Modular synth control panel demo">
<div class="card">
<div class="panel">
<div class="readout">
<div class="readout-item">
<div class="readout-key">Mode</div>
<div class="readout-val" data-cd-syn-mode>STUDIO</div>
</div>
<div class="readout-item">
<div class="readout-key">Master</div>
<div class="readout-val" data-cd-syn-master>87</div>
</div>
<div class="readout-item">
<div class="readout-key">BPM</div>
<div class="readout-val" data-cd-syn-bpm>124</div>
</div>
<div class="readout-item">
<div class="readout-key">Status</div>
<div class="readout-val live">LIVE</div>
</div>
</div>
<div class="main-layout">
<div class="left-controls">
<div class="section">
<div class="section-label">Transport</div>
<div class="btn-row">
<button class="push-btn" type="button" data-action="play">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Play</span></span>
</button>
<button class="push-btn active" type="button" data-action="rec">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Rec</span></span>
</button>
<button class="push-btn" type="button" data-action="stop">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Stop</span></span>
</button>
<button class="push-btn active" type="button" data-action="loop">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Loop</span></span>
</button>
<button class="push-btn" type="button" data-action="fx">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">FX</span></span>
</button>
</div>
</div>
<div class="section">
<div class="section-label">Routing</div>
<div class="toggle-row">
<div class="toggle-unit">
<button class="toggle-sw on" type="button" data-toggle="mono" style="--led-col:#00e8cc">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Mono</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw" type="button" data-toggle="reverb" style="--led-col:#c060ff">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Reverb</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw on" type="button" data-toggle="eq" style="--led-col:#ffaa00">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">EQ</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw" type="button" data-toggle="comp" style="--led-col:#ff3840">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Comp</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw on" type="button" data-toggle="gate" style="--led-col:#00e060">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Gate</span>
</div>
</div>
</div>
<div class="section">
<div class="section-label">Channel Mix</div>
<div class="fader-row" data-cd-syn-faderrow></div>
</div>
</div>
<div class="right-controls">
<div class="section-label rl">Level</div>
<div class="vu-row" data-cd-syn-vurow></div>
</div>
</div>
</div>
</div>
</section>/* ─── 06 Modular Synth Controls — audio control panel ──────── */
@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Rajdhani:wght@400;500;600;700&display=swap');
.cd-syn {
--cd-syn-panel: #1a1c22;
--cd-syn-inset: #14161b;
--cd-syn-text-dim: rgba(120,140,180,0.4);
--cd-syn-cyan: #00e8cc;
--cd-syn-amber: #ffaa00;
--cd-syn-red: #ff3840;
--cd-syn-green: #00e060;
--cd-syn-purple: #c060ff;
--cd-syn-bg: #11131a;
position: relative;
width: 100%;
min-height: 580px;
background: var(--cd-syn-bg);
font-family: 'Share Tech Mono', ui-monospace, monospace;
overflow: hidden;
box-sizing: border-box;
}
.cd-syn *,
.cd-syn *::before,
.cd-syn *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cd-syn .card {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 32px 16px;
}
.cd-syn .panel {
width: 100%;
max-width: 640px;
background: var(--cd-syn-panel);
border-radius: 16px;
padding: 28px;
box-shadow: 0 0 0 1px rgba(255,255,255,0.05), 0 2px 0 rgba(255,255,255,0.04), 0 4px 24px rgba(0,0,0,0.6), 0 1px 0 rgba(255,255,255,0.06) inset, 0 -1px 0 rgba(0,0,0,0.4) inset;
position: relative;
}
.cd-syn .panel::before {
content: '';
position: absolute;
inset: 0;
border-radius: 16px;
background-image: repeating-linear-gradient(90deg, transparent 0px, transparent 2px, rgba(255,255,255,0.007) 2px, rgba(255,255,255,0.007) 3px);
pointer-events: none;
}
.cd-syn .readout {
background: var(--cd-syn-inset);
border-radius: 8px;
padding: 11px 16px;
box-shadow: inset 0 2px 6px rgba(0,0,0,0.5);
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 18px;
gap: 8px;
}
.cd-syn .readout-item {
text-align: center;
}
.cd-syn .readout-key {
font-size: 7px;
letter-spacing: 3px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
margin-bottom: 3px;
}
.cd-syn .readout-val {
font-family: 'Share Tech Mono', monospace;
font-size: 13px;
letter-spacing: 2px;
color: var(--cd-syn-cyan);
text-shadow: 0 0 10px rgba(0,232,204,0.5);
}
.cd-syn .readout-val.live {
color: var(--cd-syn-green);
text-shadow: 0 0 10px rgba(0,224,96,0.5);
}
.cd-syn .section {
margin-bottom: 22px;
}
.cd-syn .section:last-child {
margin-bottom: 0;
}
.cd-syn .section-label {
font-family: 'Share Tech Mono', monospace;
font-size: 9px;
letter-spacing: 3px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
margin-bottom: 14px;
display: flex;
align-items: center;
gap: 8px;
}
.cd-syn .section-label::after {
content: '';
flex: 1;
height: 1px;
background: rgba(255,255,255,0.06);
}
.cd-syn .section-label.rl {
margin-bottom: 10px;
}
.cd-syn .main-layout {
display: flex;
gap: 22px;
align-items: flex-start;
}
.cd-syn .left-controls {
flex: 1;
}
.cd-syn .right-controls {
display: flex;
flex-direction: column;
gap: 4px;
}
/* Push buttons */
.cd-syn .btn-row {
display: flex;
gap: 12px;
align-items: center;
flex-wrap: wrap;
}
.cd-syn .push-btn {
position: relative;
cursor: pointer;
border: none;
background: none;
padding: 0;
outline: none;
}
.cd-syn .push-btn-body {
width: 72px;
height: 50px;
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
position: relative;
transition: transform 0.08s ease, box-shadow 0.08s ease;
background: var(--cd-syn-btn-color);
box-shadow: 0 6px 0 var(--cd-syn-btn-shadow), 0 7px 12px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.18), inset 0 -1px 0 rgba(0,0,0,0.3);
}
.cd-syn .push-btn:active .push-btn-body,
.cd-syn .push-btn.pressed .push-btn-body {
transform: translateY(4px);
box-shadow: 0 2px 0 var(--cd-syn-btn-shadow), 0 3px 6px rgba(0,0,0,0.5), inset 0 2px 4px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.08);
}
.cd-syn .push-btn-label {
font-family: 'Share Tech Mono', monospace;
font-size: 8px;
letter-spacing: 1.5px;
color: rgba(255,255,255,0.85);
text-transform: uppercase;
}
.cd-syn .btn-led {
width: 6px;
height: 6px;
border-radius: 50%;
background: rgba(0,0,0,0.4);
transition: background 0.2s, box-shadow 0.2s;
}
.cd-syn .push-btn.active .btn-led {
background: var(--cd-syn-led-color);
box-shadow: 0 0 6px var(--cd-syn-led-color), 0 0 14px var(--cd-syn-led-color);
}
.cd-syn .push-btn:nth-child(1) {
--cd-syn-btn-color: #1a2838;
--cd-syn-btn-shadow: #0e1820;
--cd-syn-led-color: #00e8cc;
}
.cd-syn .push-btn:nth-child(2) {
--cd-syn-btn-color: #281a10;
--cd-syn-btn-shadow: #180e08;
--cd-syn-led-color: #ffaa00;
}
.cd-syn .push-btn:nth-child(3) {
--cd-syn-btn-color: #281818;
--cd-syn-btn-shadow: #180808;
--cd-syn-led-color: #ff3840;
}
.cd-syn .push-btn:nth-child(4) {
--cd-syn-btn-color: #182818;
--cd-syn-btn-shadow: #081808;
--cd-syn-led-color: #00e060;
}
.cd-syn .push-btn:nth-child(5) {
--cd-syn-btn-color: #1e1a30;
--cd-syn-btn-shadow: #100e20;
--cd-syn-led-color: #c060ff;
}
/* Toggles */
.cd-syn .toggle-row {
display: flex;
gap: 22px;
align-items: center;
flex-wrap: wrap;
}
.cd-syn .toggle-unit {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
.cd-syn .toggle-label {
font-size: 8px;
letter-spacing: 2px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
}
.cd-syn .toggle-sw {
position: relative;
width: 60px;
height: 28px;
cursor: pointer;
border-radius: 6px;
background: var(--cd-syn-inset);
border: none;
padding: 3px;
box-shadow: inset 0 2px 6px rgba(0,0,0,0.6), inset 0 1px 2px rgba(0,0,0,0.8), 0 1px 0 rgba(255,255,255,0.06);
}
.cd-syn .toggle-thumb {
display: block;
width: 26px;
height: 22px;
border-radius: 4px;
background: linear-gradient(180deg, #2e3248 0%, #22263a 100%);
box-shadow: 0 3px 0 #12141e, 0 4px 8px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.12);
transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.cd-syn .toggle-sw.on .toggle-thumb {
transform: translateX(28px);
}
.cd-syn .toggle-sw-led {
position: absolute;
width: 4px;
height: 4px;
border-radius: 50%;
top: 50%;
right: 7px;
transform: translateY(-50%);
background: rgba(0,0,0,0.5);
transition: background 0.2s, box-shadow 0.2s;
}
.cd-syn .toggle-sw.on .toggle-sw-led {
background: var(--led-col);
box-shadow: 0 0 6px var(--led-col);
}
/* Faders */
.cd-syn .fader-row {
display: flex;
gap: 18px;
align-items: flex-end;
flex-wrap: wrap;
}
.cd-syn .fader-unit {
display: flex;
flex-direction: column;
align-items: center;
gap: 7px;
}
.cd-syn .fader-track-wrap {
width: 28px;
height: 120px;
background: var(--cd-syn-inset);
border-radius: 6px;
box-shadow: inset 0 2px 6px rgba(0,0,0,0.6), inset 0 1px 3px rgba(0,0,0,0.8), 0 1px 0 rgba(255,255,255,0.05);
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.cd-syn .fader-track-wrap::before {
content: '';
position: absolute;
left: 4px;
right: 4px;
top: 10px;
bottom: 10px;
background: repeating-linear-gradient(to bottom, rgba(255,255,255,0.06) 0px, rgba(255,255,255,0.06) 1px, transparent 1px, transparent 10px);
pointer-events: none;
}
.cd-syn .fader-thumb {
width: 24px;
height: 20px;
border-radius: 4px;
background: linear-gradient(180deg, #3a3f58 0%, #2a2e44 100%);
box-shadow: 0 3px 0 #141620, 0 4px 8px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.15);
position: absolute;
cursor: ns-resize;
user-select: none;
touch-action: none;
z-index: 2;
}
.cd-syn .fader-fill {
position: absolute;
bottom: 10px;
left: 10px;
right: 10px;
border-radius: 2px;
background: linear-gradient(to top, var(--cd-syn-fader-color), transparent);
opacity: 0.5;
pointer-events: none;
}
.cd-syn .fader-label {
font-size: 8px;
letter-spacing: 2px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
}
.cd-syn .fader-value {
font-size: 10px;
font-family: 'Share Tech Mono', monospace;
letter-spacing: 1px;
min-height: 16px;
color: var(--cd-syn-fader-color);
}
/* VU */
.cd-syn .vu-row {
display: flex;
gap: 9px;
align-items: flex-end;
margin-left: 8px;
}
.cd-syn .vu-bar-wrap {
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
}
.cd-syn .vu-track {
width: 13px;
height: 120px;
background: var(--cd-syn-inset);
border-radius: 4px;
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6);
display: flex;
flex-direction: column-reverse;
overflow: hidden;
gap: 1px;
padding: 3px;
}
.cd-syn .vu-seg {
width: 100%;
height: 7px;
border-radius: 2px;
background: var(--cd-syn-seg-color);
opacity: 0.15;
transition: opacity 0.08s;
flex-shrink: 0;
}
.cd-syn .vu-seg.lit {
opacity: 1;
box-shadow: 0 0 6px var(--cd-syn-seg-color);
}
.cd-syn .vu-label {
font-size: 8px;
letter-spacing: 2px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
}
@media (max-width: 720px) {
.cd-syn .main-layout {
flex-direction: column;
}
.cd-syn .right-controls {
width: 100%;
}
.cd-syn .vu-row {
justify-content: flex-start;
margin-left: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.cd-syn .toggle-thumb {
transition: none !important;
}
.cd-syn .vu-seg {
transition: none !important;
}
}/* ─── 06 Modular Synth Controls — audio control panel ──────── */
@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Rajdhani:wght@400;500;600;700&display=swap');
.cd-syn {
--cd-syn-panel: #1a1c22;
--cd-syn-inset: #14161b;
--cd-syn-text-dim: rgba(120,140,180,0.4);
--cd-syn-cyan: #00e8cc;
--cd-syn-amber: #ffaa00;
--cd-syn-red: #ff3840;
--cd-syn-green: #00e060;
--cd-syn-purple: #c060ff;
--cd-syn-bg: #11131a;
position: relative;
width: 100%;
min-height: 580px;
background: var(--cd-syn-bg);
font-family: 'Share Tech Mono', ui-monospace, monospace;
overflow: hidden;
box-sizing: border-box;
}
.cd-syn *,
.cd-syn *::before,
.cd-syn *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cd-syn .card {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 32px 16px;
}
.cd-syn .panel {
width: 100%;
max-width: 640px;
background: var(--cd-syn-panel);
border-radius: 16px;
padding: 28px;
box-shadow: 0 0 0 1px rgba(255,255,255,0.05), 0 2px 0 rgba(255,255,255,0.04), 0 4px 24px rgba(0,0,0,0.6), 0 1px 0 rgba(255,255,255,0.06) inset, 0 -1px 0 rgba(0,0,0,0.4) inset;
position: relative;
}
.cd-syn .panel::before {
content: '';
position: absolute;
inset: 0;
border-radius: 16px;
background-image: repeating-linear-gradient(90deg, transparent 0px, transparent 2px, rgba(255,255,255,0.007) 2px, rgba(255,255,255,0.007) 3px);
pointer-events: none;
}
.cd-syn .readout {
background: var(--cd-syn-inset);
border-radius: 8px;
padding: 11px 16px;
box-shadow: inset 0 2px 6px rgba(0,0,0,0.5);
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 18px;
gap: 8px;
}
.cd-syn .readout-item {
text-align: center;
}
.cd-syn .readout-key {
font-size: 7px;
letter-spacing: 3px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
margin-bottom: 3px;
}
.cd-syn .readout-val {
font-family: 'Share Tech Mono', monospace;
font-size: 13px;
letter-spacing: 2px;
color: var(--cd-syn-cyan);
text-shadow: 0 0 10px rgba(0,232,204,0.5);
}
.cd-syn .readout-val.live {
color: var(--cd-syn-green);
text-shadow: 0 0 10px rgba(0,224,96,0.5);
}
.cd-syn .section {
margin-bottom: 22px;
}
.cd-syn .section:last-child {
margin-bottom: 0;
}
.cd-syn .section-label {
font-family: 'Share Tech Mono', monospace;
font-size: 9px;
letter-spacing: 3px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
margin-bottom: 14px;
display: flex;
align-items: center;
gap: 8px;
}
.cd-syn .section-label::after {
content: '';
flex: 1;
height: 1px;
background: rgba(255,255,255,0.06);
}
.cd-syn .section-label.rl {
margin-bottom: 10px;
}
.cd-syn .main-layout {
display: flex;
gap: 22px;
align-items: flex-start;
}
.cd-syn .left-controls {
flex: 1;
}
.cd-syn .right-controls {
display: flex;
flex-direction: column;
gap: 4px;
}
/* Push buttons */
.cd-syn .btn-row {
display: flex;
gap: 12px;
align-items: center;
flex-wrap: wrap;
}
.cd-syn .push-btn {
position: relative;
cursor: pointer;
border: none;
background: none;
padding: 0;
outline: none;
}
.cd-syn .push-btn-body {
width: 72px;
height: 50px;
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
position: relative;
transition: transform 0.08s ease, box-shadow 0.08s ease;
background: var(--cd-syn-btn-color);
box-shadow: 0 6px 0 var(--cd-syn-btn-shadow), 0 7px 12px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.18), inset 0 -1px 0 rgba(0,0,0,0.3);
}
.cd-syn .push-btn:active .push-btn-body,
.cd-syn .push-btn.pressed .push-btn-body {
transform: translateY(4px);
box-shadow: 0 2px 0 var(--cd-syn-btn-shadow), 0 3px 6px rgba(0,0,0,0.5), inset 0 2px 4px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.08);
}
.cd-syn .push-btn-label {
font-family: 'Share Tech Mono', monospace;
font-size: 8px;
letter-spacing: 1.5px;
color: rgba(255,255,255,0.85);
text-transform: uppercase;
}
.cd-syn .btn-led {
width: 6px;
height: 6px;
border-radius: 50%;
background: rgba(0,0,0,0.4);
transition: background 0.2s, box-shadow 0.2s;
}
.cd-syn .push-btn.active .btn-led {
background: var(--cd-syn-led-color);
box-shadow: 0 0 6px var(--cd-syn-led-color), 0 0 14px var(--cd-syn-led-color);
}
.cd-syn .push-btn:nth-child(1) {
--cd-syn-btn-color: #1a2838;
--cd-syn-btn-shadow: #0e1820;
--cd-syn-led-color: #00e8cc;
}
.cd-syn .push-btn:nth-child(2) {
--cd-syn-btn-color: #281a10;
--cd-syn-btn-shadow: #180e08;
--cd-syn-led-color: #ffaa00;
}
.cd-syn .push-btn:nth-child(3) {
--cd-syn-btn-color: #281818;
--cd-syn-btn-shadow: #180808;
--cd-syn-led-color: #ff3840;
}
.cd-syn .push-btn:nth-child(4) {
--cd-syn-btn-color: #182818;
--cd-syn-btn-shadow: #081808;
--cd-syn-led-color: #00e060;
}
.cd-syn .push-btn:nth-child(5) {
--cd-syn-btn-color: #1e1a30;
--cd-syn-btn-shadow: #100e20;
--cd-syn-led-color: #c060ff;
}
/* Toggles */
.cd-syn .toggle-row {
display: flex;
gap: 22px;
align-items: center;
flex-wrap: wrap;
}
.cd-syn .toggle-unit {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
.cd-syn .toggle-label {
font-size: 8px;
letter-spacing: 2px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
}
.cd-syn .toggle-sw {
position: relative;
width: 60px;
height: 28px;
cursor: pointer;
border-radius: 6px;
background: var(--cd-syn-inset);
border: none;
padding: 3px;
box-shadow: inset 0 2px 6px rgba(0,0,0,0.6), inset 0 1px 2px rgba(0,0,0,0.8), 0 1px 0 rgba(255,255,255,0.06);
}
.cd-syn .toggle-thumb {
display: block;
width: 26px;
height: 22px;
border-radius: 4px;
background: linear-gradient(180deg, #2e3248 0%, #22263a 100%);
box-shadow: 0 3px 0 #12141e, 0 4px 8px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.12);
transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.cd-syn .toggle-sw.on .toggle-thumb {
transform: translateX(28px);
}
.cd-syn .toggle-sw-led {
position: absolute;
width: 4px;
height: 4px;
border-radius: 50%;
top: 50%;
right: 7px;
transform: translateY(-50%);
background: rgba(0,0,0,0.5);
transition: background 0.2s, box-shadow 0.2s;
}
.cd-syn .toggle-sw.on .toggle-sw-led {
background: var(--led-col);
box-shadow: 0 0 6px var(--led-col);
}
/* Faders */
.cd-syn .fader-row {
display: flex;
gap: 18px;
align-items: flex-end;
flex-wrap: wrap;
}
.cd-syn .fader-unit {
display: flex;
flex-direction: column;
align-items: center;
gap: 7px;
}
.cd-syn .fader-track-wrap {
width: 28px;
height: 120px;
background: var(--cd-syn-inset);
border-radius: 6px;
box-shadow: inset 0 2px 6px rgba(0,0,0,0.6), inset 0 1px 3px rgba(0,0,0,0.8), 0 1px 0 rgba(255,255,255,0.05);
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.cd-syn .fader-track-wrap::before {
content: '';
position: absolute;
left: 4px;
right: 4px;
top: 10px;
bottom: 10px;
background: repeating-linear-gradient(to bottom, rgba(255,255,255,0.06) 0px, rgba(255,255,255,0.06) 1px, transparent 1px, transparent 10px);
pointer-events: none;
}
.cd-syn .fader-thumb {
width: 24px;
height: 20px;
border-radius: 4px;
background: linear-gradient(180deg, #3a3f58 0%, #2a2e44 100%);
box-shadow: 0 3px 0 #141620, 0 4px 8px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.15);
position: absolute;
cursor: ns-resize;
user-select: none;
touch-action: none;
z-index: 2;
}
.cd-syn .fader-fill {
position: absolute;
bottom: 10px;
left: 10px;
right: 10px;
border-radius: 2px;
background: linear-gradient(to top, var(--cd-syn-fader-color), transparent);
opacity: 0.5;
pointer-events: none;
}
.cd-syn .fader-label {
font-size: 8px;
letter-spacing: 2px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
}
.cd-syn .fader-value {
font-size: 10px;
font-family: 'Share Tech Mono', monospace;
letter-spacing: 1px;
min-height: 16px;
color: var(--cd-syn-fader-color);
}
/* VU */
.cd-syn .vu-row {
display: flex;
gap: 9px;
align-items: flex-end;
margin-left: 8px;
}
.cd-syn .vu-bar-wrap {
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
}
.cd-syn .vu-track {
width: 13px;
height: 120px;
background: var(--cd-syn-inset);
border-radius: 4px;
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6);
display: flex;
flex-direction: column-reverse;
overflow: hidden;
gap: 1px;
padding: 3px;
}
.cd-syn .vu-seg {
width: 100%;
height: 7px;
border-radius: 2px;
background: var(--cd-syn-seg-color);
opacity: 0.15;
transition: opacity 0.08s;
flex-shrink: 0;
}
.cd-syn .vu-seg.lit {
opacity: 1;
box-shadow: 0 0 6px var(--cd-syn-seg-color);
}
.cd-syn .vu-label {
font-size: 8px;
letter-spacing: 2px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
}
@media (max-width: 720px) {
.cd-syn .main-layout {
flex-direction: column;
}
.cd-syn .right-controls {
width: 100%;
}
.cd-syn .vu-row {
justify-content: flex-start;
margin-left: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.cd-syn .toggle-thumb {
transition: none !important;
}
.cd-syn .vu-seg {
transition: none !important;
}
}(() => {
const root = document.querySelector('.cd-syn');
if (!root) return;
// Push buttons
const modeReadout = root.querySelector('[data-cd-syn-mode]');
root.querySelectorAll('.push-btn').forEach(btn => {
btn.addEventListener('click', () => {
btn.classList.toggle('active');
const action = btn.dataset.action;
const modes = { play: 'PLAY', rec: 'RECORD', stop: 'STOPPED', loop: 'LOOP', fx: 'FX ON' };
if (modes[action] && modeReadout) modeReadout.textContent = modes[action];
});
});
// Toggles
root.querySelectorAll('.toggle-sw').forEach(sw => {
sw.addEventListener('click', () => sw.classList.toggle('on'));
});
// Faders
const faderRow = root.querySelector('[data-cd-syn-faderrow]');
const masterReadout = root.querySelector('[data-cd-syn-master]');
const faderData = [
{ label: 'CH.1', color: 'var(--cd-syn-cyan)', val: 87 },
{ label: 'CH.2', color: 'var(--cd-syn-cyan)', val: 62 },
{ label: 'CH.3', color: 'var(--cd-syn-amber)', val: 74 },
{ label: 'CH.4', color: 'var(--cd-syn-amber)', val: 90 },
{ label: 'SUB', color: 'var(--cd-syn-purple)', val: 55 },
{ label: 'MST', color: 'var(--cd-syn-green)', val: 87 },
];
const TRACK_H = 120, PADDING = 10, THUMB_H = 20;
const TRAVEL = TRACK_H - PADDING * 2 - THUMB_H;
faderData.forEach((fd, fi) => {
const unit = document.createElement('div');
unit.className = 'fader-unit';
unit.innerHTML = `
<div class="fader-value" style="--cd-syn-fader-color:${fd.color}">${fd.val}</div>
<div class="fader-track-wrap">
<div class="fader-fill" style="--cd-syn-fader-color:${fd.color}"></div>
<div class="fader-thumb"></div>
</div>
<div class="fader-label">${fd.label}</div>
`;
faderRow.appendChild(unit);
const thumb = unit.querySelector('.fader-thumb');
const fill = unit.querySelector('.fader-fill');
const valEl = unit.querySelector('.fader-value');
function setVal(v) {
v = Math.max(0, Math.min(100, v));
fd.val = Math.round(v);
const pct = v / 100;
thumb.style.top = (PADDING + TRAVEL * (1 - pct)) + 'px';
fill.style.height = (TRAVEL * pct + THUMB_H / 2) + 'px';
valEl.textContent = fd.val;
if (fi === 5 && masterReadout) masterReadout.textContent = fd.val;
}
setVal(fd.val);
let dragging = false, startY = 0, startVal = 0;
thumb.addEventListener('mousedown', e => {
dragging = true; startY = e.clientY; startVal = fd.val; e.preventDefault();
});
root.addEventListener('mousemove', e => {
if (!dragging) return;
setVal(startVal + ((startY - e.clientY) / TRAVEL) * 100);
});
root.addEventListener('mouseup', () => { dragging = false; });
root.addEventListener('mouseleave', () => { dragging = false; });
thumb.addEventListener('touchstart', e => {
dragging = true; startY = e.touches[0].clientY; startVal = fd.val;
}, { passive: true });
root.addEventListener('touchmove', e => {
if (!dragging) return;
setVal(startVal + ((startY - e.touches[0].clientY) / TRAVEL) * 100);
}, { passive: true });
root.addEventListener('touchend', () => { dragging = false; });
});
// VU meters
const vuRow = root.querySelector('[data-cd-syn-vurow]');
const vuData = [
{ label: 'L', color: '#00e8cc' },
{ label: 'R', color: '#00e8cc' },
];
const N_SEGS = 12;
const vuIntervals = [];
vuData.forEach((vu, vi) => {
const wrap = document.createElement('div');
wrap.className = 'vu-bar-wrap';
const track = document.createElement('div');
track.className = 'vu-track';
for (let s = 0; s < N_SEGS; s++) {
const seg = document.createElement('div');
seg.className = 'vu-seg';
const segColor = s >= N_SEGS - 2 ? '#ff3840' : s >= N_SEGS - 4 ? '#ffaa00' : vu.color;
seg.style.setProperty('--cd-syn-seg-color', segColor);
track.appendChild(seg);
}
const lbl = document.createElement('div');
lbl.className = 'vu-label';
lbl.textContent = vu.label;
wrap.appendChild(track);
wrap.appendChild(lbl);
vuRow.appendChild(wrap);
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (prefersReduced) return;
function animateVU() {
const segs = track.querySelectorAll('.vu-seg');
const base = 6;
const variation = Math.random() > 0.9 ? Math.floor(Math.random() * 3) : 0;
const level = base + variation;
segs.forEach((seg, si) => {
seg.classList.toggle('lit', si < level);
});
vuIntervals[vi] = setTimeout(animateVU, 80 + Math.random() * 60);
}
setTimeout(animateVU, vi * 40);
});
// BPM blink
const bpmReadout = root.querySelector('[data-cd-syn-bpm]');
if (bpmReadout) {
setInterval(() => {
bpmReadout.textContent = 124 + (Math.random() > 0.96 ? 1 : 0);
}, 500);
}
})();(() => {
const root = document.querySelector('.cd-syn');
if (!root) return;
// Push buttons
const modeReadout = root.querySelector('[data-cd-syn-mode]');
root.querySelectorAll('.push-btn').forEach(btn => {
btn.addEventListener('click', () => {
btn.classList.toggle('active');
const action = btn.dataset.action;
const modes = { play: 'PLAY', rec: 'RECORD', stop: 'STOPPED', loop: 'LOOP', fx: 'FX ON' };
if (modes[action] && modeReadout) modeReadout.textContent = modes[action];
});
});
// Toggles
root.querySelectorAll('.toggle-sw').forEach(sw => {
sw.addEventListener('click', () => sw.classList.toggle('on'));
});
// Faders
const faderRow = root.querySelector('[data-cd-syn-faderrow]');
const masterReadout = root.querySelector('[data-cd-syn-master]');
const faderData = [
{ label: 'CH.1', color: 'var(--cd-syn-cyan)', val: 87 },
{ label: 'CH.2', color: 'var(--cd-syn-cyan)', val: 62 },
{ label: 'CH.3', color: 'var(--cd-syn-amber)', val: 74 },
{ label: 'CH.4', color: 'var(--cd-syn-amber)', val: 90 },
{ label: 'SUB', color: 'var(--cd-syn-purple)', val: 55 },
{ label: 'MST', color: 'var(--cd-syn-green)', val: 87 },
];
const TRACK_H = 120, PADDING = 10, THUMB_H = 20;
const TRAVEL = TRACK_H - PADDING * 2 - THUMB_H;
faderData.forEach((fd, fi) => {
const unit = document.createElement('div');
unit.className = 'fader-unit';
unit.innerHTML = `
<div class="fader-value" style="--cd-syn-fader-color:${fd.color}">${fd.val}</div>
<div class="fader-track-wrap">
<div class="fader-fill" style="--cd-syn-fader-color:${fd.color}"></div>
<div class="fader-thumb"></div>
</div>
<div class="fader-label">${fd.label}</div>
`;
faderRow.appendChild(unit);
const thumb = unit.querySelector('.fader-thumb');
const fill = unit.querySelector('.fader-fill');
const valEl = unit.querySelector('.fader-value');
function setVal(v) {
v = Math.max(0, Math.min(100, v));
fd.val = Math.round(v);
const pct = v / 100;
thumb.style.top = (PADDING + TRAVEL * (1 - pct)) + 'px';
fill.style.height = (TRAVEL * pct + THUMB_H / 2) + 'px';
valEl.textContent = fd.val;
if (fi === 5 && masterReadout) masterReadout.textContent = fd.val;
}
setVal(fd.val);
let dragging = false, startY = 0, startVal = 0;
thumb.addEventListener('mousedown', e => {
dragging = true; startY = e.clientY; startVal = fd.val; e.preventDefault();
});
root.addEventListener('mousemove', e => {
if (!dragging) return;
setVal(startVal + ((startY - e.clientY) / TRAVEL) * 100);
});
root.addEventListener('mouseup', () => { dragging = false; });
root.addEventListener('mouseleave', () => { dragging = false; });
thumb.addEventListener('touchstart', e => {
dragging = true; startY = e.touches[0].clientY; startVal = fd.val;
}, { passive: true });
root.addEventListener('touchmove', e => {
if (!dragging) return;
setVal(startVal + ((startY - e.touches[0].clientY) / TRAVEL) * 100);
}, { passive: true });
root.addEventListener('touchend', () => { dragging = false; });
});
// VU meters
const vuRow = root.querySelector('[data-cd-syn-vurow]');
const vuData = [
{ label: 'L', color: '#00e8cc' },
{ label: 'R', color: '#00e8cc' },
];
const N_SEGS = 12;
const vuIntervals = [];
vuData.forEach((vu, vi) => {
const wrap = document.createElement('div');
wrap.className = 'vu-bar-wrap';
const track = document.createElement('div');
track.className = 'vu-track';
for (let s = 0; s < N_SEGS; s++) {
const seg = document.createElement('div');
seg.className = 'vu-seg';
const segColor = s >= N_SEGS - 2 ? '#ff3840' : s >= N_SEGS - 4 ? '#ffaa00' : vu.color;
seg.style.setProperty('--cd-syn-seg-color', segColor);
track.appendChild(seg);
}
const lbl = document.createElement('div');
lbl.className = 'vu-label';
lbl.textContent = vu.label;
wrap.appendChild(track);
wrap.appendChild(lbl);
vuRow.appendChild(wrap);
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (prefersReduced) return;
function animateVU() {
const segs = track.querySelectorAll('.vu-seg');
const base = 6;
const variation = Math.random() > 0.9 ? Math.floor(Math.random() * 3) : 0;
const level = base + variation;
segs.forEach((seg, si) => {
seg.classList.toggle('lit', si < level);
});
vuIntervals[vi] = setTimeout(animateVU, 80 + Math.random() * 60);
}
setTimeout(animateVU, vi * 40);
});
// BPM blink
const bpmReadout = root.querySelector('[data-cd-syn-bpm]');
if (bpmReadout) {
setInterval(() => {
bpmReadout.textContent = 124 + (Math.random() > 0.96 ? 1 : 0);
}, 500);
}
})();Here's a working CSS 3D Design from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Modular Synth Controls
Source: https://codefronts.com/design-styles/css-3d/modular-synth-controls/
A dark anodized panel with four interaction systems working simultaneously: push buttons with 3D translateY press travel and colored LED dots, toggle switches with a spring-overshoot thumb animation, six vertical faders with drag-to-set handles + fill bars + real-time value readouts, and dual VU meters with color-coded segments (cyan → amber → red) animating continuously. A readout bar at the top updates live as controls change. Share Tech Mono + Rajdhani. Best for audio production apps, game HUDs, creative dashboards, hardware-inspired control panels.
## HTML
```html
<section class="cd-syn" aria-label="Modular synth control panel demo">
<div class="card">
<div class="panel">
<div class="readout">
<div class="readout-item">
<div class="readout-key">Mode</div>
<div class="readout-val" data-cd-syn-mode>STUDIO</div>
</div>
<div class="readout-item">
<div class="readout-key">Master</div>
<div class="readout-val" data-cd-syn-master>87</div>
</div>
<div class="readout-item">
<div class="readout-key">BPM</div>
<div class="readout-val" data-cd-syn-bpm>124</div>
</div>
<div class="readout-item">
<div class="readout-key">Status</div>
<div class="readout-val live">LIVE</div>
</div>
</div>
<div class="main-layout">
<div class="left-controls">
<div class="section">
<div class="section-label">Transport</div>
<div class="btn-row">
<button class="push-btn" type="button" data-action="play">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Play</span></span>
</button>
<button class="push-btn active" type="button" data-action="rec">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Rec</span></span>
</button>
<button class="push-btn" type="button" data-action="stop">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Stop</span></span>
</button>
<button class="push-btn active" type="button" data-action="loop">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Loop</span></span>
</button>
<button class="push-btn" type="button" data-action="fx">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">FX</span></span>
</button>
</div>
</div>
<div class="section">
<div class="section-label">Routing</div>
<div class="toggle-row">
<div class="toggle-unit">
<button class="toggle-sw on" type="button" data-toggle="mono" style="--led-col:#00e8cc">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Mono</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw" type="button" data-toggle="reverb" style="--led-col:#c060ff">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Reverb</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw on" type="button" data-toggle="eq" style="--led-col:#ffaa00">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">EQ</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw" type="button" data-toggle="comp" style="--led-col:#ff3840">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Comp</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw on" type="button" data-toggle="gate" style="--led-col:#00e060">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Gate</span>
</div>
</div>
</div>
<div class="section">
<div class="section-label">Channel Mix</div>
<div class="fader-row" data-cd-syn-faderrow></div>
</div>
</div>
<div class="right-controls">
<div class="section-label rl">Level</div>
<div class="vu-row" data-cd-syn-vurow></div>
</div>
</div>
</div>
</div>
</section>
```
## CSS
```css
/* ─── 06 Modular Synth Controls — audio control panel ──────── */
@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Rajdhani:wght@400;500;600;700&display=swap');
.cd-syn {
--cd-syn-panel: #1a1c22;
--cd-syn-inset: #14161b;
--cd-syn-text-dim: rgba(120,140,180,0.4);
--cd-syn-cyan: #00e8cc;
--cd-syn-amber: #ffaa00;
--cd-syn-red: #ff3840;
--cd-syn-green: #00e060;
--cd-syn-purple: #c060ff;
--cd-syn-bg: #11131a;
position: relative;
width: 100%;
min-height: 580px;
background: var(--cd-syn-bg);
font-family: 'Share Tech Mono', ui-monospace, monospace;
overflow: hidden;
box-sizing: border-box;
}
.cd-syn *,
.cd-syn *::before,
.cd-syn *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cd-syn .card {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 32px 16px;
}
.cd-syn .panel {
width: 100%;
max-width: 640px;
background: var(--cd-syn-panel);
border-radius: 16px;
padding: 28px;
box-shadow: 0 0 0 1px rgba(255,255,255,0.05), 0 2px 0 rgba(255,255,255,0.04), 0 4px 24px rgba(0,0,0,0.6), 0 1px 0 rgba(255,255,255,0.06) inset, 0 -1px 0 rgba(0,0,0,0.4) inset;
position: relative;
}
.cd-syn .panel::before {
content: '';
position: absolute;
inset: 0;
border-radius: 16px;
background-image: repeating-linear-gradient(90deg, transparent 0px, transparent 2px, rgba(255,255,255,0.007) 2px, rgba(255,255,255,0.007) 3px);
pointer-events: none;
}
.cd-syn .readout {
background: var(--cd-syn-inset);
border-radius: 8px;
padding: 11px 16px;
box-shadow: inset 0 2px 6px rgba(0,0,0,0.5);
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 18px;
gap: 8px;
}
.cd-syn .readout-item {
text-align: center;
}
.cd-syn .readout-key {
font-size: 7px;
letter-spacing: 3px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
margin-bottom: 3px;
}
.cd-syn .readout-val {
font-family: 'Share Tech Mono', monospace;
font-size: 13px;
letter-spacing: 2px;
color: var(--cd-syn-cyan);
text-shadow: 0 0 10px rgba(0,232,204,0.5);
}
.cd-syn .readout-val.live {
color: var(--cd-syn-green);
text-shadow: 0 0 10px rgba(0,224,96,0.5);
}
.cd-syn .section {
margin-bottom: 22px;
}
.cd-syn .section:last-child {
margin-bottom: 0;
}
.cd-syn .section-label {
font-family: 'Share Tech Mono', monospace;
font-size: 9px;
letter-spacing: 3px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
margin-bottom: 14px;
display: flex;
align-items: center;
gap: 8px;
}
.cd-syn .section-label::after {
content: '';
flex: 1;
height: 1px;
background: rgba(255,255,255,0.06);
}
.cd-syn .section-label.rl {
margin-bottom: 10px;
}
.cd-syn .main-layout {
display: flex;
gap: 22px;
align-items: flex-start;
}
.cd-syn .left-controls {
flex: 1;
}
.cd-syn .right-controls {
display: flex;
flex-direction: column;
gap: 4px;
}
/* Push buttons */
.cd-syn .btn-row {
display: flex;
gap: 12px;
align-items: center;
flex-wrap: wrap;
}
.cd-syn .push-btn {
position: relative;
cursor: pointer;
border: none;
background: none;
padding: 0;
outline: none;
}
.cd-syn .push-btn-body {
width: 72px;
height: 50px;
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
position: relative;
transition: transform 0.08s ease, box-shadow 0.08s ease;
background: var(--cd-syn-btn-color);
box-shadow: 0 6px 0 var(--cd-syn-btn-shadow), 0 7px 12px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.18), inset 0 -1px 0 rgba(0,0,0,0.3);
}
.cd-syn .push-btn:active .push-btn-body,
.cd-syn .push-btn.pressed .push-btn-body {
transform: translateY(4px);
box-shadow: 0 2px 0 var(--cd-syn-btn-shadow), 0 3px 6px rgba(0,0,0,0.5), inset 0 2px 4px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.08);
}
.cd-syn .push-btn-label {
font-family: 'Share Tech Mono', monospace;
font-size: 8px;
letter-spacing: 1.5px;
color: rgba(255,255,255,0.85);
text-transform: uppercase;
}
.cd-syn .btn-led {
width: 6px;
height: 6px;
border-radius: 50%;
background: rgba(0,0,0,0.4);
transition: background 0.2s, box-shadow 0.2s;
}
.cd-syn .push-btn.active .btn-led {
background: var(--cd-syn-led-color);
box-shadow: 0 0 6px var(--cd-syn-led-color), 0 0 14px var(--cd-syn-led-color);
}
.cd-syn .push-btn:nth-child(1) {
--cd-syn-btn-color: #1a2838;
--cd-syn-btn-shadow: #0e1820;
--cd-syn-led-color: #00e8cc;
}
.cd-syn .push-btn:nth-child(2) {
--cd-syn-btn-color: #281a10;
--cd-syn-btn-shadow: #180e08;
--cd-syn-led-color: #ffaa00;
}
.cd-syn .push-btn:nth-child(3) {
--cd-syn-btn-color: #281818;
--cd-syn-btn-shadow: #180808;
--cd-syn-led-color: #ff3840;
}
.cd-syn .push-btn:nth-child(4) {
--cd-syn-btn-color: #182818;
--cd-syn-btn-shadow: #081808;
--cd-syn-led-color: #00e060;
}
.cd-syn .push-btn:nth-child(5) {
--cd-syn-btn-color: #1e1a30;
--cd-syn-btn-shadow: #100e20;
--cd-syn-led-color: #c060ff;
}
/* Toggles */
.cd-syn .toggle-row {
display: flex;
gap: 22px;
align-items: center;
flex-wrap: wrap;
}
.cd-syn .toggle-unit {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
.cd-syn .toggle-label {
font-size: 8px;
letter-spacing: 2px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
}
.cd-syn .toggle-sw {
position: relative;
width: 60px;
height: 28px;
cursor: pointer;
border-radius: 6px;
background: var(--cd-syn-inset);
border: none;
padding: 3px;
box-shadow: inset 0 2px 6px rgba(0,0,0,0.6), inset 0 1px 2px rgba(0,0,0,0.8), 0 1px 0 rgba(255,255,255,0.06);
}
.cd-syn .toggle-thumb {
display: block;
width: 26px;
height: 22px;
border-radius: 4px;
background: linear-gradient(180deg, #2e3248 0%, #22263a 100%);
box-shadow: 0 3px 0 #12141e, 0 4px 8px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.12);
transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.cd-syn .toggle-sw.on .toggle-thumb {
transform: translateX(28px);
}
.cd-syn .toggle-sw-led {
position: absolute;
width: 4px;
height: 4px;
border-radius: 50%;
top: 50%;
right: 7px;
transform: translateY(-50%);
background: rgba(0,0,0,0.5);
transition: background 0.2s, box-shadow 0.2s;
}
.cd-syn .toggle-sw.on .toggle-sw-led {
background: var(--led-col);
box-shadow: 0 0 6px var(--led-col);
}
/* Faders */
.cd-syn .fader-row {
display: flex;
gap: 18px;
align-items: flex-end;
flex-wrap: wrap;
}
.cd-syn .fader-unit {
display: flex;
flex-direction: column;
align-items: center;
gap: 7px;
}
.cd-syn .fader-track-wrap {
width: 28px;
height: 120px;
background: var(--cd-syn-inset);
border-radius: 6px;
box-shadow: inset 0 2px 6px rgba(0,0,0,0.6), inset 0 1px 3px rgba(0,0,0,0.8), 0 1px 0 rgba(255,255,255,0.05);
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.cd-syn .fader-track-wrap::before {
content: '';
position: absolute;
left: 4px;
right: 4px;
top: 10px;
bottom: 10px;
background: repeating-linear-gradient(to bottom, rgba(255,255,255,0.06) 0px, rgba(255,255,255,0.06) 1px, transparent 1px, transparent 10px);
pointer-events: none;
}
.cd-syn .fader-thumb {
width: 24px;
height: 20px;
border-radius: 4px;
background: linear-gradient(180deg, #3a3f58 0%, #2a2e44 100%);
box-shadow: 0 3px 0 #141620, 0 4px 8px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.15);
position: absolute;
cursor: ns-resize;
user-select: none;
touch-action: none;
z-index: 2;
}
.cd-syn .fader-fill {
position: absolute;
bottom: 10px;
left: 10px;
right: 10px;
border-radius: 2px;
background: linear-gradient(to top, var(--cd-syn-fader-color), transparent);
opacity: 0.5;
pointer-events: none;
}
.cd-syn .fader-label {
font-size: 8px;
letter-spacing: 2px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
}
.cd-syn .fader-value {
font-size: 10px;
font-family: 'Share Tech Mono', monospace;
letter-spacing: 1px;
min-height: 16px;
color: var(--cd-syn-fader-color);
}
/* VU */
.cd-syn .vu-row {
display: flex;
gap: 9px;
align-items: flex-end;
margin-left: 8px;
}
.cd-syn .vu-bar-wrap {
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
}
.cd-syn .vu-track {
width: 13px;
height: 120px;
background: var(--cd-syn-inset);
border-radius: 4px;
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6);
display: flex;
flex-direction: column-reverse;
overflow: hidden;
gap: 1px;
padding: 3px;
}
.cd-syn .vu-seg {
width: 100%;
height: 7px;
border-radius: 2px;
background: var(--cd-syn-seg-color);
opacity: 0.15;
transition: opacity 0.08s;
flex-shrink: 0;
}
.cd-syn .vu-seg.lit {
opacity: 1;
box-shadow: 0 0 6px var(--cd-syn-seg-color);
}
.cd-syn .vu-label {
font-size: 8px;
letter-spacing: 2px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
}
@media (max-width: 720px) {
.cd-syn .main-layout {
flex-direction: column;
}
.cd-syn .right-controls {
width: 100%;
}
.cd-syn .vu-row {
justify-content: flex-start;
margin-left: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.cd-syn .toggle-thumb {
transition: none !important;
}
.cd-syn .vu-seg {
transition: none !important;
}
}
```
## JavaScript
```js
(() => {
const root = document.querySelector('.cd-syn');
if (!root) return;
// Push buttons
const modeReadout = root.querySelector('[data-cd-syn-mode]');
root.querySelectorAll('.push-btn').forEach(btn => {
btn.addEventListener('click', () => {
btn.classList.toggle('active');
const action = btn.dataset.action;
const modes = { play: 'PLAY', rec: 'RECORD', stop: 'STOPPED', loop: 'LOOP', fx: 'FX ON' };
if (modes[action] && modeReadout) modeReadout.textContent = modes[action];
});
});
// Toggles
root.querySelectorAll('.toggle-sw').forEach(sw => {
sw.addEventListener('click', () => sw.classList.toggle('on'));
});
// Faders
const faderRow = root.querySelector('[data-cd-syn-faderrow]');
const masterReadout = root.querySelector('[data-cd-syn-master]');
const faderData = [
{ label: 'CH.1', color: 'var(--cd-syn-cyan)', val: 87 },
{ label: 'CH.2', color: 'var(--cd-syn-cyan)', val: 62 },
{ label: 'CH.3', color: 'var(--cd-syn-amber)', val: 74 },
{ label: 'CH.4', color: 'var(--cd-syn-amber)', val: 90 },
{ label: 'SUB', color: 'var(--cd-syn-purple)', val: 55 },
{ label: 'MST', color: 'var(--cd-syn-green)', val: 87 },
];
const TRACK_H = 120, PADDING = 10, THUMB_H = 20;
const TRAVEL = TRACK_H - PADDING * 2 - THUMB_H;
faderData.forEach((fd, fi) => {
const unit = document.createElement('div');
unit.className = 'fader-unit';
unit.innerHTML = `
<div class="fader-value" style="--cd-syn-fader-color:${fd.color}">${fd.val}</div>
<div class="fader-track-wrap">
<div class="fader-fill" style="--cd-syn-fader-color:${fd.color}"></div>
<div class="fader-thumb"></div>
</div>
<div class="fader-label">${fd.label}</div>
`;
faderRow.appendChild(unit);
const thumb = unit.querySelector('.fader-thumb');
const fill = unit.querySelector('.fader-fill');
const valEl = unit.querySelector('.fader-value');
function setVal(v) {
v = Math.max(0, Math.min(100, v));
fd.val = Math.round(v);
const pct = v / 100;
thumb.style.top = (PADDING + TRAVEL * (1 - pct)) + 'px';
fill.style.height = (TRAVEL * pct + THUMB_H / 2) + 'px';
valEl.textContent = fd.val;
if (fi === 5 && masterReadout) masterReadout.textContent = fd.val;
}
setVal(fd.val);
let dragging = false, startY = 0, startVal = 0;
thumb.addEventListener('mousedown', e => {
dragging = true; startY = e.clientY; startVal = fd.val; e.preventDefault();
});
root.addEventListener('mousemove', e => {
if (!dragging) return;
setVal(startVal + ((startY - e.clientY) / TRAVEL) * 100);
});
root.addEventListener('mouseup', () => { dragging = false; });
root.addEventListener('mouseleave', () => { dragging = false; });
thumb.addEventListener('touchstart', e => {
dragging = true; startY = e.touches[0].clientY; startVal = fd.val;
}, { passive: true });
root.addEventListener('touchmove', e => {
if (!dragging) return;
setVal(startVal + ((startY - e.touches[0].clientY) / TRAVEL) * 100);
}, { passive: true });
root.addEventListener('touchend', () => { dragging = false; });
});
// VU meters
const vuRow = root.querySelector('[data-cd-syn-vurow]');
const vuData = [
{ label: 'L', color: '#00e8cc' },
{ label: 'R', color: '#00e8cc' },
];
const N_SEGS = 12;
const vuIntervals = [];
vuData.forEach((vu, vi) => {
const wrap = document.createElement('div');
wrap.className = 'vu-bar-wrap';
const track = document.createElement('div');
track.className = 'vu-track';
for (let s = 0; s < N_SEGS; s++) {
const seg = document.createElement('div');
seg.className = 'vu-seg';
const segColor = s >= N_SEGS - 2 ? '#ff3840' : s >= N_SEGS - 4 ? '#ffaa00' : vu.color;
seg.style.setProperty('--cd-syn-seg-color', segColor);
track.appendChild(seg);
}
const lbl = document.createElement('div');
lbl.className = 'vu-label';
lbl.textContent = vu.label;
wrap.appendChild(track);
wrap.appendChild(lbl);
vuRow.appendChild(wrap);
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (prefersReduced) return;
function animateVU() {
const segs = track.querySelectorAll('.vu-seg');
const base = 6;
const variation = Math.random() > 0.9 ? Math.floor(Math.random() * 3) : 0;
const level = base + variation;
segs.forEach((seg, si) => {
seg.classList.toggle('lit', si < level);
});
vuIntervals[vi] = setTimeout(animateVU, 80 + Math.random() * 60);
}
setTimeout(animateVU, vi * 40);
});
// BPM blink
const bpmReadout = root.querySelector('[data-cd-syn-bpm]');
if (bpmReadout) {
setInterval(() => {
bpmReadout.textContent = 124 + (Math.random() > 0.96 ? 1 : 0);
}, 500);
}
})();
```Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS 3D Design from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Modular Synth Controls
Source: https://codefronts.com/design-styles/css-3d/modular-synth-controls/
A dark anodized panel with four interaction systems working simultaneously: push buttons with 3D translateY press travel and colored LED dots, toggle switches with a spring-overshoot thumb animation, six vertical faders with drag-to-set handles + fill bars + real-time value readouts, and dual VU meters with color-coded segments (cyan → amber → red) animating continuously. A readout bar at the top updates live as controls change. Share Tech Mono + Rajdhani. Best for audio production apps, game HUDs, creative dashboards, hardware-inspired control panels.
## HTML
```html
<section class="cd-syn" aria-label="Modular synth control panel demo">
<div class="card">
<div class="panel">
<div class="readout">
<div class="readout-item">
<div class="readout-key">Mode</div>
<div class="readout-val" data-cd-syn-mode>STUDIO</div>
</div>
<div class="readout-item">
<div class="readout-key">Master</div>
<div class="readout-val" data-cd-syn-master>87</div>
</div>
<div class="readout-item">
<div class="readout-key">BPM</div>
<div class="readout-val" data-cd-syn-bpm>124</div>
</div>
<div class="readout-item">
<div class="readout-key">Status</div>
<div class="readout-val live">LIVE</div>
</div>
</div>
<div class="main-layout">
<div class="left-controls">
<div class="section">
<div class="section-label">Transport</div>
<div class="btn-row">
<button class="push-btn" type="button" data-action="play">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Play</span></span>
</button>
<button class="push-btn active" type="button" data-action="rec">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Rec</span></span>
</button>
<button class="push-btn" type="button" data-action="stop">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Stop</span></span>
</button>
<button class="push-btn active" type="button" data-action="loop">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">Loop</span></span>
</button>
<button class="push-btn" type="button" data-action="fx">
<span class="push-btn-body"><span class="btn-led"></span><span class="push-btn-label">FX</span></span>
</button>
</div>
</div>
<div class="section">
<div class="section-label">Routing</div>
<div class="toggle-row">
<div class="toggle-unit">
<button class="toggle-sw on" type="button" data-toggle="mono" style="--led-col:#00e8cc">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Mono</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw" type="button" data-toggle="reverb" style="--led-col:#c060ff">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Reverb</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw on" type="button" data-toggle="eq" style="--led-col:#ffaa00">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">EQ</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw" type="button" data-toggle="comp" style="--led-col:#ff3840">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Comp</span>
</div>
<div class="toggle-unit">
<button class="toggle-sw on" type="button" data-toggle="gate" style="--led-col:#00e060">
<span class="toggle-thumb"></span>
<span class="toggle-sw-led"></span>
</button>
<span class="toggle-label">Gate</span>
</div>
</div>
</div>
<div class="section">
<div class="section-label">Channel Mix</div>
<div class="fader-row" data-cd-syn-faderrow></div>
</div>
</div>
<div class="right-controls">
<div class="section-label rl">Level</div>
<div class="vu-row" data-cd-syn-vurow></div>
</div>
</div>
</div>
</div>
</section>
```
## CSS
```css
/* ─── 06 Modular Synth Controls — audio control panel ──────── */
@import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&family=Rajdhani:wght@400;500;600;700&display=swap');
.cd-syn {
--cd-syn-panel: #1a1c22;
--cd-syn-inset: #14161b;
--cd-syn-text-dim: rgba(120,140,180,0.4);
--cd-syn-cyan: #00e8cc;
--cd-syn-amber: #ffaa00;
--cd-syn-red: #ff3840;
--cd-syn-green: #00e060;
--cd-syn-purple: #c060ff;
--cd-syn-bg: #11131a;
position: relative;
width: 100%;
min-height: 580px;
background: var(--cd-syn-bg);
font-family: 'Share Tech Mono', ui-monospace, monospace;
overflow: hidden;
box-sizing: border-box;
}
.cd-syn *,
.cd-syn *::before,
.cd-syn *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.cd-syn .card {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 32px 16px;
}
.cd-syn .panel {
width: 100%;
max-width: 640px;
background: var(--cd-syn-panel);
border-radius: 16px;
padding: 28px;
box-shadow: 0 0 0 1px rgba(255,255,255,0.05), 0 2px 0 rgba(255,255,255,0.04), 0 4px 24px rgba(0,0,0,0.6), 0 1px 0 rgba(255,255,255,0.06) inset, 0 -1px 0 rgba(0,0,0,0.4) inset;
position: relative;
}
.cd-syn .panel::before {
content: '';
position: absolute;
inset: 0;
border-radius: 16px;
background-image: repeating-linear-gradient(90deg, transparent 0px, transparent 2px, rgba(255,255,255,0.007) 2px, rgba(255,255,255,0.007) 3px);
pointer-events: none;
}
.cd-syn .readout {
background: var(--cd-syn-inset);
border-radius: 8px;
padding: 11px 16px;
box-shadow: inset 0 2px 6px rgba(0,0,0,0.5);
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 18px;
gap: 8px;
}
.cd-syn .readout-item {
text-align: center;
}
.cd-syn .readout-key {
font-size: 7px;
letter-spacing: 3px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
margin-bottom: 3px;
}
.cd-syn .readout-val {
font-family: 'Share Tech Mono', monospace;
font-size: 13px;
letter-spacing: 2px;
color: var(--cd-syn-cyan);
text-shadow: 0 0 10px rgba(0,232,204,0.5);
}
.cd-syn .readout-val.live {
color: var(--cd-syn-green);
text-shadow: 0 0 10px rgba(0,224,96,0.5);
}
.cd-syn .section {
margin-bottom: 22px;
}
.cd-syn .section:last-child {
margin-bottom: 0;
}
.cd-syn .section-label {
font-family: 'Share Tech Mono', monospace;
font-size: 9px;
letter-spacing: 3px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
margin-bottom: 14px;
display: flex;
align-items: center;
gap: 8px;
}
.cd-syn .section-label::after {
content: '';
flex: 1;
height: 1px;
background: rgba(255,255,255,0.06);
}
.cd-syn .section-label.rl {
margin-bottom: 10px;
}
.cd-syn .main-layout {
display: flex;
gap: 22px;
align-items: flex-start;
}
.cd-syn .left-controls {
flex: 1;
}
.cd-syn .right-controls {
display: flex;
flex-direction: column;
gap: 4px;
}
/* Push buttons */
.cd-syn .btn-row {
display: flex;
gap: 12px;
align-items: center;
flex-wrap: wrap;
}
.cd-syn .push-btn {
position: relative;
cursor: pointer;
border: none;
background: none;
padding: 0;
outline: none;
}
.cd-syn .push-btn-body {
width: 72px;
height: 50px;
border-radius: 8px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
position: relative;
transition: transform 0.08s ease, box-shadow 0.08s ease;
background: var(--cd-syn-btn-color);
box-shadow: 0 6px 0 var(--cd-syn-btn-shadow), 0 7px 12px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.18), inset 0 -1px 0 rgba(0,0,0,0.3);
}
.cd-syn .push-btn:active .push-btn-body,
.cd-syn .push-btn.pressed .push-btn-body {
transform: translateY(4px);
box-shadow: 0 2px 0 var(--cd-syn-btn-shadow), 0 3px 6px rgba(0,0,0,0.5), inset 0 2px 4px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.08);
}
.cd-syn .push-btn-label {
font-family: 'Share Tech Mono', monospace;
font-size: 8px;
letter-spacing: 1.5px;
color: rgba(255,255,255,0.85);
text-transform: uppercase;
}
.cd-syn .btn-led {
width: 6px;
height: 6px;
border-radius: 50%;
background: rgba(0,0,0,0.4);
transition: background 0.2s, box-shadow 0.2s;
}
.cd-syn .push-btn.active .btn-led {
background: var(--cd-syn-led-color);
box-shadow: 0 0 6px var(--cd-syn-led-color), 0 0 14px var(--cd-syn-led-color);
}
.cd-syn .push-btn:nth-child(1) {
--cd-syn-btn-color: #1a2838;
--cd-syn-btn-shadow: #0e1820;
--cd-syn-led-color: #00e8cc;
}
.cd-syn .push-btn:nth-child(2) {
--cd-syn-btn-color: #281a10;
--cd-syn-btn-shadow: #180e08;
--cd-syn-led-color: #ffaa00;
}
.cd-syn .push-btn:nth-child(3) {
--cd-syn-btn-color: #281818;
--cd-syn-btn-shadow: #180808;
--cd-syn-led-color: #ff3840;
}
.cd-syn .push-btn:nth-child(4) {
--cd-syn-btn-color: #182818;
--cd-syn-btn-shadow: #081808;
--cd-syn-led-color: #00e060;
}
.cd-syn .push-btn:nth-child(5) {
--cd-syn-btn-color: #1e1a30;
--cd-syn-btn-shadow: #100e20;
--cd-syn-led-color: #c060ff;
}
/* Toggles */
.cd-syn .toggle-row {
display: flex;
gap: 22px;
align-items: center;
flex-wrap: wrap;
}
.cd-syn .toggle-unit {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
}
.cd-syn .toggle-label {
font-size: 8px;
letter-spacing: 2px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
}
.cd-syn .toggle-sw {
position: relative;
width: 60px;
height: 28px;
cursor: pointer;
border-radius: 6px;
background: var(--cd-syn-inset);
border: none;
padding: 3px;
box-shadow: inset 0 2px 6px rgba(0,0,0,0.6), inset 0 1px 2px rgba(0,0,0,0.8), 0 1px 0 rgba(255,255,255,0.06);
}
.cd-syn .toggle-thumb {
display: block;
width: 26px;
height: 22px;
border-radius: 4px;
background: linear-gradient(180deg, #2e3248 0%, #22263a 100%);
box-shadow: 0 3px 0 #12141e, 0 4px 8px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.12);
transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.cd-syn .toggle-sw.on .toggle-thumb {
transform: translateX(28px);
}
.cd-syn .toggle-sw-led {
position: absolute;
width: 4px;
height: 4px;
border-radius: 50%;
top: 50%;
right: 7px;
transform: translateY(-50%);
background: rgba(0,0,0,0.5);
transition: background 0.2s, box-shadow 0.2s;
}
.cd-syn .toggle-sw.on .toggle-sw-led {
background: var(--led-col);
box-shadow: 0 0 6px var(--led-col);
}
/* Faders */
.cd-syn .fader-row {
display: flex;
gap: 18px;
align-items: flex-end;
flex-wrap: wrap;
}
.cd-syn .fader-unit {
display: flex;
flex-direction: column;
align-items: center;
gap: 7px;
}
.cd-syn .fader-track-wrap {
width: 28px;
height: 120px;
background: var(--cd-syn-inset);
border-radius: 6px;
box-shadow: inset 0 2px 6px rgba(0,0,0,0.6), inset 0 1px 3px rgba(0,0,0,0.8), 0 1px 0 rgba(255,255,255,0.05);
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.cd-syn .fader-track-wrap::before {
content: '';
position: absolute;
left: 4px;
right: 4px;
top: 10px;
bottom: 10px;
background: repeating-linear-gradient(to bottom, rgba(255,255,255,0.06) 0px, rgba(255,255,255,0.06) 1px, transparent 1px, transparent 10px);
pointer-events: none;
}
.cd-syn .fader-thumb {
width: 24px;
height: 20px;
border-radius: 4px;
background: linear-gradient(180deg, #3a3f58 0%, #2a2e44 100%);
box-shadow: 0 3px 0 #141620, 0 4px 8px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.15);
position: absolute;
cursor: ns-resize;
user-select: none;
touch-action: none;
z-index: 2;
}
.cd-syn .fader-fill {
position: absolute;
bottom: 10px;
left: 10px;
right: 10px;
border-radius: 2px;
background: linear-gradient(to top, var(--cd-syn-fader-color), transparent);
opacity: 0.5;
pointer-events: none;
}
.cd-syn .fader-label {
font-size: 8px;
letter-spacing: 2px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
}
.cd-syn .fader-value {
font-size: 10px;
font-family: 'Share Tech Mono', monospace;
letter-spacing: 1px;
min-height: 16px;
color: var(--cd-syn-fader-color);
}
/* VU */
.cd-syn .vu-row {
display: flex;
gap: 9px;
align-items: flex-end;
margin-left: 8px;
}
.cd-syn .vu-bar-wrap {
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
}
.cd-syn .vu-track {
width: 13px;
height: 120px;
background: var(--cd-syn-inset);
border-radius: 4px;
box-shadow: inset 0 2px 5px rgba(0,0,0,0.6);
display: flex;
flex-direction: column-reverse;
overflow: hidden;
gap: 1px;
padding: 3px;
}
.cd-syn .vu-seg {
width: 100%;
height: 7px;
border-radius: 2px;
background: var(--cd-syn-seg-color);
opacity: 0.15;
transition: opacity 0.08s;
flex-shrink: 0;
}
.cd-syn .vu-seg.lit {
opacity: 1;
box-shadow: 0 0 6px var(--cd-syn-seg-color);
}
.cd-syn .vu-label {
font-size: 8px;
letter-spacing: 2px;
color: var(--cd-syn-text-dim);
text-transform: uppercase;
}
@media (max-width: 720px) {
.cd-syn .main-layout {
flex-direction: column;
}
.cd-syn .right-controls {
width: 100%;
}
.cd-syn .vu-row {
justify-content: flex-start;
margin-left: 0;
}
}
@media (prefers-reduced-motion: reduce) {
.cd-syn .toggle-thumb {
transition: none !important;
}
.cd-syn .vu-seg {
transition: none !important;
}
}
```
## JavaScript
```js
(() => {
const root = document.querySelector('.cd-syn');
if (!root) return;
// Push buttons
const modeReadout = root.querySelector('[data-cd-syn-mode]');
root.querySelectorAll('.push-btn').forEach(btn => {
btn.addEventListener('click', () => {
btn.classList.toggle('active');
const action = btn.dataset.action;
const modes = { play: 'PLAY', rec: 'RECORD', stop: 'STOPPED', loop: 'LOOP', fx: 'FX ON' };
if (modes[action] && modeReadout) modeReadout.textContent = modes[action];
});
});
// Toggles
root.querySelectorAll('.toggle-sw').forEach(sw => {
sw.addEventListener('click', () => sw.classList.toggle('on'));
});
// Faders
const faderRow = root.querySelector('[data-cd-syn-faderrow]');
const masterReadout = root.querySelector('[data-cd-syn-master]');
const faderData = [
{ label: 'CH.1', color: 'var(--cd-syn-cyan)', val: 87 },
{ label: 'CH.2', color: 'var(--cd-syn-cyan)', val: 62 },
{ label: 'CH.3', color: 'var(--cd-syn-amber)', val: 74 },
{ label: 'CH.4', color: 'var(--cd-syn-amber)', val: 90 },
{ label: 'SUB', color: 'var(--cd-syn-purple)', val: 55 },
{ label: 'MST', color: 'var(--cd-syn-green)', val: 87 },
];
const TRACK_H = 120, PADDING = 10, THUMB_H = 20;
const TRAVEL = TRACK_H - PADDING * 2 - THUMB_H;
faderData.forEach((fd, fi) => {
const unit = document.createElement('div');
unit.className = 'fader-unit';
unit.innerHTML = `
<div class="fader-value" style="--cd-syn-fader-color:${fd.color}">${fd.val}</div>
<div class="fader-track-wrap">
<div class="fader-fill" style="--cd-syn-fader-color:${fd.color}"></div>
<div class="fader-thumb"></div>
</div>
<div class="fader-label">${fd.label}</div>
`;
faderRow.appendChild(unit);
const thumb = unit.querySelector('.fader-thumb');
const fill = unit.querySelector('.fader-fill');
const valEl = unit.querySelector('.fader-value');
function setVal(v) {
v = Math.max(0, Math.min(100, v));
fd.val = Math.round(v);
const pct = v / 100;
thumb.style.top = (PADDING + TRAVEL * (1 - pct)) + 'px';
fill.style.height = (TRAVEL * pct + THUMB_H / 2) + 'px';
valEl.textContent = fd.val;
if (fi === 5 && masterReadout) masterReadout.textContent = fd.val;
}
setVal(fd.val);
let dragging = false, startY = 0, startVal = 0;
thumb.addEventListener('mousedown', e => {
dragging = true; startY = e.clientY; startVal = fd.val; e.preventDefault();
});
root.addEventListener('mousemove', e => {
if (!dragging) return;
setVal(startVal + ((startY - e.clientY) / TRAVEL) * 100);
});
root.addEventListener('mouseup', () => { dragging = false; });
root.addEventListener('mouseleave', () => { dragging = false; });
thumb.addEventListener('touchstart', e => {
dragging = true; startY = e.touches[0].clientY; startVal = fd.val;
}, { passive: true });
root.addEventListener('touchmove', e => {
if (!dragging) return;
setVal(startVal + ((startY - e.touches[0].clientY) / TRAVEL) * 100);
}, { passive: true });
root.addEventListener('touchend', () => { dragging = false; });
});
// VU meters
const vuRow = root.querySelector('[data-cd-syn-vurow]');
const vuData = [
{ label: 'L', color: '#00e8cc' },
{ label: 'R', color: '#00e8cc' },
];
const N_SEGS = 12;
const vuIntervals = [];
vuData.forEach((vu, vi) => {
const wrap = document.createElement('div');
wrap.className = 'vu-bar-wrap';
const track = document.createElement('div');
track.className = 'vu-track';
for (let s = 0; s < N_SEGS; s++) {
const seg = document.createElement('div');
seg.className = 'vu-seg';
const segColor = s >= N_SEGS - 2 ? '#ff3840' : s >= N_SEGS - 4 ? '#ffaa00' : vu.color;
seg.style.setProperty('--cd-syn-seg-color', segColor);
track.appendChild(seg);
}
const lbl = document.createElement('div');
lbl.className = 'vu-label';
lbl.textContent = vu.label;
wrap.appendChild(track);
wrap.appendChild(lbl);
vuRow.appendChild(wrap);
const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
if (prefersReduced) return;
function animateVU() {
const segs = track.querySelectorAll('.vu-seg');
const base = 6;
const variation = Math.random() > 0.9 ? Math.floor(Math.random() * 3) : 0;
const level = base + variation;
segs.forEach((seg, si) => {
seg.classList.toggle('lit', si < level);
});
vuIntervals[vi] = setTimeout(animateVU, 80 + Math.random() * 60);
}
setTimeout(animateVU, vi * 40);
});
// BPM blink
const bpmReadout = root.querySelector('[data-cd-syn-bpm]');
if (bpmReadout) {
setInterval(() => {
bpmReadout.textContent = 124 + (Math.random() > 0.96 ? 1 : 0);
}, 500);
}
})();
```