/* ============================================================ SECTIONS 2 — Sobre mí, Proyectos (grid filtrable), Lightbox ============================================================ */ /* ---------- Sobre mí ---------- */ function About({ refMap }) { return (
{ if (refMap) refMap.current['sobre'] = el; }} style={{ background: 'var(--color-surface)', padding: 'clamp(64px, 9vh, 112px) 0', borderTop: '1px solid var(--color-border)', borderBottom: '1px solid var(--color-border)' }}>
Yan Trotta
Sobre mí

«Llevo el proyecto del concepto a la entrega: diseño, presupuesto, materiales y obra, con la misma exigencia en cada fase.»

{ABOUT.map((p, i) => (

{p}

))}
Habilidades clave
{SKILLS.map((s) => {s})}
Herramientas
{TOOLS.map((s) => {s})}
); } /* ---------- Proyectos ---------- */ function Projects({ refMap, onOpen }) { const [filter, setFilter] = React.useState('Todos'); const shown = PROJECTS.filter((p) => filter === 'Todos' || p.cat === filter); return (
{ if (refMap) refMap.current['proyectos'] = el; }} style={{ background: 'var(--color-bg)', padding: 'clamp(64px, 9vh, 112px) 0' }}>
{FILTERS.map((f) => setFilter(f)} count={f === 'Todos' ? PROJECTS.length : PROJECTS.filter((p) => p.cat === f).length} />)}
{shown.map((p, i) => (
))}
); } function FilterChip({ label, active, onClick, count }) { const [h, setH] = React.useState(false); return ( ); } function PortfolioTile({ p, i, onOpen }) { const [h, setH] = React.useState(false); return ( { e.preventDefault(); onOpen(p); }} onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)} style={{ display: 'block', position: 'relative', height: '100%', minHeight: 280, textDecoration: 'none', borderRadius: 'var(--radius-lg)', overflow: 'hidden', border: '1px solid var(--color-border)', boxShadow: h ? 'var(--shadow-md)' : 'var(--shadow-xs)', transform: h ? 'translateY(-3px)' : 'none', transition: 'box-shadow var(--dur-base) var(--ease-out), transform var(--dur-base) var(--ease-out)' }}> {p.title}
{p.cat}

{p.title}

{p.place}

{p.images && p.images.length > 1 ? ( {p.images.length} ) : null}
); } /* ---------- Lightbox (con galería) ---------- */ function Lightbox({ project, onClose }) { const gallery = project ? (project.images && project.images.length ? project.images : [project.image]) : []; const [idx, setIdx] = React.useState(0); const multi = gallery.length > 1; React.useEffect(() => { setIdx(0); }, [project]); React.useEffect(() => { if (!project) return; const fn = (e) => { if (e.key === 'Escape') onClose(); else if (e.key === 'ArrowRight' && multi) setIdx((i) => (i + 1) % gallery.length); else if (e.key === 'ArrowLeft' && multi) setIdx((i) => (i - 1 + gallery.length) % gallery.length); }; window.addEventListener('keydown', fn); document.body.style.overflow = 'hidden'; return () => { window.removeEventListener('keydown', fn); document.body.style.overflow = ''; }; }, [project, multi, gallery.length]); if (!project) return null; const go = (d) => setIdx((i) => (i + d + gallery.length) % gallery.length); return (
e.stopPropagation()} className="lb-card" style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1.3fr) minmax(300px, 0.86fr)', gridTemplateRows: 'minmax(0, 1fr)', background: 'var(--color-surface)', borderRadius: 'var(--radius-xl)', overflow: 'hidden', maxWidth: 1040, width: '100%', maxHeight: '90vh', boxShadow: 'var(--shadow-lg)' }}>
{project.title} {project.cat} {multi ? ( {idx + 1} / {gallery.length} ) : null}
{multi ? (
{gallery.map((src, i) => ( ))}
) : null}
{project.place}

{project.title}

{project.blurb}

{multi ?

Usa las flechas o las miniaturas para recorrer {gallery.length} imágenes.

: null}
); } function lbArrow(side) { return { position: 'absolute', top: '50%', [side]: 14, transform: 'translateY(-50%)', width: 46, height: 46, borderRadius: 'var(--radius-full)', border: 'none', background: 'var(--white)', color: 'var(--color-primary)', cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: '0 4px 16px rgba(10,21,29,0.35)', zIndex: 3 }; } Object.assign(window, { About, Projects, Lightbox });