Passagens com fade e 32 px, cena anterior termina em opacidade 0, sem visibility nem clip-path. 3D do hero como fundo ambiente, sob demanda e desligado em toque, aparelho fraco, saveData e movimento reduzido. Lenis fora do toque e salto direto em âncoras distantes. Vitrine só de clientes, até 3 capítulos, fixa só no desktop e carrossel no celular; vídeo só do projeto em cena com preload metadata. Rótulos mono a partir de 12 px e limão só no contato.
48 lines
1.6 KiB
TypeScript
48 lines
1.6 KiB
TypeScript
"use client";
|
|
|
|
import dynamic from "next/dynamic";
|
|
import { useEffect, useState } from "react";
|
|
import { useReducedMotion } from "@/app/hooks/useReducedMotion";
|
|
import { isLowPowerDevice } from "@/lib/device";
|
|
|
|
const HeroScene = dynamic(() => import("./HeroScene"), { ssr: false });
|
|
|
|
/**
|
|
* Reusable 3D animated background for internal hero sections.
|
|
* Drop this inside any `relative overflow-hidden` dark section.
|
|
* A cena WebGL só monta em aparelho que aguenta (sem toque, sem pouca CPU/memória, sem "economizar dados"):
|
|
* nos outros fica o fundo escuro, sem baixar o Three.js.
|
|
*/
|
|
export default function HeroBackground() {
|
|
const shouldReduceMotion = useReducedMotion();
|
|
const [capable, setCapable] = useState(false);
|
|
|
|
useEffect(() => {
|
|
setCapable(!isLowPowerDevice());
|
|
}, []);
|
|
|
|
if (shouldReduceMotion) return null;
|
|
|
|
return (
|
|
<>
|
|
{/* 3D particle scene */}
|
|
{capable && <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)",
|
|
}}
|
|
/>
|
|
</>
|
|
);
|
|
}
|