diff --git a/themes/mms43/assets/css/main.css b/themes/mms43/assets/css/main.css
index 09a0f0a..7b20dff 100644
--- a/themes/mms43/assets/css/main.css
+++ b/themes/mms43/assets/css/main.css
@@ -2989,3 +2989,76 @@ a {
height: 400px;
}
}
+
+/* Aires de covoiturage (BNLC), sous les trajets de l'onglet Covoiturage */
+.carpool-areas {
+ margin-top: 1rem;
+ padding-top: 1rem;
+ border-top: 1px solid #e5e7eb;
+}
+
+.carpool-areas-title {
+ font-size: 15px;
+ font-weight: 700;
+ color: var(--color-text);
+ margin-bottom: 0.75rem;
+}
+
+.carpool-areas-group {
+ margin-bottom: 0.75rem;
+}
+
+.carpool-areas-group:last-child {
+ margin-bottom: 0;
+}
+
+.carpool-areas-subtitle {
+ font-size: 13px;
+ font-weight: 600;
+ color: #6b7280;
+ margin-bottom: 0.25rem;
+}
+
+.carpool-area-item {
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+ padding: 0.5rem;
+ border-radius: 8px;
+ cursor: pointer;
+ transition: background-color 0.2s;
+}
+
+.carpool-area-item:hover {
+ background-color: #f3f4f6;
+}
+
+.carpool-area-name {
+ font-size: 14px;
+ color: var(--color-text);
+}
+
+.carpool-area-address {
+ font-size: 13px;
+ color: #6b7280;
+}
+
+.carpool-area-tags {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.25rem;
+}
+
+.carpool-area-tag {
+ font-size: 12px;
+ font-weight: 500;
+ padding: 0.125rem 0.5rem;
+ border-radius: 4px;
+ background-color: #f3f4f6;
+ color: #374151;
+}
+
+.carpool-area-tag:first-child {
+ background-color: #fdf1e3;
+ color: var(--color-highlight);
+}
diff --git a/themes/mms43/layouts/_partials/search-results.html b/themes/mms43/layouts/_partials/search-results.html
index a423ee6..b95cefa 100644
--- a/themes/mms43/layouts/_partials/search-results.html
+++ b/themes/mms43/layouts/_partials/search-results.html
@@ -156,6 +156,32 @@
Aucun covoiturage disponible pour ce trajet.
{{ . }}
@@ -668,6 +694,88 @@ } + // Aires de covoiturage (BNLC), servies par le service geography via + // parcoursmob. Les propriétés BNLC sont éparses : tout est gardé. + function carpoolAreasFromData() { + const areas = ((window.__PARCOURSMOB_DATA__ || {}).results || {}).carpool_areas || {}; + const toArea = (feature, end) => { + const props = (feature && feature.properties) || {}; + return { + end: end, + name: props.nom || 'Aire de covoiturage', + address: props.adresse || null, + city: props.commune || null, + type: props.type || null, + places: typeof props.places === 'number' ? props.places : null, + placesPmr: typeof props.places_pmr === 'number' ? props.places_pmr : null, + coordinates: (feature && feature.geometry) ? feature.geometry.coordinates : null + }; + }; + return [] + .concat(((areas.departure || {}).results || []).map(f => toArea(f, 'departure'))) + .concat(((areas.arrival || {}).results || []).map(f => toArea(f, 'arrival'))) + .filter(area => area.coordinates); + } + + function carpoolAreasBlock() { + const areas = carpoolAreasFromData(); + return { + groups: [ + {end: 'departure', label: 'Près du départ', areas: areas.filter(a => a.end === 'departure')}, + {end: 'arrival', label: "Près de l'arrivée", areas: areas.filter(a => a.end === 'arrival')} + ].filter(group => group.areas.length), + + focusArea(area) { + if (window.parcoursmobMap && area.coordinates) { + window.parcoursmobMap.flyTo({center: area.coordinates, zoom: 14}); + } + } + }; + } + + function addCarpoolAreasLayer(map, areas) { + if (!areas.length || map.getSource('carpool-areas')) return; + + map.addSource('carpool-areas', { + type: 'geojson', + data: { + type: 'FeatureCollection', + features: areas.map(area => ({ + type: 'Feature', + geometry: {type: 'Point', coordinates: area.coordinates}, + properties: {name: area.name, city: area.city || '', type: area.type || ''} + })) + } + }); + + map.addLayer({ + id: 'carpool-areas-points', + type: 'circle', + source: 'carpool-areas', + paint: { + 'circle-radius': 6, + 'circle-color': getComputedStyle(document.documentElement) + .getPropertyValue('--color-highlight').trim() || '#F08F29', + 'circle-stroke-width': 2, + 'circle-stroke-color': '#ffffff' + } + }); + + map.on('click', 'carpool-areas-points', (e) => { + const props = e.features[0].properties; + const lines = [`${props.name}`]; + if (props.city) lines.push(props.city); + if (props.type) lines.push(props.type); + new maplibregl.Popup() + .setLngLat(e.features[0].geometry.coordinates) + .setHTML(lines.join('