Portfolio
Dark, single-page personal portfolio: a counter loading screen, an HLS video hero with a floating nav and a cycling role line, a bento work grid, a journal list, a scroll-pinned parallax gallery with lightbox, count-up stats and a video contact footer. Self-contained dark palette, driven by GSAP and Framer Motion.
Preview
Installation
npx shadcn@latest add https://hirael.com/r/portfolio.jsonCode
components/templates/portfolio/portfolio.tsx
"use client";
import * as React from "react";
import { MotionConfig } from "framer-motion";
import { cn } from "@/lib/utils";
import { Contact } from "./contact";
import { Explorations } from "./explorations";
import { inter, instrumentSerif } from "./fonts";
import { Hero } from "./hero";
import { Journal } from "./journal";
import { LoadingScreen } from "./loading-screen";
import { SelectedWorks } from "./selected-works";
import { Stats } from "./stats";
import { PORTFOLIO_STYLES } from "./styles";
export default function Portfolio() {
const [isLoading, setIsLoading] = React.useState(true);
return (
<div
data-slot="portfolio"
className={cn(
inter.variable,
instrumentSerif.variable,
"min-h-svh bg-[hsl(var(--bg))] text-[hsl(var(--text))] antialiased",
)}
>
<style dangerouslySetInnerHTML={{ __html: PORTFOLIO_STYLES }} />
<MotionConfig reducedMotion="user">
{isLoading ? (
<LoadingScreen onComplete={() => setIsLoading(false)} />
) : null}
<Hero start={!isLoading} />
<SelectedWorks />
<Journal />
<Explorations />
<Stats />
<Contact />
</MotionConfig>
</div>
);
}
Dependencies
npm
gsapframer-motionhls.js