feat(portfolio): add operator profile with banner, publication, and honors
This commit is contained in:
68
components/portfolio/Hero.tsx
Normal file
68
components/portfolio/Hero.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
"use client";
|
||||
|
||||
import { m, useReducedMotion } from "motion/react";
|
||||
import { hero } from "@/lib/portfolio";
|
||||
import { HeroCanvas } from "./HeroCanvas";
|
||||
|
||||
const paletteEventName = "blacksite:palette";
|
||||
|
||||
export function Hero() {
|
||||
const shouldReduceMotion = useReducedMotion();
|
||||
|
||||
const openCommandPalette = () => {
|
||||
window.dispatchEvent(new CustomEvent(paletteEventName));
|
||||
};
|
||||
|
||||
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-[radial-gradient(circle_at_20%_20%,rgba(255,90,31,0.12),transparent_30%),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(64px,10vw,140px)] leading-[0.92] tracking-[-0.06em] text-balance text-blacksite-text"
|
||||
>
|
||||
{hero.heading}
|
||||
</h1>
|
||||
|
||||
<p className="mt-8 max-w-2xl text-lg leading-8 text-blacksite-muted sm:text-xl">
|
||||
{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"
|
||||
>
|
||||
Open Command Palette
|
||||
</button>
|
||||
</div>
|
||||
</m.div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user