3 changed files with 298 additions and 26 deletions
+9 -15
View File
@@ -1,20 +1,16 @@
---
title: Qui sommes-nous ?
savoirPlusLinks:
- text: Découvrez l'article consacré à la Maison de la Mobilité Solidaire de Haute-Loire dans le journal Le Bimsa
url: https://lebimsa.fr/l-actu-des-territoires/mobilite-en-haute-loire-la-solution-du-covoiturage/
- text: Découvrez l'interview de Willy Guieau, Directeur opérationnel de la Maison de la Mobilité Solidaire de Haute-Loire
url: https://www.linkedin.com/pulse/maison-de-la-mobilit%C3%A9-solidaire-haute-loire-humains-%C3%A0-coeur-bw18e/
- text: La Maison de la mobilité solidaire Haute-Loire bien implantée dans le territoire
url: https://www.auvergnerhonealpes-ee.fr/annuaires/actualites/detail/maison-de-la-mobilite-solidaire-haute-loire-bien-implantee-dans-le-territoire
- text: De nouvelles solutions sur le territoire Mézenc Loire Meygal
url: https://www.mezencloiremeygal.fr/wp-content/uploads/2026/07/Bulletin-CCMLM-2026-HD.pdf#page=25
- text: Le rapport annuel de lEtat 2026 « Agir sur la mobilité pour lutter contre la pauvreté » cite la MMS
url: https://drive.google.com/file/d/1T_U55KeyE_YSD2NtLxEagWTJVwVkmlY5/view
layout: qui-sommes-nous
title: "Qui sommes-nous ?"
layout: "qui-sommes-nous"
menu:
main:
weight: 4
savoirPlusLinks:
- text: "Découvrez l'article consacré à la Maison de la Mobilité Solidaire de Haute-Loire dans le journal Le Bimsa"
url: "https://lebimsa.fr/l-actu-des-territoires/mobilite-en-haute-loire-la-solution-du-covoiturage/"
- text: "Découvrez l'interview de Willy Guieau, Directeur opérationnel de la Maison de la Mobilité Solidaire de Haute-Loire"
url: "https://www.linkedin.com/pulse/maison-de-la-mobilit%C3%A9-solidaire-haute-loire-humains-%C3%A0-coeur-bw18e/"
- text: "La Maison de la mobilité solidaire Haute-Loire bien implantée dans le territoire"
url: "https://www.auvergnerhonealpes-ee.fr/annuaires/actualites/detail/maison-de-la-mobilite-solidaire-haute-loire-bien-implantee-dans-le-territoire"
---
La Maison de la Mobilité Solidaire Haute-Loire est un projet porté par les associations FIT, Solidarauto43 et FACE43, avec pour missions :
@@ -28,5 +24,3 @@ Le projet « Maison de la Mobilité Solidaire Haute-Loire » est lauréat du pro
Le programme TIMS est piloté par le réseau CLER, Mob'in, Auvergne-Rhône-Alpes Energie Environnement et le réseau des Agences Régionales de l'Energie et de l'Environnement.
La MMS bénéficie également du soutien financier de l'Etat via le PACTE des solidarités et de l'Agence Nationale de la Cohésion Territoriale, ainsi que de la MSA.
_Crédit photos : ©Marion-Joubert_
+117 -4
View File
@@ -2268,6 +2268,23 @@ a {
margin-right: 0.75rem;
}
/* Secondary count on the Covoiturage accordion: how many carpooling areas
were found. The accordion sits on --color-secondary, so this is a white
pill with the header's own green inside — legible on that background, and
clearly a different kind of count from the orange trip badge next to it. */
.accordion-badge-areas {
background-color: var(--color-white);
color: var(--color-secondary);
gap: 0.25rem;
padding: 0 0.5rem;
min-width: 0;
}
.accordion-badge-areas svg {
flex-shrink: 0;
}
.accordion-arrow {
width: 24px;
height: 24px;
@@ -2429,31 +2446,54 @@ a {
}
/* Map Markers */
/* MapLibre writes `transform: translate(-50%,-50%) translate(Xpx,Ypx)` on
.map-marker to position it, and rewrites it on every map frame. Any
transform or transition declared here would fight that — a hover scale
would also scale the pixel offset, and a transition would make the marker
lag behind the map. So .map-marker only reserves space; everything visual
lives on .map-marker-inner, which MapLibre never touches. */
.map-marker {
width: 36px;
height: 36px;
cursor: pointer;
}
.map-marker-inner {
width: 100%;
height: 100%;
border-radius: 10px;
border: 2px solid var(--color-white);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: transform 0.2s ease;
}
.map-marker:hover {
.map-marker-inner:hover {
transform: scale(1.1);
}
.map-marker-departure {
.map-marker-departure .map-marker-inner {
background-color: var(--color-secondary);
}
.map-marker-arrival {
.map-marker-arrival .map-marker-inner {
background-color: var(--color-highlight);
}
/* Carpooling areas: smaller than trip endpoints, they are context not
destinations. */
.map-marker-area {
width: 24px;
height: 24px;
}
.map-marker-area .map-marker-inner {
background-color: var(--color-highlight);
border-width: 1px;
}
/* MapLibre Popup Styling */
.maplibregl-popup-content {
padding: 12px 16px;
@@ -2989,3 +3029,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);
}
@@ -121,10 +121,20 @@
</div>
<!-- Covoiturage -->
<div class="result-accordion" x-data="{ open: false }">
<div class="result-accordion"
x-data="{ open: false, get areaCount() { return (results.carpool_areas?.departure?.number || 0) + (results.carpool_areas?.arrival?.number || 0); } }"
x-init="$watch('open', value => value ? showCarpoolAreaMarkers() : hideCarpoolAreaMarkers())">
<button type="button" class="accordion-header" @click="open = !open" :class="{ 'active': open }">
<span class="accordion-title">Covoiturage</span>
<span class="accordion-badge" x-text="results.carpools?.number || 0"></span>
<span class="accordion-badge accordion-badge-areas" x-show="areaCount" x-cloak
:title="areaCount + ' aire' + (areaCount > 1 ? 's' : '') + ' de covoiturage à proximité'">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M15 10.5a3 3 0 1 1 -6 0a3 3 0 0 1 6 0z"/>
<path d="M19.5 10.5c0 7.142 -7.5 11.25 -7.5 11.25s-7.5 -4.108 -7.5 -11.25a7.5 7.5 0 1 1 15 0z"/>
</svg>
<span x-text="areaCount"></span>
</span>
{{ if $iconArrow }}
<img src="{{ $iconArrow.RelPermalink }}" alt="" class="accordion-arrow" :class="{ 'open': open }" />
{{ end }}
@@ -156,6 +166,32 @@
<template x-if="!results.carpools?.number">
<p class="no-result-text">Aucun covoiturage disponible pour ce trajet.</p>
</template>
<!-- Aires de covoiturage (BNLC) autour du départ et de l'arrivée -->
<div class="carpool-areas" x-data="carpoolAreasBlock()" x-show="groups.length" x-cloak>
<div class="carpool-areas-title">Aires de covoiturage</div>
<template x-for="group in groups" :key="group.end">
<div class="carpool-areas-group">
<div class="carpool-areas-subtitle" x-text="group.label"></div>
<template x-for="(area, index) in group.areas" :key="group.end + '-' + index">
<div class="carpool-area-item" @click="focusArea(area)">
<span class="carpool-area-name" x-text="area.name"></span>
<span class="carpool-area-address" x-show="area.address || area.city">
<span x-text="area.address" x-show="area.address"></span>
<span x-show="area.address && area.city">&middot;</span>
<span x-text="area.city" x-show="area.city"></span>
</span>
<span class="carpool-area-tags">
<span class="carpool-area-tag" x-show="area.type" x-text="area.type"></span>
<span class="carpool-area-tag" x-show="area.places" x-text="area.places + ' place(s)'"></span>
<span class="carpool-area-tag" x-show="area.placesPmr" x-text="area.placesPmr + ' PMR'"></span>
</span>
</div>
</template>
</div>
</template>
</div>
{{ with .Params.contactCTA.carpool }}
<div class="accordion-cta">
<p>{{ . }}</p>
@@ -668,6 +704,127 @@
}
// 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});
}
}
};
}
// Marker glyph per BNLC type — same set as the back-office compact view.
function carpoolAreaIcon(type) {
const glyph = (body, width) => `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="white" stroke-width="${width || 2}" stroke-linecap="round" stroke-linejoin="round">${body}</svg>`;
switch (type) {
case 'Aire de covoiturage':
return glyph('<circle cx="7" cy="17" r="2"/><circle cx="17" cy="17" r="2"/><path d="M5 17h-2v-6l2 -5h9l4 5h1a2 2 0 0 1 2 2v4h-2m-4 0h-6"/>');
case 'Parking':
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="13" height="13"><text x="12" y="18.5" text-anchor="middle" font-family="ui-sans-serif, system-ui, sans-serif" font-size="20" font-weight="700" fill="white">P</text></svg>`;
case 'Parking relais':
return glyph('<circle cx="6" cy="17" r="2"/><circle cx="18" cy="17" r="2"/><path d="M4 17h-2v-11a1 1 0 0 1 1 -1h14a5 7 0 0 1 5 7v5h-2m-4 0h-8"/><path d="M2 10h15"/>');
case "Sortie d'autoroute":
return glyph('<path d="M4 21v-8a4 4 0 0 1 4 -4h9"/><path d="M14 6l3 3l-3 3"/>');
case 'Supermarché':
return glyph('<circle cx="9" cy="19" r="1.5"/><circle cx="17" cy="19" r="1.5"/><path d="M3 4h2l2.4 10.5a2 2 0 0 0 2 1.5h7.6a2 2 0 0 0 2 -1.6l1 -5.4h-13"/>');
case 'Auto-stop':
return glyph('<circle cx="13" cy="4" r="1"/><path d="M7 21l3 -4"/><path d="M16 21l-2 -4l-3 -3l1 -6"/><path d="M6 12l2 -3l4 -1l3 3l3 1"/>');
case 'Délaissé routier':
return glyph('<path d="M12 3v4"/><path d="M12 10v4"/><path d="M12 17v4"/><path d="M5 3v18"/><path d="M19 3v18"/>');
default:
return glyph('<path d="M15 10.5a3 3 0 1 1 -6 0a3 3 0 0 1 6 0z"/><path d="M19.5 10.5c0 7.142 -7.5 11.25 -7.5 11.25s-7.5 -4.108 -7.5 -11.25a7.5 7.5 0 1 1 15 0z"/>', 1.8);
}
}
// The areas only show while the Covoiturage accordion is open. The flag
// outlives the map so the markers come back when the map is recreated on
// a desktop/mobile switch.
let carpoolAreasVisible = false;
let carpoolAreaMarkers = [];
function clearCarpoolAreaMarkers() {
carpoolAreaMarkers.forEach(marker => marker.remove());
carpoolAreaMarkers = [];
}
function renderCarpoolAreaMarkers() {
const map = window.parcoursmobMap;
clearCarpoolAreaMarkers();
if (!map || !carpoolAreasVisible) return;
const areas = carpoolAreasFromData();
if (!areas.length) return;
const data = window.__PARCOURSMOB_DATA__ || {};
const bounds = new maplibregl.LngLatBounds();
areas.forEach((area) => {
const el = document.createElement('div');
el.className = 'map-marker map-marker-area';
el.innerHTML = `<div class="map-marker-inner">${carpoolAreaIcon(area.type)}</div>`;
const lines = [`<strong>${area.name}</strong>`];
if (area.city) lines.push(area.city);
if (area.address) lines.push(area.address);
if (area.type) lines.push(area.type);
const marker = new maplibregl.Marker({ element: el })
.setLngLat(area.coordinates)
.setPopup(new maplibregl.Popup({ offset: 20 }).setHTML(lines.join('<br>')))
.addTo(map);
carpoolAreaMarkers.push(marker);
bounds.extend(area.coordinates);
});
// Keep the trip framed while bringing the areas into view, rather than
// recentring on the areas alone.
if (data.departure) bounds.extend(data.departure.geometry.coordinates);
if (data.destination) bounds.extend(data.destination.geometry.coordinates);
map.fitBounds(bounds, { padding: 60, maxZoom: 14 });
}
function showCarpoolAreaMarkers() {
carpoolAreasVisible = true;
renderCarpoolAreaMarkers();
}
function hideCarpoolAreaMarkers() {
carpoolAreasVisible = false;
clearCarpoolAreaMarkers();
}
function initMap() {
const data = window.__PARCOURSMOB_DATA__ || {};
const departure = data.departure;
@@ -706,9 +863,11 @@
const departureEl = document.createElement('div');
departureEl.className = 'map-marker map-marker-departure';
departureEl.innerHTML = `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="18" height="18">
<path fill-rule="evenodd" d="M11.54 22.351l.07.04.028.016a.76.76 0 00.723 0l.028-.015.071-.041a16.975 16.975 0 001.144-.742 19.58 19.58 0 002.683-2.282c1.944-1.99 3.963-4.98 3.963-8.827a8.25 8.25 0 00-16.5 0c0 3.846 2.02 6.837 3.963 8.827a19.58 19.58 0 002.682 2.282 16.975 16.975 0 001.145.742zM12 13.5a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd" />
</svg>
<div class="map-marker-inner">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="18" height="18">
<path fill-rule="evenodd" d="M11.54 22.351l.07.04.028.016a.76.76 0 00.723 0l.028-.015.071-.041a16.975 16.975 0 001.144-.742 19.58 19.58 0 002.683-2.282c1.944-1.99 3.963-4.98 3.963-8.827a8.25 8.25 0 00-16.5 0c0 3.846 2.02 6.837 3.963 8.827a19.58 19.58 0 002.682 2.282 16.975 16.975 0 001.145.742zM12 13.5a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd" />
</svg>
</div>
`;
new maplibregl.Marker({ element: departureEl })
.setLngLat(depCoords)
@@ -719,15 +878,21 @@
const arrivalEl = document.createElement('div');
arrivalEl.className = 'map-marker map-marker-arrival';
arrivalEl.innerHTML = `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="18" height="18">
<path fill-rule="evenodd" d="M3 2.25a.75.75 0 01.75.75v.54l1.838-.46a9.75 9.75 0 016.725.738l.108.054a8.25 8.25 0 005.58.652l3.109-.732a.75.75 0 01.917.81 47.784 47.784 0 00.005 10.337.75.75 0 01-.574.812l-3.114.733a9.75 9.75 0 01-6.594-.77l-.108-.054a8.25 8.25 0 00-5.69-.625l-2.202.55V21a.75.75 0 01-1.5 0V3A.75.75 0 013 2.25z" clip-rule="evenodd" />
</svg>
<div class="map-marker-inner">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="18" height="18">
<path fill-rule="evenodd" d="M3 2.25a.75.75 0 01.75.75v.54l1.838-.46a9.75 9.75 0 016.725.738l.108.054a8.25 8.25 0 005.58.652l3.109-.732a.75.75 0 01.917.81 47.784 47.784 0 00.005 10.337.75.75 0 01-.574.812l-3.114.733a9.75 9.75 0 01-6.594-.77l-.108-.054a8.25 8.25 0 00-5.69-.625l-2.202.55V21a.75.75 0 01-1.5 0V3A.75.75 0 013 2.25z" clip-rule="evenodd" />
</svg>
</div>
`;
new maplibregl.Marker({ element: arrivalEl })
.setLngLat(destCoords)
.setPopup(new maplibregl.Popup().setHTML(`<strong>Arrivée</strong><br>${destination.properties.label}`))
.addTo(map);
// window.parcoursmobMap is assigned by the caller, which has already
// returned by the time `load` fires.
map.on('load', () => renderCarpoolAreaMarkers());
return map;
}