39 lines
1.2 KiB
TypeScript
39 lines
1.2 KiB
TypeScript
"use client";
|
|
|
|
import dynamic from "next/dynamic";
|
|
import { useReducedMotion } from "framer-motion";
|
|
|
|
const HeroScene = dynamic(() => import("./HeroScene"), { ssr: false });
|
|
|
|
/**
|
|
* Reusable 3D animated background for internal hero sections.
|
|
* Drop this inside any `relative overflow-hidden` dark section.
|
|
*/
|
|
export default function HeroBackground() {
|
|
const shouldReduceMotion = useReducedMotion();
|
|
|
|
if (shouldReduceMotion) return null;
|
|
|
|
return (
|
|
<>
|
|
{/* 3D particle scene */}
|
|
<HeroScene />
|
|
|
|
{/* Cinematic radial vignette */}
|
|
<div className="pointer-events-none absolute inset-0 z-[1] bg-[radial-gradient(ellipse_80%_60%_at_50%_40%,transparent_0%,rgba(10,10,10,0.5)_55%,var(--ink)_100%)]" />
|
|
|
|
{/* Gradient fade to bottom */}
|
|
<div className="pointer-events-none absolute inset-0 z-[1] bg-gradient-to-b from-transparent via-transparent to-[var(--ink)]" />
|
|
|
|
{/* Scanlines */}
|
|
<div
|
|
className="pointer-events-none absolute inset-0 z-[2] opacity-[0.012]"
|
|
style={{
|
|
backgroundImage:
|
|
"repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(255,255,255,0.03) 2px, rgba(255,255,255,0.03) 4px)",
|
|
}}
|
|
/>
|
|
</>
|
|
);
|
|
}
|