.status background: #00000066; border-radius: 40px; padding: 0.6rem 1rem; text-align: center; font-family: monospace; font-size: 1.2rem; font-weight: bold; color: #c0e0ff; letter-spacing: 2px;
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)`;
function getCycleIntervalMs() const bpm = parseInt(bpmSlider.value, 10); // one cardiac cycle = 60/BPM seconds → milliseconds return (60 / bpm) * 1000;
.status background: #00000066; border-radius: 40px; padding: 0.6rem 1rem; text-align: center; font-family: monospace; font-size: 1.2rem; font-weight: bold; color: #c0e0ff; letter-spacing: 2px;
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)`;
function getCycleIntervalMs() const bpm = parseInt(bpmSlider.value, 10); // one cardiac cycle = 60/BPM seconds → milliseconds return (60 / bpm) * 1000;