// Portfolio section — multiple layout variants const Portfolio = ({ style = 'editorial', onOpen }) => { const [filter, setFilter] = React.useState('All'); const tags = ['All', 'Web', 'AI', 'Commerce', 'SaaS']; const filtered = filter === 'All' ? PORTFOLIO : PORTFOLIO.filter(p => p.tag.toLowerCase().includes(filter.toLowerCase())); return (
{tags.map(t => ( ))}
{PORTFOLIO.length} CASES · 2023–2026
{style === 'editorial' && } {style === 'cards' && } {style === 'list' && }
); }; const PortfolioEditorial = ({ items, onOpen }) => (
{items.map((p, i) => { const big = i === 0; const span = big ? 12 : (i % 3 === 1 ? 7 : 5); return (
onOpen?.(p)} className="clickable" style={{gridColumn:`span ${span}`}}>
); })}
); const CaseCard = ({ p, big }) => (
{p.tag} {p.featured && Featured}
{p.year}

{p.name}

{p.summary}

{Icon.arrow()}
{p.metric[0].toUpperCase()}
{p.metric[1]}
ROLE
{p.role.join(', ')}
STACK
{p.stack.join(' · ')}
); const CaseVisual = ({ p }) => { // Simple abstract visualization unique per project const seed = p.id.charCodeAt(0); return ( {p.name.toUpperCase()} / {p.id.toUpperCase()} ); }; const PortfolioCards = ({ items, onOpen }) => (
{items.map(p => (
onOpen?.(p)} className="clickable">
))}
); const PortfolioList = ({ items, onOpen }) => (
{items.map((p, i) => (
onOpen?.(p)} className="clickable" style={{ display:'grid', gridTemplateColumns:'80px 1.5fr 1.2fr 1fr 60px', gap:24, alignItems:'center', padding:'24px 28px', borderTop: i>0 ? '1px solid var(--line)' : 'none', transition:'background .2s ease' }} onMouseEnter={e=>e.currentTarget.style.background='var(--bg-2)'} onMouseLeave={e=>e.currentTarget.style.background='transparent'}> {String(i+1).padStart(2,'0')} · {p.year}
{p.name}
{p.summary}
{p.metric[0].toUpperCase()}
{p.metric[1]}
{p.stack.join(' · ')}
{Icon.arrow()}
))}
); window.Portfolio = Portfolio;