// sections/Portfolio.jsx — project archive · v2 print index function PortfolioSection({ onOpen }) { const [filter, setFilter] = React.useState('all'); const filters = [ { id: 'all', label: 'All' }, { id: 'fbp', label: 'FBP' }, { id: 'course', label: 'Courses' }, { id: 'internship', label: 'Internship' }, ]; const matches = (p) => { if (filter === 'all') return true; return p.kind === filter; }; const filtered = PROJECTS.filter(matches); return (
{/* Filter tray */}
{filters.map(f => ( setFilter(f.id)}> {f.label} ))}
{filtered.length} {filtered.length === 1 ? 'track' : 'tracks'}
{/* Index table */}
Trk
Title
Venue
Year
{filtered.map(p => ( onOpen(p)} /> ))}
{/* Card grid below */}
D · Featured

Featured

{filtered.slice(0, 3).map(p => ( onOpen(p)} /> ))}
); } function FilterTab({ active, onClick, children }) { const [hover, setHover] = React.useState(false); return ( ); } function ProjectRow({ project, onClick }) { const [hover, setHover] = React.useState(false); return (
setHover(true)} onMouseLeave={() => setHover(false)} className="pf-grid" style={{ display: 'grid', gridTemplateColumns: '52px 1fr 220px 120px 32px', gap: 16, padding: '16px 8px', alignItems: 'center', borderBottom: '1px solid var(--c-border)', background: hover ? '#FAFBFC' : 'transparent', cursor: 'pointer', transition: 'background 160ms', }}>
{project.number}
{project.title} — {project.subtitle}
{project.desc}
{project.venue}
{project.year}
); } function ProjectCardLocal({ project, onClick }) { const [hover, setHover] = React.useState(false); return (
setHover(true)} onMouseLeave={() => setHover(false)} style={{ background: '#FFFFFF', border: `1px solid ${hover ? 'var(--c-smoke)' : 'var(--c-border)'}`, overflow: 'hidden', transition: 'transform 240ms var(--ease-spring), border-color 180ms', transform: hover ? 'translateY(-3px)' : 'translateY(0)', cursor: 'pointer', display: 'flex', flexDirection: 'column', }}>
Track {project.number}
{project.number}
{project.year} · {project.venue}
{project.title}
{project.desc}
{project.tags.map((t, i) => {t.label})}
); } window.PortfolioSection = PortfolioSection;