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 'motion/react';
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';
const 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>
);
};
export default Portfolio;
Dependencies
shadcn registry
button
npm
gsapmotion