Retour au catalogue
Video Background
Section hero avec background video, titre large, description et double CTA centre. Bouton mute inclus.
videomedium Both Responsive a11y
bolddarkelegantuniversalagencyeventfullscreencentered
Theme
"use client";
import { motion } from "framer-motion";
import { ArrowRight, Volume2, VolumeX } from "lucide-react";
import { useState } from "react";
interface VideoBackgroundProps {
title?: string;
titleAccent?: string;
description?: string;
ctaLabel?: string;
ctaUrl?: string;
ctaSecondaryLabel?: string;
}
const EASE = [0.16, 1, 0.3, 1] as const;
export default function VideoBackground({
title = "Creez l'impossible",
titleAccent = "avec nous",
description = "Un studio creatif qui repousse les limites du design digital.",
ctaLabel = "Demarrer",
ctaUrl = "#contact",
ctaSecondaryLabel = "",
}: VideoBackgroundProps) {
const [muted, setMuted] = useState(true);
return (
<section
style={{
position: "relative",
minHeight: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "center",
overflow: "hidden",
background: "var(--color-background)",
}}
>
{/* Video background placeholder */}
<div
style={{
position: "absolute",
inset: 0,
background: "linear-gradient(160deg, var(--color-background) 0%, var(--color-background-alt) 50%, var(--color-background) 100%)",
}}
>
{/* Simulated video grain */}
<div
aria-hidden
style={{
position: "absolute",
inset: 0,
backgroundImage: "radial-gradient(circle at 20% 50%, color-mix(in srgb, var(--color-accent) 4%, transparent), transparent 50%), radial-gradient(circle at 80% 20%, color-mix(in srgb, var(--color-accent) 3%, transparent), transparent 40%)",
}}
/>
</div>
{/* Dark overlay */}
<div
style={{
position: "absolute",
inset: 0,
background: "color-mix(in srgb, var(--color-background) 60%, transparent)",
pointerEvents: "none",
}}
/>
{/* Content overlay */}
<div
style={{
position: "relative",
zIndex: 2,
maxWidth: "800px",
textAlign: "center",
padding: "0 var(--container-padding-x, 1.5rem)",
}}
>
<motion.h1
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.7, ease: EASE }}
style={{
fontFamily: "var(--font-sans)",
fontSize: "clamp(2.5rem, 6vw, 5rem)",
fontWeight: 800,
lineHeight: 1.05,
letterSpacing: "-0.03em",
color: "var(--color-foreground)",
marginBottom: "1.5rem",
}}
>
{title}{" "}
<span
style={{
color: "var(--color-accent)",
fontFamily: "var(--font-serif)",
fontWeight: 400,
fontStyle: "italic",
}}
>
{titleAccent}
</span>
</motion.h1>
<motion.p
initial={{ opacity: 0, y: 16 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.15, ease: EASE }}
style={{
fontSize: "1.1875rem",
lineHeight: 1.7,
color: "var(--color-foreground-muted)",
maxWidth: "560px",
margin: "0 auto 2.5rem",
}}
>
{description}
</motion.p>
<motion.div
initial={{ opacity: 0, y: 12 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: 0.28, ease: EASE }}
style={{ display: "flex", flexWrap: "wrap", justifyContent: "center", gap: "0.75rem" }}
>
<a
href={ctaUrl}
style={{
display: "inline-flex",
alignItems: "center",
gap: "8px",
padding: "0.875rem 2rem",
borderRadius: "var(--radius-full)",
background: "var(--color-accent)",
color: "var(--color-foreground)",
fontWeight: 600,
fontSize: "0.9375rem",
textDecoration: "none",
transition: "opacity var(--duration-normal) var(--ease-out)",
}}
>
{ctaLabel}
<ArrowRight style={{ width: 16, height: 16 }} />
</a>
{ctaSecondaryLabel && (
<a
href={ctaUrl}
style={{
display: "inline-flex",
alignItems: "center",
gap: "6px",
padding: "0.875rem 2rem",
borderRadius: "var(--radius-full)",
border: "1px solid var(--color-border)",
color: "var(--color-foreground-muted)",
fontWeight: 500,
fontSize: "0.9375rem",
textDecoration: "none",
transition: "all var(--duration-normal) var(--ease-out)",
}}
>
{ctaSecondaryLabel}
</a>
)}
</motion.div>
</div>
{/* Mute toggle */}
<motion.button
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.6 }}
onClick={() => setMuted((m) => !m)}
style={{
position: "absolute",
bottom: "2rem",
right: "2rem",
zIndex: 3,
width: "44px",
height: "44px",
borderRadius: "var(--radius-full)",
border: "1px solid var(--color-border)",
background: "color-mix(in srgb, var(--color-background) 80%, transparent)",
display: "flex",
alignItems: "center",
justifyContent: "center",
cursor: "pointer",
color: "var(--color-foreground-muted)",
}}
aria-label={muted ? "Activer le son" : "Couper le son"}
>
{muted ? (
<VolumeX style={{ width: 18, height: 18 }} />
) : (
<Volume2 style={{ width: 18, height: 18 }} />
)}
</motion.button>
</section>
);
}