Add audio pitch player to homepage hero

A 90-second spoken lightning talk (kokoro TTS) with a play/pause button and
progress bar in the hero CTA row. Registers audio-lines/play/pause icons.
This commit is contained in:
Ryan Malloy 2026-07-04 19:05:53 -06:00
parent 49ee8d200b
commit ad93d6cbbb
3 changed files with 48 additions and 1 deletions

View File

@ -9,7 +9,7 @@ export default defineConfig({
adapter: node({ mode: 'standalone' }), adapter: node({ mode: 'standalone' }),
integrations: [ integrations: [
react(), react(),
icon({ include: { lucide: ['plus', 'book-open', 'zap', 'cpu', 'activity', 'circuit-board', 'file-text', 'chevron-down', 'chevron-right', 'arrow-right', 'check-circle-2', 'clock', 'layers'] } }), icon({ include: { lucide: ['plus', 'book-open', 'zap', 'cpu', 'activity', 'circuit-board', 'file-text', 'chevron-down', 'chevron-right', 'arrow-right', 'check-circle-2', 'clock', 'layers', 'audio-lines', 'play', 'pause'] } }),
], ],
telemetry: false, telemetry: false,
devToolbar: { enabled: false }, devToolbar: { enabled: false },

Binary file not shown.

View File

@ -65,6 +65,19 @@ try {
Browse Notebooks Browse Notebooks
<Icon name="lucide:chevron-down" class="w-4 h-4" /> <Icon name="lucide:chevron-down" class="w-4 h-4" />
</a> </a>
<button
id="pitch-btn"
type="button"
aria-label="Play the 90-second audio pitch"
class="pitch-btn relative overflow-hidden inline-flex items-center gap-2 px-5 py-2.5 rounded-lg border border-slate-700 text-slate-300 hover:border-blue-500/50 hover:text-slate-100 font-medium transition-colors text-sm"
>
<Icon name="lucide:play" class="pitch-icon-play w-4 h-4 text-blue-400" />
<Icon name="lucide:pause" class="pitch-icon-pause w-4 h-4 text-blue-400 hidden" />
<span>Listen to the pitch</span>
<span class="text-slate-500 text-xs tabular-nums">90s</span>
<span id="pitch-progress" class="absolute bottom-0 left-0 h-0.5 w-0 bg-blue-500 transition-[width] duration-150"></span>
</button>
<audio id="pitch-audio" preload="none" src="/audio/spicebook-lightning-talk.mp3"></audio>
</div> </div>
</div> </div>
@ -188,4 +201,38 @@ try {
</p> </p>
</div> </div>
</footer> </footer>
<script>
// Hero pitch player: play/pause toggle, icon swap, and a progress bar
// along the button's bottom edge. Vanilla — no framework island needed.
const btn = document.getElementById('pitch-btn');
const audio = document.getElementById('pitch-audio') as HTMLAudioElement | null;
if (btn && audio) {
const iconPlay = btn.querySelector('.pitch-icon-play');
const iconPause = btn.querySelector('.pitch-icon-pause');
const progress = document.getElementById('pitch-progress');
btn.addEventListener('click', () => {
audio.paused ? audio.play() : audio.pause();
});
audio.addEventListener('play', () => {
iconPlay?.classList.add('hidden');
iconPause?.classList.remove('hidden');
});
const reset = () => {
iconPlay?.classList.remove('hidden');
iconPause?.classList.add('hidden');
};
audio.addEventListener('pause', reset);
audio.addEventListener('ended', () => {
reset();
if (progress) progress.style.width = '0';
});
audio.addEventListener('timeupdate', () => {
if (progress && audio.duration) {
progress.style.width = `${(audio.currentTime / audio.duration) * 100}%`;
}
});
}
</script>
</NotebookLayout> </NotebookLayout>