Join Waitlist

The Woodshed Groove Mojo

Hit the woodshed, get the groove, find your Mojo

Find your Mojo
The Solution

How it works

1

Loop, Slowdown and change the pitch of practice tracks

2

Transcribe and make notes of your lessons

3

Create practice playlists

Get early access

Be among the first to try it. Limited spots available.

Starting at $3.99/mo

We respect your privacy. No spam, ever.

able to break out (audit issue 17). const ORIGIN = "woodshed-mojo"; const KIND = "waitlist"; const SLUG = "woodshed-mojo"; const form = document.getElementById('waitlist-form'); const dialog = document.getElementById('name-dialog'); const successMsg = document.getElementById('success-msg'); let pendingEmail = ''; // Step 1: capture the email, then ask for an optional name before submitting. form.addEventListener('submit', (e) => { e.preventDefault(); pendingEmail = form.email.value.trim(); if (!pendingEmail) return; dialog.classList.remove('hidden'); dialog.classList.add('flex'); document.getElementById('first-name').focus(); }); // Step 2: Finish (with name) or Skip (without) — either way, one POST completes it. async function completeSignup(firstName, lastName) { dialog.classList.add('hidden'); dialog.classList.remove('flex'); const btn = form.querySelector('button'); btn.textContent = 'Joining...'; btn.disabled = true; try { const payload = { email: pendingEmail, origin: ORIGIN, kind: KIND }; if (firstName) payload.firstName = firstName; if (lastName) payload.lastName = lastName; const res = await fetch('/api/landing/' + encodeURIComponent(SLUG) + '/signup', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); const data = await res.json(); if (!res.ok) { if (data.error === 'Already signed up') { successMsg.textContent = "You're already on the list!"; } else { throw new Error(data.error); } } successMsg.classList.remove('hidden'); form.style.display = 'none'; } catch (err) { btn.textContent = 'Try again'; btn.disabled = false; console.error('Signup error:', err); } } document.getElementById('name-finish').addEventListener('click', () => { completeSignup( document.getElementById('first-name').value.trim(), document.getElementById('last-name').value.trim() ); }); document.getElementById('name-skip').addEventListener('click', () => completeSignup('', ''));