feat(video): add YouTube lightbox to benefits section

Replaces static video link with a self-contained VideoCard component
that opens a native <dialog> lightbox with autoplay on open and
iframe src teardown on close. Includes pulsing ring animation on the
play button and a rounded-triangle SVG icon.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-09 14:16:00 -07:00
co-authored by Claude Sonnet 4.6
parent 615412c880
commit ce5e53c71f
7 changed files with 77 additions and 10 deletions
+51
View File
@@ -0,0 +1,51 @@
---
interface Props {
image: string;
alt: string;
videoUrl: string;
videoTitle: string;
}
const { image, alt, videoUrl, videoTitle } = Astro.props;
---
<button class="video-card" data-video-url={videoUrl} aria-haspopup="dialog" aria-label={`Watch video: ${videoTitle}`}>
<img src={`/assets/images/${image}`} alt={alt} />
<span aria-hidden="true">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50" height="50" fill="currentColor" aria-hidden="true">
<path d="M21 12.88L37.5 22.4A3 3 0 0 1 37.5 27.6L21 37.12A3 3 0 0 1 16.5 34.52L16.5 15.48A3 3 0 0 1 21 12.88Z" />
</svg>
</span>
</button>
<dialog class="video-dialog">
<div class="video-dialog-inner">
<button class="video-dialog-close" aria-label="Close video" autofocus>✕</button>
<div class="video-dialog-frame">
<iframe title={videoTitle} allowfullscreen allow="autoplay; encrypted-media"></iframe>
</div>
</div>
</dialog>
<script>
document.querySelectorAll('button.video-card[data-video-url]').forEach((card) => {
const dialog = card.nextElementSibling as HTMLDialogElement;
const iframe = dialog.querySelector('iframe') as HTMLIFrameElement;
const base = card.getAttribute('data-video-url')!;
const sep = base.includes('?') ? '&' : '?';
const closeBtn = dialog.querySelector('.video-dialog-close') as HTMLButtonElement;
closeBtn.addEventListener('click', () => dialog.close());
card.addEventListener('click', () => {
iframe.src = `${base}${sep}autoplay=1`;
dialog.showModal();
});
dialog.addEventListener('close', () => {
iframe.src = '';
});
// Close on backdrop click
dialog.addEventListener('click', (e) => {
if (e.target === dialog) dialog.close();
});
});
</script>