Skip to content

Commit 3202a1b

Browse files
charliecreates[bot]CharlieHelpsmichaelmagan
authored
Add landing page hero video demo (#40)
* Add hero video demo to landing page * Add fallback text to landing page video * Style landing page video fallback content * Simplify landing page video fallback * Improve landing page video fallback text * Add accessible label to landing page video * Polish landing page hero video markup * Simplify hero video fallback markup * Use local hero demo video with controls * Match hero video aspect ratio * Add mute toggle for hero demo video * Improve hero video mute control * Refine hero video mute toggle * Tweak hero video layout * Add poster frame and safer playback * Clarify hero demo video playback --------- Co-authored-by: CharlieHelps <charlie@charlielabs.ai> Co-authored-by: michael magan <magan@tambo.co>
1 parent 9e8d9e8 commit 3202a1b

4 files changed

Lines changed: 61 additions & 27 deletions

File tree

public/videos/hero-demo-poster.jpg

27.8 KB
Loading

public/videos/hero-demo.mp4

7.75 MB
Binary file not shown.

src/app/page.tsx

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { Metadata } from "next";
22
import Link from "next/link";
33

4+
import { HeroDemoVideo } from "@/components/landing/hero-demo-video";
5+
46
export const metadata: Metadata = {
57
title: "StrudelLM - AI-Powered Live Coding Music",
68
description:
@@ -61,6 +63,8 @@ export default function LandingPage() {
6163
Powered by Strudel and AI.
6264
</p>
6365

66+
<HeroDemoVideo />
67+
6468
{/* CTA Button */}
6569
<Link
6670
href="/chat"
@@ -85,33 +89,6 @@ export default function LandingPage() {
8589
</div>
8690
</main>
8791

88-
{/* Video Section - uncomment when video asset is ready
89-
<section className="px-6 py-16 bg-muted/50">
90-
<div className="max-w-4xl mx-auto">
91-
<h2 className="text-2xl md:text-3xl font-semibold text-center mb-8">
92-
See it in action
93-
</h2>
94-
95-
<div className="relative aspect-video bg-muted rounded-xl overflow-hidden border border-border">
96-
<video
97-
className="w-full h-full object-cover"
98-
controls
99-
playsInline
100-
preload="metadata"
101-
>
102-
<source
103-
src="https://github.com/user-attachments/assets/YOUR_VIDEO.mp4"
104-
type="video/mp4"
105-
/>
106-
<p className="absolute inset-0 flex items-center justify-center text-muted-foreground">
107-
Your browser does not support the video tag.
108-
</p>
109-
</video>
110-
</div>
111-
</div>
112-
</section>
113-
*/}
114-
11592
{/* Features Section */}
11693
<section className="px-6 py-16">
11794
<div className="max-w-4xl mx-auto">
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
"use client";
2+
3+
import { useCallback, useRef, useState } from "react";
4+
5+
export function HeroDemoVideo() {
6+
const videoRef = useRef<HTMLVideoElement | null>(null);
7+
const [isMuted, setIsMuted] = useState(true);
8+
9+
const toggleMuted = useCallback(() => {
10+
setIsMuted((prevMuted) => {
11+
const video = videoRef.current;
12+
const nextMuted = !prevMuted;
13+
14+
if (video) {
15+
video.muted = nextMuted;
16+
if (!nextMuted) {
17+
void video.play().catch(() => {
18+
// Ignore: some browsers block play() depending on autoplay policy.
19+
});
20+
}
21+
}
22+
23+
return nextMuted;
24+
});
25+
}, []);
26+
27+
return (
28+
// Matches `public/videos/hero-demo.mp4` (1700x1080).
29+
<div className="relative mb-10 w-full aspect-[85/54] rounded-2xl overflow-hidden border border-border/50 shadow-2xl shadow-success/5 bg-black/50 backdrop-blur-sm">
30+
<video
31+
ref={videoRef}
32+
className="w-full h-full object-cover"
33+
autoPlay
34+
// Only loop while muted to reduce the chance of unexpected background audio.
35+
loop={isMuted}
36+
muted={isMuted}
37+
playsInline
38+
preload="metadata"
39+
poster="/videos/hero-demo-poster.jpg"
40+
aria-label="StrudelLM live coding music demo"
41+
>
42+
<source src="/videos/hero-demo.mp4" type="video/mp4" />
43+
Demo video (StrudelLM live coding with AI) is not supported in this browser.
44+
</video>
45+
46+
<button
47+
type="button"
48+
onClick={toggleMuted}
49+
aria-pressed={!isMuted}
50+
aria-label={isMuted ? "Unmute demo video audio" : "Mute demo video audio"}
51+
className="absolute bottom-3 right-3 rounded-lg border border-border/50 bg-background/80 px-3 py-1.5 text-sm text-foreground shadow-sm backdrop-blur hover:bg-background/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-success focus-visible:ring-offset-2 focus-visible:ring-offset-background"
52+
>
53+
{isMuted ? "Unmute" : "Mute"}
54+
</button>
55+
</div>
56+
);
57+
}

0 commit comments

Comments
 (0)