<div class="button-group"> <button class="lub-btn" id="playLubBtn">🔊 LUB (S1)</button> <button class="dub-btn" id="playDubBtn">🔊 DUB (S2)</button> <button class="auto-btn" id="autoCycleBtn">🔄 AUTO CYCLE</button> </div>
// combined lub-dub with timing function playLubDub() playLub(); activateLub(); statusSpan.innerHTML = '❤️ LUB (S1) – AV valves close'; setTimeout(() => playDub(); activateDub(); statusSpan.innerHTML = '💙 DUB (S2) – Semilunar valves close'; , 220); // natural split between lub & dub lub dub valves
.valve-icon font-size: 5rem; transition: transform 0.1s ease; filter: drop-shadow(0 4px 8px rgba(0,0,0,0.5)); button class="lub-btn" id="playLubBtn">
function activateLub() lubValveDiv.classList.add('active'); setTimeout(() => lubValveDiv.classList.remove('active'), 180); 🔊 LUB (S1)<
function startAutoCycle() if (autoInterval) clearInterval(autoInterval); isAuto = true; function nextBeat() if (!isAuto) return; playLubDub(); // initial immediate beat nextBeat(); autoInterval = setInterval(nextBeat, getCycleIntervalMs()); statusSpan.innerHTML = `🔄 AUTO CYCLE ($bpmSlider.value BPM)`;
// ----- Animation & Valve Activation ----- const lubValveDiv = document.getElementById('lubValve'); const dubValveDiv = document.getElementById('dubValve'); const statusSpan = document.getElementById('statusMsg');
h1 text-align: center; margin: 0 0 0.5rem 0; font-size: 2.2rem; letter-spacing: 2px; background: linear-gradient(135deg, #ffb7a7, #ffd6b0); -webkit-background-clip: text; background-clip: text; color: transparent;