Files
2026-07-06 21:55:50 -05:00

86 lines
3.4 KiB
TypeScript

"use client";
import { m, useReducedMotion } from "motion/react";
import { hero } from "@/lib/portfolio";
import { HeroCanvas } from "./HeroCanvas";
const paletteEventName = "blacksite:palette";
function openCommandPalette() {
if (typeof window === "undefined") {
return;
}
window.dispatchEvent(new CustomEvent(paletteEventName));
}
export function Hero() {
const shouldReduceMotion = useReducedMotion();
const headingFragments = hero.heading
.split(". ")
.map((fragment, index, fragments) => {
if (index < fragments.length - 1 && !fragment.endsWith(".")) {
return `${fragment}.`;
}
return fragment;
});
return (
<section
aria-labelledby="hero-heading"
className="relative isolate flex min-h-screen overflow-hidden bg-blacksite-bg px-5 py-28 text-blacksite-text sm:px-8 lg:px-12"
>
<HeroCanvas />
<div className="absolute inset-0 z-0 bg-[linear-gradient(90deg,rgba(3,5,6,0.98),rgba(3,5,6,0.78)_52%,rgba(3,5,6,0.96))]" />
<m.div
initial={shouldReduceMotion ? false : { opacity: 0, y: 18 }}
animate={shouldReduceMotion ? undefined : { opacity: 1, y: 0 }}
transition={{ duration: 0.6, ease: [0.22, 1, 0.36, 1] }}
className="relative z-10 mx-auto flex w-full max-w-7xl flex-col justify-center"
>
<div className="mb-8 inline-flex w-fit items-center gap-3 border border-blacksite-line bg-blacksite-surface/80 px-4 py-2 font-mono text-[11px] uppercase tracking-[0.16em] text-blacksite-muted shadow-[0_0_40px_rgba(0,0,0,0.35)] backdrop-blur-sm">
<span className="h-2 w-2 rounded-full bg-signal-green shadow-[0_0_14px_rgba(182,255,0,0.75)]" />
[STATUS: ONLINE]
</div>
<h1
id="hero-heading"
className="max-w-6xl font-display text-[clamp(3rem,9vw,7.5rem)] font-medium leading-[0.92] tracking-[-0.05em] text-balance text-blacksite-text"
>
{headingFragments.map((fragment) => (
<span key={fragment} className="block">
{fragment}
</span>
))}
</h1>
<p className="mt-6 max-w-2xl font-mono text-sm leading-7 text-blacksite-muted sm:text-base">
{hero.subline}
</p>
<div className="mt-10 flex flex-col gap-3 sm:flex-row">
<a
href="#work"
className="group inline-flex items-center justify-center border border-blacksite-line border-l-signal-orange bg-blacksite-surface px-6 py-3 font-mono text-xs uppercase tracking-[0.16em] text-blacksite-text transition-colors hover:border-signal-orange hover:bg-blacksite-surface2 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-signal-orange"
>
View Work
<span className="ml-3 text-signal-orange" aria-hidden="true">
/.
</span>
</a>
<button
type="button"
onClick={openCommandPalette}
className="inline-flex items-center justify-center border border-blacksite-line bg-blacksite-bg2/85 px-6 py-3 font-mono text-xs uppercase tracking-[0.16em] text-blacksite-muted transition-colors hover:border-signal-orange hover:text-blacksite-text focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-signal-orange"
>
K
</button>
</div>
</m.div>
</section>
);
}