web-portfolio/components/sections/projects.tsx

80 lines
2.2 KiB
TypeScript
Raw Normal View History

import Reveal from '@/components/ui/reveal';
import SectionHeading from '@/components/ui/section-heading';
2026-11-03 09:00:14 -06:00
import { projects } from '@/lib/site';
const Projects = () => {
2026-11-03 09:00:14 -06:00
const rem = projects.length % 3;
const lastRowStart = projects.length - (rem || 3);
2026-11-03 09:00:14 -06:00
return (
<section id="work" className="container-page py-16">
<SectionHeading title="Selected Work">
Instant-Response Web Applications
</SectionHeading>
2026-11-03 09:00:14 -06:00
<div className="grid panel md:grid-cols-6">
{projects.map((project, i) => {
const inLastRow = i >= lastRowStart;
const colSpan =
inLastRow && rem === 1
? 'md:col-span-6'
: inLastRow && rem === 2
? 'md:col-span-3'
: 'md:col-span-2';
const rightRule =
i !== projects.length - 1 && i % 3 !== 2
? 'md:border-r'
: '';
const bottomRule = inLastRow ? 'md:border-b-0' : '';
const className = `group grid border-white/12 p-6 transition-colors not-last:border-b hover:bg-white/4 md:p-7 ${colSpan} ${rightRule} ${bottomRule}`;
2026-11-03 09:00:14 -06:00
const content = (
<Reveal delay={i * 60}>
<div className="flex h-full flex-col justify-between">
<div>
<h3 className="flex items-baseline justify-between gap-2 font-display text-lg font-normal tracking-tight text-ink group-hover:text-crest">
<span>{project.title}</span>
{project.href && (
<span
aria-hidden
className="text-sm text-aurora transition-transform group-hover:translate-x-0.5 group-hover:-translate-y-0.5"
>
↗
</span>
2026-11-03 09:00:14 -06:00
)}
</h3>
<p className="mt-2.5 text-sm leading-relaxed text-ink/70">
{project.blurb}
</p>
</div>
2026-11-03 09:00:14 -06:00
<p className="mt-8 border-t border-white/10 pt-3 font-mono text-xs text-aurora/90">
{project.stack}
</p>
</div>
</Reveal>
);
2026-11-03 09:00:14 -06:00
return project.href ? (
<a
key={project.title}
href={project.href}
target="_blank"
rel="noreferrer"
className={className}
>
{content}
</a>
) : (
<article key={project.title} className={className}>
{content}
</article>
);
})}
</div>
</section>
);
};
export default Projects;