/* eslint-disable react/prop-types */
/**
* DistritosBrowser · barra de filtros sticky + grid responsivo.
* Brief 1 §3.2 Filtros + Grid.
*
* - Filtros multi-select por Tipo · Región · Estado (chips)
* - Sticky behavior bajo el header
* - Reset visible cuando hay filtros activos
* - Cards 3-col desktop / 2-col tablet / 1-col mobile
* - Hover: image zoom + caption slide + cobre arrow badge
*/
const { useState: uS_Db, useEffect: uE_Db, useMemo: uM_Db } = React;
function FilterGroup({ label, options, selected, onToggle }) {
return (
{label}
{options.map((opt) => {
const isActive = selected.includes(opt);
return (
);
})}
);
}
function DistritoCard({ d, i }) {
const [hover, setHover] = uS_Db(false);
return (
setHover(true)}
onMouseLeave={() => setHover(false)}
style={dbStyles.card}
>
{/* tags arriba derecha */}
{d.tags.slice(0, 2).map((t, k) => (
{t}
))}
{d.verified && (
)}
{/* badge arrow al hover */}
{/* contenido inferior */}
{d.year}
{d.name}
{d.location}
{d.summary}
);
}
function DistritosBrowser() {
const [tipo, setTipo] = uS_Db([]);
const [region, setRegion] = uS_Db([]);
const [estado, setEstado] = uS_Db([]);
const [stuck, setStuck] = uS_Db(false);
const TYPES = window.DISTRITOS_TYPES || [];
const REGIONS = window.DISTRITOS_REGIONS || [];
const ESTADOS = window.DISTRITOS_ESTADOS || [];
const DATA = window.DISTRITOS_DATA || [];
const filtered = uM_Db(() => {
return DATA.filter((d) => {
if (tipo.length && !tipo.some(t => d.types.includes(t))) return false;
if (region.length && !region.includes(d.region)) return false;
if (estado.length && !estado.includes(d.estado)) return false;
return true;
});
}, [tipo, region, estado, DATA]);
const activeCount = tipo.length + region.length + estado.length;
uE_Db(() => {
const onScroll = () => setStuck(window.scrollY > 200);
window.addEventListener('scroll', onScroll, { passive: true });
return () => window.removeEventListener('scroll', onScroll);
}, []);
const toggle = (setter) => (val) => setter((prev) =>
prev.includes(val) ? prev.filter(x => x !== val) : [...prev, val]
);
const reset = () => { setTipo([]); setRegion([]); setEstado([]); };
return (
{/* Filter bar */}
{filtered.length}
de {DATA.length} distritos
{activeCount > 0 && (
)}
{/* Grid */}
{filtered.length > 0 ? (
{filtered.map((d, i) => (
))}
) : (
Ningún distrito coincide con esos filtros.
Prueba quitar alguno o explora el portafolio completo.
)}
{/* footer note */}
+1,900 proyectos · +40 distritos · 18 años originando lo extraordinario.
);
}
const dbStyles = {
section: {
background: 'var(--color-cream)',
},
filterBar: {
position: 'sticky',
top: 72,
zIndex: 30,
background: 'rgba(250, 249, 244, 0.96)',
backdropFilter: 'blur(12px)',
WebkitBackdropFilter: 'blur(12px)',
borderBottom: '1px solid rgba(33,52,64,0.05)',
transition: 'box-shadow 320ms ease, border-color 320ms ease',
},
filterInner: {
paddingBlock: 20,
display: 'flex',
flexDirection: 'column',
gap: 16,
},
filtersList: {
display: 'flex',
flexDirection: 'column',
gap: 16,
},
filterGroup: {
display: 'flex',
alignItems: 'baseline',
gap: 16,
flexWrap: 'wrap',
},
filterLabel: {
fontSize: 11,
fontWeight: 700,
letterSpacing: '0.18em',
color: 'var(--color-copper-fallback)',
textTransform: 'uppercase',
minWidth: 60,
},
chipRow: {
display: 'flex',
flexWrap: 'wrap',
gap: 8,
},
chip: {
display: 'inline-flex',
alignItems: 'center',
gap: 6,
padding: '6px 14px',
background: 'transparent',
border: '1px solid rgba(33,52,64,0.18)',
borderRadius: 999,
fontSize: 12,
fontWeight: 700,
letterSpacing: '0.06em',
color: 'var(--color-navy-deep)',
fontFamily: 'inherit',
transition: 'background 200ms ease, border-color 200ms ease, color 200ms ease',
whiteSpace: 'nowrap',
},
chipActive: {
background: 'var(--color-copper-fallback)',
borderColor: 'var(--color-copper-fallback)',
color: '#fff',
},
chipClose: {
display: 'inline-flex',
alignItems: 'center', justifyContent: 'center',
width: 14, height: 14,
background: 'rgba(255,255,255,0.22)',
borderRadius: 999,
},
filterMeta: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
gap: 16,
flexWrap: 'wrap',
paddingTop: 12,
borderTop: '1px solid rgba(33,52,64,0.08)',
},
resultCount: {
display: 'inline-flex',
alignItems: 'baseline',
gap: 8,
fontSize: 13,
color: 'var(--color-navy-medium)',
},
resultNum: {
fontSize: 20,
color: 'var(--color-navy-deep)',
fontWeight: 800,
fontFamily: 'ui-monospace, Menlo, Consolas, monospace',
},
resultText: { fontStyle: 'italic' },
resetBtn: {
display: 'inline-flex',
alignItems: 'center',
gap: 8,
padding: '8px 16px',
background: 'transparent',
border: '1px solid rgba(33,52,64,0.2)',
borderRadius: 999,
fontSize: 12,
fontWeight: 700,
letterSpacing: '0.06em',
color: 'var(--color-navy-deep)',
transition: 'border-color 200ms ease, color 200ms ease',
},
gridContainer: {
paddingTop: 48,
paddingBottom: 80,
},
grid: {
display: 'grid',
gridTemplateColumns: '1fr',
gap: 24,
},
card: {
display: 'block',
color: 'inherit',
textDecoration: 'none',
borderRadius: 4,
overflow: 'hidden',
background: '#000',
},
imgWrap: {
position: 'relative',
aspectRatio: '4 / 3',
overflow: 'hidden',
},
imgInner: {
position: 'absolute', inset: 0,
transition: 'transform 800ms cubic-bezier(0.16, 1, 0.3, 1)',
},
overlay: {
position: 'absolute', inset: 0,
/* Overlay más fuerte en el tercio inferior donde está el texto.
El año, nombre y location ahora tienen contraste suficiente sobre cualquier imagen. */
background: 'linear-gradient(180deg, rgba(33,52,64,0.05) 0%, rgba(33,52,64,0.20) 40%, rgba(15,27,35,0.75) 75%, rgba(15,27,35,0.95) 100%)',
transition: 'opacity 400ms ease',
},
tagsRow: {
position: 'absolute',
top: 16, right: 16, left: 16,
display: 'flex',
flexWrap: 'wrap',
gap: 6,
justifyContent: 'flex-end',
zIndex: 2,
},
tag: {
fontSize: 10,
fontWeight: 700,
letterSpacing: '0.14em',
color: '#fff',
textTransform: 'uppercase',
background: 'rgba(168, 107, 45, 0.85)',
padding: '4px 8px',
borderRadius: 2,
backdropFilter: 'blur(6px)',
},
verified: {
display: 'inline-flex',
alignItems: 'center', justifyContent: 'center',
width: 22, height: 22,
background: 'var(--color-mint-soft)',
color: 'var(--color-navy-deep)',
borderRadius: 999,
boxShadow: '0 2px 8px rgba(0,0,0,0.16)',
},
arrowBadge: {
position: 'absolute',
bottom: 16, right: 16,
width: 36, height: 36,
borderRadius: 999,
backgroundImage: 'url("assets/textures/cobre-patinado.svg")',
backgroundSize: 'cover',
display: 'flex',
alignItems: 'center', justifyContent: 'center',
color: '#fff',
transition: 'opacity 360ms ease, transform 600ms cubic-bezier(0.16,1,0.3,1)',
zIndex: 3,
},
cardContent: {
position: 'absolute',
left: 24, right: 24, bottom: 24,
color: '#fff',
zIndex: 2,
},
year: {
fontSize: 11, fontWeight: 700, letterSpacing: '0.18em',
color: 'var(--color-copper-fallback)',
fontFamily: 'ui-monospace, Menlo, Consolas, monospace',
textShadow: '0 1px 4px rgba(0,0,0,0.6)',
},
name: {
margin: '6px 0 0',
fontSize: 22,
fontWeight: 800,
color: '#fff',
letterSpacing: '-0.005em',
lineHeight: 1.15,
textShadow: '0 2px 12px rgba(0,0,0,0.45), 0 1px 3px rgba(0,0,0,0.3)',
},
loc: {
margin: '6px 0 0',
fontSize: 12,
color: '#fff',
letterSpacing: '0.12em',
textTransform: 'uppercase',
textShadow: '0 1px 6px rgba(0,0,0,0.55)',
fontWeight: 700,
},
summary: {
margin: 0,
fontSize: 13,
lineHeight: 1.55,
color: 'rgba(255,255,255,0.85)',
overflow: 'hidden',
transition: 'max-height 500ms cubic-bezier(0.16,1,0.3,1), opacity 400ms ease, margin-top 500ms cubic-bezier(0.16,1,0.3,1)',
},
emptyState: {
paddingBlock: 120,
textAlign: 'center',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: 16,
color: 'var(--color-navy-medium)',
},
emptyTitle: {
margin: '8px 0 0',
fontSize: 22, fontWeight: 700,
color: 'var(--color-navy-deep)',
},
emptyBody: { margin: 0, fontSize: 16 },
footNote: {
display: 'flex',
alignItems: 'center',
gap: 12,
paddingBlock: 32,
borderTop: '1px solid rgba(33,52,64,0.10)',
fontSize: 14,
color: 'var(--color-navy-medium)',
fontStyle: 'italic',
},
footDot: {
width: 8, height: 8, borderRadius: 999,
backgroundImage: 'url("assets/textures/cobre-patinado.svg")',
backgroundSize: 'cover',
},
};
const dbMQ = document.createElement('style');
dbMQ.textContent = `
@media (min-width: 900px) {
section[data-screen-label="02 Distritos Browser"] [style*="grid-template-columns: 1fr"][style*="gap: 24px"] {
grid-template-columns: repeat(2, 1fr) !important;
}
}
@media (min-width: 1024px) {
section[data-screen-label="02 Distritos Browser"] [style*="grid-template-columns: 1fr"][style*="gap: 24px"] {
grid-template-columns: repeat(3, 1fr) !important;
}
}
section[data-screen-label="02 Distritos Browser"] button[style*="rgba(33,52,64,0.2)"]:hover {
border-color: var(--color-copper-fallback) !important;
color: var(--color-copper-fallback) !important;
}
section[data-screen-label="02 Distritos Browser"] button[style*="rgba(33,52,64,0.18)"]:hover:not([style*="rgb(168, 107, 45)"]) {
border-color: var(--color-navy-deep) !important;
}
`;
document.head.appendChild(dbMQ);
window.DistritosBrowser = DistritosBrowser;