`;
}).join('');
}
// Elements
const infoPanel = document.getElementById('infoPanel');
const infoPanelEmpty = document.getElementById('infoPanelEmpty');
const infoPanelContent = document.getElementById('infoPanelContent');
const infoPanelTitle = document.getElementById('infoPanelTitle');
const infoPanelItems = document.getElementById('infoPanelItems');
const mobileHint = document.getElementById('mobileHint');
const drawerOverlay = document.getElementById('drawerOverlay');
const mobileDrawer = document.getElementById('mobileDrawer');
const drawerTitle = document.getElementById('drawerTitle');
const drawerContent = document.getElementById('drawerContent');
const drawerClose = document.getElementById('drawerClose');
let selectedState = null;
function selectState(sigla) {
selectedState = sigla;
const nome = estadosNomes[sigla];
const items = coberturaPorEstado[sigla] || [];
// Update desktop panel
infoPanelEmpty.style.display = 'none';
infoPanelContent.style.display = 'block';
infoPanelTitle.textContent = nome;
infoPanelItems.innerHTML = renderItems(items);
// Mobile: show drawer
if (window.innerWidth < 1024) {
mobileHint.style.display = 'none';
drawerTitle.textContent = nome;
drawerContent.innerHTML = renderItems(items);
drawerOverlay.style.display = 'block';
setTimeout(() => {
drawerOverlay.classList.add('visible');
mobileDrawer.classList.add('visible');
}, 10);
}
}
function closeDrawer() {
drawerOverlay.classList.remove('visible');
mobileDrawer.classList.remove('visible');
setTimeout(() => {
drawerOverlay.style.display = 'none';
}, 300);
}
drawerClose.addEventListener('click', closeDrawer);
drawerOverlay.addEventListener('click', closeDrawer);
// Initialize map
const isMobile = window.innerWidth < 1024;
const map = L.map('map', {
center: [-14, -52],
zoom: isMobile ? 3.5 : 4,
zoomControl: true,
attributionControl: false,
scrollWheelZoom: false,
dragging: true,
doubleClickZoom: false,
touchZoom: true
});
L.tileLayer('https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png', {
subdomains: 'abcd',
minZoom: 3,
maxZoom: 8
}).addTo(map);
const defaultStyle = {
fillColor: '#4ade80',
weight: 1.5,
opacity: 1,
color: '#ffffff',
fillOpacity: 0.4
};
const hoverStyle = {
fillColor: '#22c55e',
weight: 2,
color: '#ffffff',
fillOpacity: 0.6
};
const selectedStyle = {
fillColor: '#16a34a',
weight: 2,
color: '#ffffff',
fillOpacity: 0.7
};
let geojsonLayer;
let selectedLayer = null;
function onEachFeature(feature, layer) {
const sigla = feature.properties.sigla;
layer.on({
mouseover: function(e) {
if (selectedLayer !== e.target) {
e.target.setStyle(hoverStyle);
}
},
mouseout: function(e) {
if (selectedLayer !== e.target) {
geojsonLayer.resetStyle(e.target);
}
},
click: function(e) {
L.DomEvent.stopPropagation(e);
if (selectedLayer) {
geojsonLayer.resetStyle(selectedLayer);
}
e.target.setStyle(selectedStyle);
selectedLayer = e.target;
if (sigla && estadosNomes[sigla]) {
selectState(sigla);
}
}
});
// Add pulse marker
if (sigla) {
const center = layer.getBounds().getCenter();
L.marker(center, {
icon: L.divIcon({
html: '
',
className: '',
iconSize: [12, 12],
iconAnchor: [6, 6]
}),
interactive: false
}).addTo(map);
}
}
// Load GeoJSON
fetch('https://raw.githubusercontent.com/codeforamerica/click_that_hood/master/public/data/brazil-states.geojson')
.then(res => res.json())
.then(data => {
geojsonLayer = L.geoJson(data, {
style: defaultStyle,
onEachFeature: onEachFeature
}).addTo(map);
})
.catch(err => console.error('Error loading map:', err));