/**
 * Styles carte multi-lieux (BoostMap) — sidebar de filtres, clusters, popups, fallback
 */
/* .ptm-map-all-wrap porte la hauteur (style inline posé par render_map_all()) et empile
   verticalement : topbar pleine largeur, puis la ligne sidebar/carte qui prend le reste
   (flex:1 sur .ptm-map-layout). La topbar DOIT être un sibling de .ptm-map-layout (pas un enfant
   de .ptm-map-main) pour s'étendre au-dessus de la sidebar ET de la carte — sinon elle ne pousse
   que la carte vers le bas, désalignant leurs bords supérieurs (bug signalé par l'utilisateur). */
.ptm-map-all-wrap {
    margin: 20px 0;
    overflow: hidden; /* garde-fou : la sidebar a son propre scroll interne, ne doit jamais faire
                          déborder le wrap visuellement même en cas d'imprévu de mise en page */
    display: flex;
    flex-direction: column;
    /* isolation:isolate — crée un contexte d'empilement propre à la carte. Sans ça, les z-index
       internes de Leaflet (ex. .leaflet-top/.leaflet-control-container à 1000, posés par
       leaflet.css) se comparent à TOUTE la page plutôt qu'à ce seul conteneur — .leaflet-container
       a bien `position:relative` mais SANS z-index explicite, ce qui NE crée PAS de contexte
       d'empilement en CSS (piège classique). Résultat signalé : la carte passait au-dessus du
       header/nav sticky du thème, dont le z-index est très probablement < 1000. `isolation:isolate`
       borne tous les z-index descendants (Leaflet et les nôtres) à l'intérieur de ce wrap, qui
       participe ensuite à l'empilement de la page avec sa propre position naturelle — ne peut plus
       jamais recouvrir un élément externe, quel que soit le z-index posé à l'intérieur. */
    isolation: isolate;
}

@media (max-width: 600px) {
    .ptm-map-all-wrap { height: 400px !important; }
}

/* .ptm-map-layout et .ptm-map-sidebar/.ptm-map-main n'ont pas de hauteur fixe à eux — ils se
   contentent de la propager depuis .ptm-map-all-wrap via flex:1/stretch. Ordre volontaire : la
   sidebar peut avoir plus de contenu (filtres) que la carte n'a de hauteur — sans cette
   propagation, la ligne flex grandirait pour accueillir la sidebar et laisserait un vide sous
   une carte de hauteur fixe plus courte. */
.ptm-map-layout {
    position: relative;
    display: flex;
    align-items: stretch;
    width: 100%;
    flex: 1 1 auto;
    min-height: 0; /* même piège flexbox que .ptm-map-sidebar plus bas — nécessaire ici aussi
                       depuis que .ptm-map-layout est lui-même un flex item (colonne du wrap) */
}
/* Fermée par défaut (desktop) : liseré de 10px visible plutôt qu'une disparition totale
   (display:none) — indique qu'un panneau existe et peut s'ouvrir, sans quoi rien ne laisse
   deviner sa présence une fois caché (retour utilisateur). Le contenu (cases à cocher etc.) est
   rendu inerte au clavier/lecteur d'écran via l'attribut `inert`, posé par buildFiltresToggle()
   selon l'état — sans ça, des éléments cliniquement invisibles à 10px de large resteraient
   atteignables au Tab. */
.ptm-map-sidebar {
    width: 10px;
    flex-shrink: 0;
    /* min-height:0 — sans ça, un flex item avec overflow-y:auto ne se limite pas toujours
       correctement à la hauteur imposée par align-items:stretch : le contenu (longue liste de
       cases) peut forcer sa propre hauteur naturelle, débordant .ptm-map-all-wrap malgré son
       overflow:hidden et poussant la PAGE entière à scroller — au lieu du scroll interne voulu.
       Piège flexbox classique, cause du désalignement sidebar/carte signalé. */
    min-height: 0;
    overflow: hidden; /* pas de scroll tant que trop étroite pour afficher quoi que ce soit */
    background: #fff;
    border-right: 1px solid rgba(0,0,0,0.12);
    padding: 16px;
    box-sizing: border-box;
}
/* Fermée (10px), le padding (16px de chaque côté) dépasse déjà la largeur disponible : le texte
   des cases/labels n'a plus aucune place et s'enroule caractère par caractère sur une colonne
   verticale — visible malgré overflow:hidden car ce n'est pas la largeur qui posait problème mais
   le contenu lui-même qui restait rendu (retour utilisateur : "on voit des cases à cocher").
   Masquage explicite du contenu par opacity, indépendant de tout calcul de largeur/débordement —
   ne laisse que le fond blanc + bordure du liseré visibles tant que fermé. */
.ptm-map-sidebar > * {
    opacity: 0;
}
.ptm-map-layout-sidebar-open .ptm-map-sidebar > * {
    opacity: 1;
}
.ptm-map-layout-sidebar-open .ptm-map-sidebar {
    width: 300px;
    overflow-y: auto;
    /* overscroll-behavior:contain — sans ça, une fois le scroll de la sidebar arrivé en bas (ou
       si le navigateur hésite sur la cible du scroll), le geste de molette "déborde" vers le
       scroll de la page au lieu de rester cantonné à la sidebar (retour utilisateur : obligé de
       scroller via la barre de défilement du navigateur plutôt que directement avec la molette
       au-dessus de la sidebar). Empêche ce chaînage, la molette reste toujours capturée ici. */
    overscroll-behavior: contain;
    /* Scrollbar fine plutôt que la barre native épaisse — celle-ci chevauchait visuellement le
       bouton chevron posé sur la jonction sidebar/carte (retour utilisateur), le bord droit de la
       sidebar (300px) étant justement où la scrollbar native se dessine. */
    scrollbar-width: thin;
    scrollbar-color: rgba(0,0,0,0.25) transparent;
}
.ptm-map-sidebar::-webkit-scrollbar {
    width: 6px;
}
.ptm-map-sidebar::-webkit-scrollbar-track {
    background: transparent;
}
.ptm-map-sidebar::-webkit-scrollbar-thumb {
    background: rgba(0,0,0,0.25);
    border-radius: 4px;
}
.ptm-map-main {
    position: relative; /* ancre pour .ptm-map-status en overlay, cf. plus bas */
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0; /* même piège flexbox que .ptm-map-sidebar ci-dessus */
    display: flex;
    flex-direction: column;
}
.ptm-map-topbar {
    display: flex;
    align-items: center;
    /* center — retour utilisateur sur grand écran (4K) : flex-start avec le "Coups de cœur"
       poussé en margin-left:auto sur un seul enfant laissait tout le reste collé à gauche et le
       chip coeur isolé à l'extrémité droite, un vide énorme entre les deux. Centrer le groupe
       entier (recherche + chips) est plus sobre et ne dépend pas de la largeur de l'écran. */
    justify-content: center;
    gap: 10px;
    padding: 10px 16px;
    flex-shrink: 0;
    border-bottom: 1px solid rgba(0,0,0,0.1);
}

/* "À propos des données" — <details> discret sous la carte (frère externe de .ptm-map-all-wrap,
   inséré par buildSourceInfoBlock() dans map-cluster.js). Hors du wrap : ni overflow:hidden ni
   hauteur fixe à contourner, donc <details> natif suffit (ancienne version : bouton chip dans la
   topbar + panel position:fixed — écrasait les chips de filtres et débordait en desktop). */
.ptm-map-source-note {
    margin: 8px 2px 0;
    font-size: 0.78rem;
}
.ptm-map-source-note summary {
    color: #666;
    cursor: pointer;
    line-height: 1.5;
}
.ptm-map-source-note[open] summary {
    margin-bottom: 6px;
}
.ptm-map-source-info-list {
    margin: 0;
    padding: 0 0 0 16px;
    list-style: disc;
}
.ptm-map-source-info-list li {
    font-size: 0.78rem;
    line-height: 1.6;
    color: #333;
    white-space: normal;
}
html.is-dark-mode .ptm-map-source-note summary { color: #94a3b8; }
html.is-dark-mode .ptm-map-source-info-list li { color: #cbd5e1; }

/* Recherche d'adresse — icône seule au repos, s'étend en champ au clic (validé sur maquette
   interactive avec l'utilisateur avant codage — pattern Google Maps, laisse la place aux futures
   chips de couches Data Paris/Coup de cœur, tâche #5, plutôt qu'un champ toujours grand ouvert). */
.ptm-map-search {
    position: relative;
    flex: 0 0 auto;
    /* Nudge 2px vers le haut — align-items:center sur .ptm-map-topbar centre mathématiquement
       la capsule (32px) par rapport aux chips, mais visuellement elle paraissait légèrement plus
       basse (retour utilisateur). */
    margin-top: -2px;
}
/* La capsule (pas .ptm-map-search lui-même) porte overflow:hidden pour l'animation de largeur —
   .ptm-map-search-results (absolue) est un enfant de .ptm-map-search, pas de la capsule, pour ne
   jamais être rognée par cet overflow:hidden. */
.ptm-map-search-capsule {
    display: flex;
    align-items: center;
    height: 32px;
    width: 32px;
    border-radius: 16px;
    border: 1px solid var(--evp-gris-perle, #ccc);
    background: #fff;
    overflow: hidden;
    transition: width 0.22s ease;
}
.ptm-map-search-open .ptm-map-search-capsule {
    /* 260px→340px : le texte ("Rechercher une adresse à Paris…") était tronqué à la taille de
       police réelle (1rem, plus grande que prévu au départ — cf. fix du fond gris du thème qui a
       aussi corrigé la taille jamais appliquée jusque-là). */
    width: 340px;
}
.ptm-map-search-toggle {
    flex: 0 0 32px;
    width: 32px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    font-size: 15px;
    cursor: pointer;
    text-transform: none;
    letter-spacing: normal;
}
/* Root cause trouvée (pas juste l'état :focus, cf. plus bas) : le thème a une règle DE BASE
   (pas scopée :focus) `input[type="text"], ...{font-size:0.75rem;padding:.375rem 1rem;
   color:#495057;background-color:#F2F4F6;border:2px solid #F2F4F6}` (style-final.css:381) —
   spécificité (0,1,1) bat ma classe seule (0,1,0). Explique à la fois "la police ne grossit
   jamais", "le fond gris" et une partie des bordures signalées. !important nécessaire (déjà le
   pattern retenu ailleurs sur cette carte, ex. .ptm-recenter-btn, pour ce genre de règle thème
   récurrente) plutôt que d'empiler indéfiniment des sélecteurs plus spécifiques. */
.ptm-map-search-input {
    flex: 1 1 auto;
    min-width: 0;
    width: 0;
    box-sizing: border-box;
    padding: 0 !important;
    margin: 0;
    border: none !important;
    border-radius: 0 !important;
    background: transparent !important;
    color: inherit !important;
    font-size: 1rem !important;
    line-height: normal !important;
    opacity: 0;
    transition: opacity 0.15s ease 0.1s;
}
.ptm-map-search-open .ptm-map-search-input {
    width: auto;
    padding: 0 4px !important;
    opacity: 1;
}
/* Vraie cause trouvée dans le CSS du thème (pas juste :focus vs :focus-visible) :
   `input[type="text"]:focus{background-color:#FFFFFF;outline:0}` (style-final.css:406, PAS scopé
   dark mode) force un fond blanc au focus, quel que soit le mode — d'où un rectangle clair
   inattendu dans la capsule sombre en dark mode. Spécificité (0,2,1) (attribut [type] + :focus,
   élément input) bat une simple classe .ptm-map-search-input:focus (0,2,0). En PLUS, le thème a
   `html.is-dark-mode input:focus{outline:2px solid #7AAED6}` (style-final.css:5404, tous types
   confondus), spécificité (0,2,2), qui rajoute l'anneau bleu clair signalé ("border à virer").
   Fix : qualifier avec l'ancêtre .ptm-map-search-capsule pousse la spécificité au-delà des deux
   règles thème (même technique que le fix dark mode des cases à cocher de la sidebar). */
.ptm-map-search-capsule .ptm-map-search-input:focus,
.ptm-map-search-capsule .ptm-map-search-input:focus-visible {
    background: transparent !important;
    box-shadow: none !important;
    outline: none !important;
    border: none !important;
}
html.is-dark-mode .ptm-map-search-capsule .ptm-map-search-input:focus,
html.is-dark-mode .ptm-map-search-capsule .ptm-map-search-input:focus-visible {
    outline: none !important;
}
.ptm-map-search-clear {
    flex: 0 0 auto;
    width: 0;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    color: var(--text-secondary, #777);
    font-size: 1rem;
    cursor: pointer;
    padding: 0;
    text-transform: none;
    letter-spacing: normal;
}
.ptm-map-search-open .ptm-map-search-clear {
    flex-basis: 26px;
    width: 26px;
}
/* Même précaution que .ptm-map-filters-toggle/.ptm-map-sidebar-reset : le thème réaffirme son
   style CTA (fond noir/texte blanc) au survol/focus/actif sur tout <button>, pas seulement au
   repos — oubli initial du :hover ici (retour utilisateur : "mouse hover ko en clair"), seuls
   :focus/:active avaient été traités, donc rien ne battait le button:hover{background:rgba(0,0,0,
   0.75)} du thème en spécificité. */
.ptm-map-search-toggle:hover,
.ptm-map-search-toggle:focus,
.ptm-map-search-toggle:active {
    background: #eaf1f7;
    color: inherit;
    outline: none;
}
.ptm-map-search-clear:hover,
.ptm-map-search-clear:focus,
.ptm-map-search-clear:active {
    background: rgba(0, 0, 0, 0.06);
    color: inherit;
    outline: none;
}
html.is-dark-mode .ptm-map-search-capsule {
    background: #2a2a2a;
    border-color: #555;
    color: #e8e0d5;
}
html.is-dark-mode .ptm-map-search-toggle:hover,
html.is-dark-mode .ptm-map-search-toggle:focus,
html.is-dark-mode .ptm-map-search-toggle:active {
    background: #384854;
}
html.is-dark-mode .ptm-map-search-clear:hover,
html.is-dark-mode .ptm-map-search-clear:focus,
html.is-dark-mode .ptm-map-search-clear:active {
    background: rgba(255, 255, 255, 0.1);
}
.ptm-map-search-results {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    /* Les panes internes de Leaflet (tuiles/marqueurs/popups/contrôles) ont des z-index natifs
       jusqu'à 1000+ (leaflet.css) — un z-index:10 se faisait passer par-dessus dès que la liste
       déborde sur la zone carte en dessous (retour utilisateur : "passe sous la carte"). */
    z-index: 1500;
    margin: 0;
    padding: 4px;
    list-style: none;
    background: #fff;
    border: 1px solid var(--evp-gris-perle, #ccc);
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    max-height: 260px;
    overflow-y: auto;
}
.ptm-map-search-results li + li {
    margin-top: 2px;
}
.ptm-map-search-results button {
    /* color:#1a1a1a explicite — le thème pose `button{background-color:#000;color:white}`
       (style-final.css:458, même piège CTA déjà croisé plusieurs fois sur cette carte) : le fond
       avait été neutralisé mais pas la couleur, laissant du texte blanc invisible sur le fond
       blanc de la liste en mode clair (lisible seulement en dark, retour utilisateur). */
    display: block;
    width: 100%;
    box-sizing: border-box;
    padding: 8px 10px;
    text-align: left;
    background: transparent;
    color: #1a1a1a;
    border: none;
    border-radius: 4px;
    font-size: 0.82rem;
    text-transform: none;
    letter-spacing: normal;
    cursor: pointer;
}
.ptm-map-search-results button:hover,
.ptm-map-search-results button:focus-visible {
    background: rgba(44, 95, 141, 0.08);
}
.ptm-map-search-empty {
    padding: 8px 10px;
    font-size: 0.82rem;
    opacity: 0.7;
}
/* Recherches récentes (historique local, cf. map-cluster.js) — en-tête compact au-dessus de la
   liste, pas un vrai bouton pleine largeur comme les résultats : classe combinée pour battre la
   spécificité de `.ptm-map-search-results button` (display:block/width:100% indésirables ici). */
.ptm-map-search-recent-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 10px 4px;
    color: #1a1a1a;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    opacity: 0.6;
}
.ptm-map-search-results button.ptm-map-search-recent-clear {
    display: inline;
    width: auto;
    padding: 0;
    font-size: 0.72rem;
    text-transform: none;
    letter-spacing: normal;
    text-decoration: underline;
    color: inherit;
    opacity: 0.85;
}
.ptm-map-search-results button.ptm-map-search-recent-clear:hover,
.ptm-map-search-results button.ptm-map-search-recent-clear:focus-visible {
    background: transparent;
    opacity: 1;
}
.ptm-map-search-recent-icon {
    margin-right: 6px;
    opacity: 0.6;
}
html.is-dark-mode .ptm-map-search-results {
    background: #2a2a2a;
    border-color: #555;
}
html.is-dark-mode .ptm-map-search-results button {
    color: #e8e0d5;
}
html.is-dark-mode .ptm-map-search-results button:hover,
html.is-dark-mode .ptm-map-search-results button:focus-visible {
    background: rgba(122, 174, 214, 0.15);
}
html.is-dark-mode .ptm-map-search-recent-header {
    color: #e8e0d5;
}

/* Sélecteur de couche exclusif (Lieux/WC/Fontaines/Wifi, radiogroup) + chip "Coups de cœur" —
   maquette validée avant codage (cf. mémoire session), style chip fin repris de la barre de
   recherche/contrôles déjà en place sur cette carte. */
.ptm-map-layers {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: nowrap;
}
/* Icône des chips de couche (WC/Fontaines/Wifi) agrandie par rapport au texte — trop petite à la
   taille du chip pour rester identifiable (retour utilisateur). Unité relative (em) : suit la
   taille du texte du chip plutôt qu'une valeur fixe. */
.ptm-map-layer-chip-icon {
    font-size: 1.4em;
    line-height: 1;
}
/* Pin Lieux (image, pas emoji) — largeur fixée, hauteur auto pour garder les proportions
   naturelles du marqueur (forme goutte, plus haute que large). */
.ptm-map-layer-chip-icon-img {
    width: 13px;
    height: auto;
    display: inline-block;
    flex: 0 0 auto;
}
.ptm-map-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 6px 12px;
    /* border-radius énorme (pas 14px fixe) : garantit une vraie pilule quelle que soit la
       hauteur réelle du contenu — le chip "Lieux" (icône image, ~21px) est légèrement plus haut
       que les chips emoji (~17px), un radius fixe le faisait paraître moins arrondi que les
       autres (retour utilisateur). */
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 500;
    background: #fff;
    border: 1px solid var(--evp-gris-perle, #ccc);
    color: #444;
    cursor: pointer;
    text-transform: none;
    letter-spacing: normal;
    white-space: nowrap;
}
.ptm-map-chip:hover {
    /* Fond plein (pas rgba à faible opacité) — 8% d'opacité sur fond blanc rendait le survol trop
       pâle, jugé "illisible" (retour utilisateur) ; même teinte pleine déjà utilisée ailleurs sur
       cette carte (.ptm-map-filters-toggle:hover). color explicite en plus du fond : même piège
       récurrent que .ptm-map-search-toggle/.ptm-map-search-results button — le thème force
       color:white sur :hover (bouton CTA générique), texte devenu illisible sur ce fond clair
       (retour utilisateur : "font hover pas visible en clair"). */
    background: #eaf1f7;
    color: #444;
}
.ptm-map-chip:focus,
.ptm-map-chip:active {
    background: #fff;
    color: #444;
    outline: none;
}
.ptm-map-chip-active {
    background: var(--evp-bleu-parisien, #2C5F8D);
    border-color: var(--evp-bleu-parisien, #2C5F8D);
    color: #fff;
}
.ptm-map-chip-active:hover,
.ptm-map-chip-active:focus,
.ptm-map-chip-active:active {
    background: var(--evp-bleu-parisien-hover, #234a6f);
    color: #fff;
}
html.is-dark-mode .ptm-map-chip {
    background: #2a2a2a;
    border-color: #555;
    color: #e8e0d5;
}
html.is-dark-mode .ptm-map-chip:hover {
    background: rgba(122, 174, 214, 0.15);
}
html.is-dark-mode .ptm-map-chip:focus,
html.is-dark-mode .ptm-map-chip:active {
    background: #2a2a2a;
    color: #e8e0d5;
}
html.is-dark-mode .ptm-map-chip-active {
    background: #7AAED6;
    border-color: #7AAED6;
    color: #1a2530;
}
html.is-dark-mode .ptm-map-chip-active:hover,
html.is-dark-mode .ptm-map-chip-active:focus,
html.is-dark-mode .ptm-map-chip-active:active {
    background: #6b9cc4;
    color: #1a2530;
}
/* Toggle ♿ "Accessibles uniquement" accolé au chip de sa couche (cf. buildPmrOnlyToggle(),
   inséré juste après ce chip dans le DOM) — deux pilules distinctes côte à côte laissaient croire
   à 2 filtres indépendants au même niveau plutôt qu'un chip + son option (retour utilisateur,
   capture à l'appui). Jointure "pilule fusionnée" : coin interne du chip aplati, toggle collé
   dessus (marge négative annulant le gap du flex parent) et arrondi seulement côté extérieur —
   se lit comme un seul bloc en deux parties plutôt que deux chips séparés.
   :has() : support navigateurs modernes largement suffisant ici (pas de repli nécessaire, la
   jointure est un raffinement visuel, jamais bloquant si non supporté — les 2 chips restent
   pleinement fonctionnels séparés dans ce cas). */
.ptm-map-layers .ptm-map-chip:has(+ .ptm-map-pmr-only-toggle) {
    border-radius: 999px 0 0 999px;
    border-right: none;
}
.ptm-map-pmr-only-toggle {
    border-radius: 0 999px 999px 0;
    /* margin:0 d'abord — le thème applique margin-bottom:0.5rem à tout <label> par défaut (même
       piège déjà rencontré et neutralisé sur .ptm-map-sidebar-checkbox), sans ça ce toggle
       (un <label>, contrairement aux autres chips qui sont des <button>) se retrouvait décalé
       verticalement par rapport à eux — visible aux DevTools (bande orange = marge), retour
       utilisateur capture à l'appui. margin-left ensuite, annule le gap:6px de .ptm-map-layers
       pour la jointure sans interstice avec le chip précédent. */
    margin: 0 0 0 -6px;
    /* Contenu plus étroit qu'un chip texte classique (case + icône, pas de libellé visible,
       cf. buildPmrOnlyToggle()) — padding réduit en conséquence, gap resserré entre les deux. */
    padding: 6px 10px;
    gap: 6px;
    /* line-height explicite plutôt qu'hérité : c'est un <label>, pas un <button> — la règle
       générique du thème `button, input[...] { line-height: 1.5 }` ne le cible pas, donc il hérite
       du line-height ambiant (celui de .entry-content en contenu éditorial, plus grand que celui
       de template-carte.php où le correctif "hauteur invisible" ci-dessous a été calibré à
       l'origine). Sans valeur explicite ici, le spacer compense un line-height hérité différent
       selon le contexte d'intégration au lieu de viser toujours 1.5, recréant l'écart de hauteur
       avec le chip voisin. */
    line-height: 1.5;
}
/* Case entièrement redessinée (appearance:none) plutôt que stylée via accent-color seul — le
   rendu natif non stylisé du navigateur/OS ajoutait un anneau/bordure coloré autour de la case
   même non cochée (constaté à vide, pas juste au focus — retour utilisateur, capture à l'appui),
   indépendant de tout accent-color posé côté CSS. Même logique que le curseur de proximité
   (#ptm-proximity-slider) déjà redessiné plus haut sur cette carte pour la même raison : un
   rendu natif imprévisible selon navigateur/OS/thème système. */
.ptm-map-pmr-only-toggle input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    width: 15px;
    height: 15px;
    margin: 0;
    flex-shrink: 0;
    cursor: pointer;
    border: 1px solid #999;
    border-radius: 3px;
    background: #fff;
    position: relative;
    outline: none;
}
.ptm-map-pmr-only-toggle input[type="checkbox"]:checked {
    /* Vert (pas le bleu des autres cases) — cohérent avec le badge ♿ des popups
       (.ptm-map-popup-pmr, même teinte), identité visuelle propre à l'accessibilité PMR. */
    background: #27ae60;
    border-color: #27ae60;
}
.ptm-map-pmr-only-toggle input[type="checkbox"]:checked::after {
    content: '';
    position: absolute;
    left: 4px;
    top: 1px;
    width: 4px;
    height: 8px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}
/* Case non cochée : suit le fond sombre des autres chips en dark mode (#2a2a2a, même teinte que
   html.is-dark-mode .ptm-map-chip) au lieu du blanc plein hérité de la règle de base — un carré
   blanc plein tranchait fort sur fond sombre (retour utilisateur, capture à l'appui). */
html.is-dark-mode .ptm-map-pmr-only-toggle input[type="checkbox"] {
    background: #2a2a2a;
    border-color: #555;
}
/* Anneau bleu au focus signalé (retour utilisateur, capture à l'appui) — pas ma règle : le thème
   a `html.is-dark-mode input:focus{outline:2px solid #7AAED6;border-color:#7AAED6;
   background-color:#1a1a1a}` (style-final.css:5404), tous types d'<input> confondus, spécificité
   (0,2,2) qui bat ma règle de base (0,2,1). Même piège déjà rencontré et corrigé pour le champ de
   recherche de cette carte (.ptm-map-search-capsule .ptm-map-search-input:focus) — même remède :
   qualifier avec le préfixe html.is-dark-mode pour repasser devant. Couleurs de repli alignées sur
   la règle ci-dessus (dark), pas sur le blanc clair — sinon le focus faisait justement réapparaître
   un carré blanc au clic malgré le fix ci-dessus. */
html.is-dark-mode .ptm-map-pmr-only-toggle input[type="checkbox"]:focus {
    outline: none;
    border-color: #555;
    background-color: #2a2a2a;
}
html.is-dark-mode .ptm-map-pmr-only-toggle input[type="checkbox"]:checked,
html.is-dark-mode .ptm-map-pmr-only-toggle input[type="checkbox"]:checked:focus {
    border-color: #27ae60;
    background-color: #27ae60;
}
/* Repère de hauteur invisible (cf. heightSpacer dans buildPmrOnlyToggle()) — sans texte visible
   dans ce chip (contrairement aux autres, ex. "WC"), sa ligne la plus haute était l'icône seule
   (line-height:1, ~17,5px) au lieu du texte des autres chips (line-height "normal" du navigateur,
   ~18,7px à cette taille de police) : ~1,25px d'écart de hauteur mesuré en direct entre ce chip et
   son voisin, pas visible autrement qu'en comparant les bordures pixel par pixel (retour
   utilisateur, capture à l'appui). visibility:hidden (pas display:none) : reste dans le flux et
   contribue à la hauteur de ligne, sans occuper de largeur ni être lu par un lecteur d'écran. */
.ptm-map-pmr-only-toggle-spacer {
    width: 0;
    overflow: hidden;
    visibility: hidden;
}

/* Mobilité partagée (DEV117 — POC Lime) — VRAI membre de .ptm-map-layers désormais (cf.
   makeMobilityChip() dans map-cluster.js), pas un composant séparé qui imite juste le style
   (retour utilisateur explicite : "il ne faut pas voir la moindre différence entre ces chips").
   .ptm-map-chip/.ptm-map-layer-chip réutilisées telles quelles pour le gabarit — couleurs, dark
   mode ET suppression du focus ring (outline:none, règle générique plus haut dans ce fichier)
   déjà couverts par ces classes partagées, rien à redupliquer ici. */
.ptm-map-mobility-chip-wrap {
    position: relative;
    display: inline-flex;
}
.ptm-mobility-popin {
    /* position/top/left posés dynamiquement en JS (positionPopin()) — cette chip peut être
       n'importe où dans la ligne de chips désormais (réordonnable via chipsConfig), et vit dans
       un conteneur overflow-x:auto sur mobile : une position CSS fixe (ex. right:0 en absolute)
       ne suffit plus, ni ne resterait dans le clipping du conteneur. position:fixed calculé par
       rapport au bouton réel, toujours clampé dans l'écran. */
    z-index: 1100;
    min-width: 200px;
    background: #fff;
    border: 1px solid var(--evp-gris-perle, #ccc);
    border-radius: 12px;
    padding: 8px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
html.is-dark-mode .ptm-mobility-popin {
    background: #2a2a2a;
    border-color: #555;
}
.ptm-mobility-popin-header {
    display: flex;
    justify-content: flex-end;
    margin-bottom: 4px;
}
.ptm-mobility-popin-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border: none;
    border-radius: 50%;
    background: transparent;
    /* #555 (pas #888) — retour utilisateur : contraste insuffisant sur fond blanc (~3,5:1, sous
       le seuil WCAG AA de 4,5:1). #555 ≈ 7,5:1, même teinte que les bordures de chip ailleurs. */
    color: #555;
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}
.ptm-mobility-popin-close:hover,
.ptm-mobility-popin-close:focus {
    background: #eaf1f7;
    /* color explicite en plus du fond — même piège récurrent que .ptm-map-chip:hover ailleurs
       dans ce fichier : le thème force color:white sur :hover (bouton CTA générique), la croix
       devenait invisible sur ce fond clair (retour utilisateur, capture à l'appui). */
    color: #555;
    outline: none;
}
html.is-dark-mode .ptm-mobility-popin-close {
    color: #ccc;
}
html.is-dark-mode .ptm-mobility-popin-close:hover,
html.is-dark-mode .ptm-mobility-popin-close:focus {
    background: rgba(122, 174, 214, 0.15);
    color: #ccc;
}
.ptm-mobility-back-btn {
    display: block;
    margin-top: 6px;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--evp-bleu-parisien, #2C5F8D);
    font-size: 0.78rem;
    text-decoration: underline;
    cursor: pointer;
}
html.is-dark-mode .ptm-mobility-back-btn {
    color: #7AAED6;
}
.ptm-mobility-provider-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.ptm-mobility-provider-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 8px 10px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: #444;
    font-size: 0.85rem;
    text-align: left;
    cursor: pointer;
}
.ptm-mobility-provider-btn:hover,
.ptm-mobility-provider-btn:focus {
    background: #eaf1f7;
    /* color explicite — même piège que .ptm-map-chip:hover : le thème force color:white sur
       :hover, "LIME" devenait quasi invisible sur ce fond clair (retour utilisateur, capture à
       l'appui). */
    color: #444;
    outline: none;
}
html.is-dark-mode .ptm-mobility-provider-btn {
    color: #e8e0d5;
}
html.is-dark-mode .ptm-mobility-provider-btn:hover,
html.is-dark-mode .ptm-mobility-provider-btn:focus {
    background: rgba(122, 174, 214, 0.15);
    color: #e8e0d5;
}
.ptm-mobility-status {
    margin-top: 6px;
    padding: 6px 8px;
    font-size: 0.78rem;
    color: #666;
    border-top: 1px solid var(--evp-gris-perle, #ccc);
}
html.is-dark-mode .ptm-mobility-status {
    color: #bbb;
    border-color: #555;
}
.ptm-mobility-status-error {
    color: #c0392b;
}
html.is-dark-mode .ptm-mobility-status-error {
    color: #e57373;
}
/* Marqueur véhicule — icône prestataire (Lime auto-hébergée, cf. class-leaflet-map.php
   mobilityProviderIcons) dans un disque blanc, même esprit que .ptm-user-location-dot pour rester
   identifiable sur fond de tuiles OSM chargé. */
.ptm-mobility-marker {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    background: #fff;
    border-radius: 50%;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
    /* Leaflet rend les marqueurs focusables (tabindex) par défaut — sans ceci, cliquer un
       marqueur affiche l'anneau de focus natif du navigateur (retour utilisateur, capture à
       l'appui : "border bleu à virer"). keyboard:false posé aussi côté JS (L.marker) — double
       verrou, pas juste cosmétique : évite aussi que ces marqueurs entrent dans la navigation au
       clavier de la carte, qui ne leur apporte rien (pas des lieux du catalogue à explorer). */
    outline: none;
}
.ptm-mobility-marker img {
    width: 16px;
    height: 16px;
}
/* Titre du popup marqueur — même gabarit que .ptm-map-popup-title (autres couches), pour que le
   popup mobilité ne reste pas sans intitulé (retour utilisateur : "on peut ajouter un texte"). */
.ptm-mobility-vehicle-title {
    font-size: 0.95rem;
    font-weight: 700;
    color: #1a1a1a;
}
html.is-dark-mode .ptm-mobility-vehicle-title {
    color: #f5f0e8;
}
.ptm-mobility-range,
.ptm-mobility-distance,
.ptm-mobility-freshness {
    color: #333;
    font-size: 0.82rem;
}
/* Ces 3 lignes n'ont pas de classe dédiée aux autres popups de cette carte à réutiliser (pas de
   couleur dark mode générique héritée) — sans cette règle, elles restaient à leur couleur claire
   par défaut sur le fond de popup assombri (#262626 en dark, cf. règle .leaflet-popup-content-
   wrapper plus bas) : texte sombre sur fond sombre, illisible (retour utilisateur, capture à
   l'appui). Le lien d'attribution n'avait pas ce problème : un <a> garde sa couleur bleue par
   défaut, visible sur les deux fonds. */
html.is-dark-mode .ptm-mobility-range,
html.is-dark-mode .ptm-mobility-distance,
html.is-dark-mode .ptm-mobility-freshness {
    color: #ccc;
}
/* Attribution Licence Ouverte 2.0 (SPEC DEV117 section 6) — répétée dans chaque popup marqueur. */
.ptm-mobility-attribution {
    margin-top: 4px;
    font-size: 0.72rem;
}
.ptm-mobility-attribution a {
    color: inherit;
    text-decoration: underline;
}
/* Couche Data Paris active — sidebar de filtres Lieux masquée entièrement (n'a aucun effet sur
   ces couches, pas de taxonomie dessus) plutôt que laissée visible sans effet ; la carte occupe
   alors toute la largeur. */
.ptm-map-layout.ptm-map-layout-no-sidebar .ptm-map-sidebar,
.ptm-map-layout.ptm-map-layout-no-sidebar .ptm-map-filters-toggle {
    display: none !important;
}


/* Sur petit écran, la sidebar devient une feuille plein écran par-dessus la carte plutôt qu'une
   colonne dans le flux — sinon 300px fixes ne laisseraient quasi plus de place à la carte. Le
   liseré de 10px (desktop, ci-dessus) n'a pas de sens ici : retour à un masquage complet
   (display:none) tant que fermée, le bouton chevron reste l'unique affordance sur mobile. */
@media (max-width: 768px) {
    .ptm-map-sidebar {
        display: none;
        width: 100%;
        /* fixed, pas absolute — la feuille doit couvrir le VIEWPORT réel, pas la position du
           document. En absolute, si la page était scrollée avant d'ouvrir "Filtres" (cas courant
           mobile : on scrolle jusqu'à la carte avant de taper le bouton), toute la feuille — donc
           aussi la flèche retour — se retrouvait décalée hors écran vers le haut, d'autant que le
           défilement de la page était important (bug distinct de celui du SVG ci-dessus, trouvé
           en mesurant getBoundingClientRect() en direct, coordonnées négatives constatées). */
        position: fixed;
        inset: 0;
        z-index: 500;
        border-right: none;
    }
    .ptm-map-layout-sidebar-open .ptm-map-sidebar {
        display: flex;
        flex-direction: column;
        width: 100%;
        /* Le scroll vit maintenant dans .ptm-map-sidebar-scroll (ci-dessous), pas ici — voir
           pourquoi juste en dessous. */
        overflow: hidden;
    }
    /* En-tête (flèche fermer + titre + Réinitialiser) et pied ("Voir les résultats") restent
       visibles en permanence pendant le scroll de la liste de filtres, façon Booking (référence
       explicite de l'utilisateur) — remplacent la pastille flottante comme mécanisme de
       fermeture (masquée ci-dessous tant que le panneau est ouvert : redondante désormais, et
       c'est elle qui cachait Réinitialiser en permanence, retour utilisateur précédent).
       Implémenté en flexbox (header/scroll/footer empilés en colonne, seul le scroll du milieu
       défile) plutôt qu'en position:sticky : confirmé via getComputedStyle en direct que sticky
       s'appliquait bien, mais du contenu déjà scrollé restait visible par-dessus façon "fantôme"
       (retour utilisateur, capture d'écran) — bug de recomposition connu de position:sticky sur
       mobile quand le conteneur scrollant est lui-même position:absolute (le cas ici, feuille
       plein écran), pas résolu même en forçant un calque de composition dédié
       (transform:translateZ(0)). Le pattern flexbox évite le problème à la racine : header/pied
       ne sont plus "collés" par scroll-tracking, ils sont structurellement HORS de la zone qui
       défile. */
    .ptm-map-layout-sidebar-open .ptm-map-filters-toggle-mobile {
        display: none;
    }
    .ptm-map-layout-sidebar-open .ptm-map-sidebar-header {
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 10px;
        background: #fff;
    }
    .ptm-map-layout-sidebar-open .ptm-map-sidebar-scroll {
        flex: 1 1 auto;
        min-height: 0; /* même piège flexbox que .ptm-map-sidebar/.ptm-map-main ailleurs sur
                          cette carte — sans lui, ce conteneur peut imposer sa hauteur naturelle
                          (celle de tout le contenu) au lieu de se limiter à l'espace flex dispo. */
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }
    .ptm-map-sidebar-close {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        /* Fond visible (pas transparent) — même traitement que .ptm-carte-back dans le header
           compact : sans lui, l'icône flottait seule sans repère visuel de "bouton", paraissant
           plus petite/discrète par comparaison même à taille de trait égale ou supérieure (retour
           utilisateur : "reste super petit... si on compare à la flèche du haut"). */
        background: rgba(0,0,0,0.06);
        border: none;
        color: #333;
        cursor: pointer;
        flex-shrink: 0;
    }
    .ptm-map-sidebar-close svg {
        display: block;
        /* width/height explicites — l'attribut HTML width="24"/height="24" seul ne suffit pas
           dans ce contexte flex (align-items/justify-content:center sur le bouton) : la largeur
           calculée retombait à 0 malgré une hauteur correcte, la flèche disparaissait entièrement
           bien que sa couleur/contraste soient corrects (confirmé par mesure DOM en direct, pas
           un souci de contraste dark mode comme il y paraissait au premier abord). */
        width: 24px;
        height: 24px;
        flex-shrink: 0;
    }
    .ptm-map-sidebar-close:hover,
    .ptm-map-sidebar-close:focus,
    .ptm-map-sidebar-close:active {
        background: rgba(0,0,0,0.12);
        color: #333;
        outline: none;
    }
    /* Réinitialiser change de contexte sur mobile (en-tête, pas pied) : redevient un simple lien
       texte discret plutôt qu'un bouton encadré pleine largeur, qui n'a plus de sens à côté du
       titre. */
    .ptm-map-sidebar-header .ptm-map-sidebar-reset {
        width: auto;
        padding: 6px 4px;
        border: none;
        background: transparent;
        flex-shrink: 0;
    }
    .ptm-map-sidebar-header .ptm-map-sidebar-reset:hover {
        background: transparent;
        text-decoration: underline;
    }
    .ptm-map-layout-sidebar-open .ptm-map-sidebar-footer {
        flex: 0 0 auto;
        background: #fff;
    }
    /* Plus visible qu'en desktop (0.82rem/#555 par défaut) — juste au-dessus du bouton CTA, ce
       compteur mérite plus de poids ici (retour utilisateur : "rendre plus visible"). */
    .ptm-map-sidebar-footer .ptm-map-sidebar-results {
        font-size: 0.95rem;
        font-weight: 600;
        color: #222;
    }
    .ptm-map-sidebar-show-results {
        display: block;
        width: 100%;
        padding: 12px;
        border: none;
        border-radius: 8px;
        background: var(--evp-bleu-parisien, #2C5F8D);
        color: #fff;
        font-weight: 700;
        font-size: 0.95rem;
        text-transform: none;
        letter-spacing: normal;
        cursor: pointer;
    }
    .ptm-map-sidebar-show-results:hover,
    .ptm-map-sidebar-show-results:focus,
    .ptm-map-sidebar-show-results:active {
        background: var(--evp-bleu-parisien-hover, #234a6f);
        color: #fff;
        outline: none;
    }
    /* Contrôles Leaflet (zoom, recentrer, géoloc — tous en 'topright', regroupés par Leaflet dans
       .leaflet-top.leaflet-right) : z-index natif 1000 (leaflet.css), donc flottent au-dessus de
       la feuille de filtres plein écran (z-index 500) alors que la carte qu'ils contrôlent est
       masquée en dessous (retour utilisateur : "toutes les icônes restent visibles"). Masqués
       tant que la feuille est ouverte — n'affecte pas la pastille Filtres elle-même, qui n'est pas
       dans ce conteneur (enfant de .ptm-map-layout, pas de Leaflet) et doit rester cliquable pour
       refermer le panneau. */
    .ptm-map-layout-sidebar-open .leaflet-top.leaflet-right {
        display: none;
    }
    /* Message de statut ("Chargement des lieux…") : z-index 550, plus haut que la feuille de
       filtres (500), donc passait par-dessus elle (retour utilisateur). Pas utile à voir pendant
       qu'on filtre — la carte qu'il concerne est masquée en dessous. */
    .ptm-map-layout-sidebar-open .ptm-map-status {
        display: none;
    }
    /* Même raisonnement pour l'attribution Leaflet/OpenStreetMap, coin bas-droit
       (.leaflet-bottom.leaflet-right) — oubliée du premier passage (qui ne visait que les
       contrôles du haut), restait visible par-dessus la feuille de filtres (retour utilisateur :
       "toujours un souci sur openstreetmap"). */
    .ptm-map-layout-sidebar-open .leaflet-bottom.leaflet-right {
        display: none;
    }
}

/* Topbar mobile — recherche + chips de couches ne tiennent pas sur une ligne à cette largeur.
   Scroll horizontal façon Airbnb (retour utilisateur, référence explicite) plutôt qu'un wrap
   multi-lignes ou une réduction en menu déroulant — change le moins possible le composant chip
   déjà en place. La recherche reste hors du scroll (elle a son propre besoin d'espace, cf.
   ci-dessous) : seul .ptm-map-layers défile, pas toute la topbar. */
@media (max-width: 768px) {
    .ptm-map-topbar {
        justify-content: flex-start; /* le centrage desktop n'a plus de sens avec un scroll */
    }
    .ptm-map-layers {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: thin;
        min-width: 0; /* laisse flex réduire ce conteneur sous son contenu naturel, condition du scroll */
        padding-bottom: 6px; /* évite que la scrollbar colle aux chips — 2px ne suffisait pas
                                 (scrollbar tactile probablement en overlay, flotte par-dessus le
                                 padding plutôt que de réserver sa propre place, retour utilisateur) */
    }
    .ptm-map-layers::-webkit-scrollbar {
        height: 4px;
    }
    /* Chip mobilité (DEV117) — désormais un VRAI membre de .ptm-map-layers (cf. makeMobilityChip()
       dans map-cluster.js) : elle défile avec les autres couches comme n'importe quel autre chip,
       plus besoin d'un traitement mobile à part (icône seule, padding réduit) — ancien correctif
       retiré, la cause structurelle (chip hors du conteneur de défilement) est réglée à la racine. */
    /* Ouverte, la capsule de recherche remplit l'espace dispo plutôt qu'une largeur fixe (340px,
       quasiment tout l'écran sur mobile) — sans ça, ouvrir la recherche pousserait les chips hors
       champ au lieu de s'adapter proprement à la ligne (retour utilisateur).
       min-width:220px (pas 0) : un plancher garanti — sans lui, le partage d'espace avec
       .ptm-map-layers (aussi flexible) pouvait laisser au champ moins de place que prévu, texte
       tronqué dès "Recherche" (retour utilisateur : "on ne sait pas ce qu'on cherche"). Le
       plancher force .ptm-map-layers (min-width:0, lui) à céder la place/scroller à la place. */
    .ptm-map-search-open {
        flex: 1 1 220px;
        min-width: 220px;
    }
    .ptm-map-search-open .ptm-map-search-capsule {
        width: 100%;
    }
    /* Police légèrement réduite en mobile — laisse voir plus de texte dans l'espace disponible. */
    .ptm-map-search-open .ptm-map-search-input {
        font-size: 0.85rem !important;
    }
}

.ptm-map-all {
    width: 100%;
    flex: 1 1 auto;
    min-height: 0; /* laisse flex-basis:auto ne pas imposer la hauteur naturelle du contenu Leaflet */
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

/* Aucun contour de focus sur ce conteneur, dans aucun état. Leaflet rend son conteneur focusable
   au clavier (pan/zoom aux flèches) — un simple clic souris déclenchait :focus, puis même en
   passant à :focus-visible (censé ne réagir qu'au clavier) le contour bleu restait visible au clic
   sur ce `<div tabindex>` (retour utilisateur répété : "toujours la border bleue" — l'heuristique
   :focus-visible de Leaflet/Chrome sur un conteneur générique ne filtre pas la souris de façon
   fiable ici). outline:none inconditionnel plutôt qu'une nouvelle variante de pseudo-classe. */
.ptm-map-all:focus,
.ptm-map-all:focus-visible {
    outline: none;
}

/* Petit bouton rond à chevron, posé sur la jonction sidebar/carte (façon Booking) — remplace
   l'ancien bouton texte "Filtres" dans une barre, jugé pas assez explicite comme affordance de
   fermeture/ouverture (retour utilisateur). Fermée : entièrement dans la carte (`left:16px`, pas
   de transform) — sidebar fermée = pas de jonction à cheval, `translateX(-50%)` à `left:0` aurait
   coupé la moitié gauche du bouton via l'`overflow:hidden` de `.ptm-map-all-wrap` (bug signalé :
   "fermé c'est pas visible"). Ouverte : `left:300px` + `translateX(-50%)` centre le bouton
   exactement sur la jonction sidebar/carte, qui existe réellement dans cet état. Fond clair par
   défaut (contrôle flottant façon Leaflet) ; adapte ses couleurs en dark mode plus bas dans ce
   fichier — la sidebar elle-même passant au noir en dark mode, un rond toujours blanc y jurait
   visuellement (retour utilisateur), contrairement à quand la carte environnante était claire. */
.ptm-map-filters-toggle {
    position: absolute;
    top: 50%; /* centré verticalement sur toute la hauteur de la ligne sidebar/carte — pas de
                 top:16px fixe, qui plaçait le bouton quasi collé au titre "Filtres" tout en haut
                 de la sidebar (chevauchement visuel signalé, retour utilisateur). Même logique que
                 le sélecteur de repli/dépli d'un panneau Booking/VSCode : centré sur le bord, pas
                 aligné sur l'en-tête. */
    left: 16px;
    transform: translateY(-50%);
    z-index: 600; /* > sidebar mobile (500) — reste cliquable par-dessus la feuille plein écran */
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: 1px solid rgba(0,0,0,0.15);
    background: #fff;
    box-shadow: 0 1px 4px rgba(0,0,0,0.25);
    font-size: 1.2rem;
    line-height: 1;
    color: #333;
    cursor: pointer;
}
.ptm-map-layout-sidebar-open .ptm-map-filters-toggle {
    left: 300px; /* = largeur de .ptm-map-sidebar */
    transform: translate(-50%, -50%); /* centre horizontalement sur la jonction ET verticalement */
}
/* Fond plein (pas rgba à faible opacité) — ce bouton flotte directement sur les tuiles de carte,
   sans barre blanche derrière lui (contrairement à .ptm-recenter-btn) : un fond translucide y
   laisse la carte transparaître à travers le bouton, visible et jugé "transparent" par
   l'utilisateur (retour). Teinte pleine et claire au lieu de rgba(...,0.08), quasi invisible. */
.ptm-map-filters-toggle:hover {
    background: #eaf1f7;
    border-color: var(--evp-bleu-parisien, #2C5F8D);
}
/* outline:none — un anneau fin avait d'abord remplacé l'anneau par défaut du navigateur (trop
   épais/mal centré), mais reste perçu comme une bordure indésirée au clic (retour utilisateur,
   même constat que pour les cases à cocher et .ptm-map-all : aucun contour de focus nulle part
   sur les contrôles de cette carte). */
.ptm-map-filters-toggle:focus,
.ptm-map-filters-toggle:active {
    /* Même précaution que .ptm-map-sidebar-more/-reset : le thème réaffirme son style CTA
       (fond noir/texte blanc) au focus/actif, pas seulement au repos — background/color
       explicitement reposés ici, pas juste l'anneau de focus. */
    background: #fff;
    color: #333;
    outline: none;
}
@media (max-width: 768px) {
    /* Pastille flottante "Filtres" (icône + libellé + badge), posée en bas-centré sur la carte
       façon Booking — remplace l'ancien chevron en coin haut-droit, jugé pas assez visible comme
       point d'entrée des filtres sur mobile (retour utilisateur explicite : "je n'aime pas du
       tout sur mobile"). Position basse-centrée : zone naturellement accessible au pouce.
       Palette identique au chevron desktop (clair #fff/#333, dark #2a2a2a/#e8e0d5 plus bas) —
       même famille de contrôle flottant, juste une forme différente sur cette largeur. */
    .ptm-map-filters-toggle-mobile,
    .ptm-map-layout-sidebar-open .ptm-map-filters-toggle-mobile {
        top: auto;
        left: 50%;
        /* 40px (pas 16px) : dégage l'attribution Leaflet/OpenStreetMap posée dans le coin bas-
           droit, avec laquelle la pastille se chevauchait trop (retour utilisateur). */
        bottom: 40px;
        right: auto;
        transform: translateX(-50%);
        width: auto;
        height: auto;
        padding: 10px 16px;
        border-radius: 999px;
        gap: 7px;
        font-size: 0.85rem;
        font-weight: 600;
    }
    .ptm-map-filters-toggle-icon {
        display: inline-flex;
        width: 15px;
        height: 15px;
        flex-shrink: 0;
    }
    .ptm-map-filters-toggle-icon svg {
        display: block;
        width: 100%;
        height: 100%;
    }
    .ptm-map-filters-toggle-badge {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 16px;
        height: 16px;
        padding: 0 4px;
        border-radius: 999px;
        background: var(--evp-bleu-parisien, #2C5F8D);
        color: #fff;
        font-size: 0.68rem;
        font-weight: 700;
        line-height: 1;
    }
    html.is-dark-mode .ptm-map-filters-toggle-badge {
        color: #1a2530;
        background: #7AAED6;
    }
}

/* Sidebar : en-tête (titre), sections, cases à cocher, pied (résultats + réinitialiser) */
.ptm-map-sidebar-header {
    margin-bottom: 14px;
    padding-bottom: 10px;
    border-bottom: 1px solid rgba(0,0,0,0.1);
}
/* Regroupe titre + (flèche fermer sur mobile / compteur de résultats sur desktop) — même wrapper
   flex quel que soit l'écran, seul le contenu change (cf. buildSidebar()). */
.ptm-map-sidebar-header-start {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}
.ptm-map-sidebar-title {
    margin: 0; /* h2 depuis peu (heading-order) — annule la marge par défaut du navigateur */
    font-weight: 700;
    font-size: 0.95rem;
}
@media (min-width: 769px) {
    /* Desktop : compteur de résultats déplacé à côté du titre (retour utilisateur — au fond de la
       sidebar, sous une longue liste de filtres, il fallait scroller jusqu'au bout pour le voir).
       position:sticky essayé en premier (théoriquement fiable ici, contrairement à mobile, la
       sidebar desktop n'étant pas position:absolute) — mais même bug constaté en pratique
       (contenu déjà scrollé visible par-dessus, retour utilisateur : "texte passe derrière").
       Repris directement en flexbox, pattern déjà validé côté mobile : header/footer sortent de
       la zone qui défile (flex:0 0 auto), seul .ptm-map-sidebar-scroll (créé dans buildSidebar(),
       enveloppe déjà toutes les sections sur les deux formats) scrolle réellement. */
    .ptm-map-layout-sidebar-open .ptm-map-sidebar {
        display: flex;
        flex-direction: column;
        overflow: hidden;
    }
    .ptm-map-layout-sidebar-open .ptm-map-sidebar-header {
        flex: 0 0 auto;
        background: #fff;
    }
    .ptm-map-layout-sidebar-open .ptm-map-sidebar-scroll {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        overscroll-behavior: contain;
        scrollbar-width: thin;
        scrollbar-color: rgba(0,0,0,0.25) transparent;
    }
    .ptm-map-layout-sidebar-open .ptm-map-sidebar-footer {
        flex: 0 0 auto;
    }
    /* Plus visible qu'avant (0.78rem/#767676) — même retour utilisateur que côté mobile
       ("rendre plus visible"). */
    .ptm-map-sidebar-header .ptm-map-sidebar-results {
        margin: 0;
        font-size: 0.9rem;
        font-weight: 600;
        color: #333;
        white-space: nowrap;
    }
}
.ptm-map-sidebar-section {
    margin-bottom: 18px;
}
.ptm-map-sidebar-section-title {
    margin: 0 0 8px;
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: #666;
}
.ptm-map-sidebar-subgroup-label {
    margin: 10px 0 4px;
    font-size: 0.82rem;
    font-weight: 600;
    color: #444;
}
.ptm-map-checkbox-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
/* Grille 4 colonnes — réservée aux listes à libellés courts/uniformes (arrondissement : "1er"..
   "20e") via buildCheckboxList(..., grid=true). Gagne de la place verticale (20 lignes → 5,
   retour utilisateur) ; pas appliqué aux autres listes (type de lieu, expérience, quartier), dont
   les libellés plus longs/variables ne s'aligneraient pas proprement en grille. */
.ptm-map-checkbox-list-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px 4px;
}
/* Filtre PMR compact (icônes seules, cf. buildCheckboxList(..., iconOnly) dans map-cluster.js) —
   les 3 cases tiennent sur une seule ligne plutôt que 3 lignes empilées, tout le gain de place visé
   par l'utilisateur (icônes seules sans la ligne horizontale n'apportait aucun gain vertical). */
.ptm-map-checkbox-list-row {
    display: flex;
    flex-direction: row;
    gap: 22px;
}
.ptm-map-sidebar-checkbox {
    display: flex;
    align-items: center;
    gap: 8px;
    /* Le thème applique une marge par défaut aux <label> (8px, confirmé en direct via
       getComputedStyle) — combinée au gap:6px de .ptm-map-checkbox-list ci-dessus, ça donnait
       14px entre chaque ligne, jugé trop lâche pour une sidebar desktop (retour utilisateur).
       Même famille de piège que le text-transform des <button> trouvé plus tôt : ne jamais
       supposer qu'un élément de formulaire est neutre par défaut sur ce thème. */
    margin: 0;
    font-size: 0.85rem;
    color: #333;
    cursor: pointer;
}
.ptm-map-sidebar-checkbox input {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    accent-color: var(--evp-bleu-parisien, #2C5F8D);
    cursor: pointer;
}
/* Anneau de focus par défaut du navigateur sur les cases à cocher (épais, bleu vif) jamais
   neutralisé jusqu'ici — même famille de correctif déjà appliqué au bouton chevron et aux
   boutons de la sidebar (retour utilisateur). */
/* outline:none (pas d'anneau, même fin) — un anneau bleu avait été ajouté ici pour remplacer le
   style par défaut du navigateur (retour précédent), mais reste perçu comme une bordure indésirée
   une fois coché/cliqué (retour utilisateur : "toujours un border"). Même traitement que
   .ptm-map-all désormais : aucun contour de focus sur cet élément. */
.ptm-map-sidebar-checkbox input:focus {
    outline: none;
}
/* Filtre PMR compact (icônes seules, cf. buildCheckboxList(..., iconOnly) dans map-cluster.js) —
   le libellé complet reste dans le DOM via .screen-reader-text (classe déjà fournie par le thème,
   cf. style-final.css), juste retiré visuellement ici plutôt que redéfini. */
.ptm-map-checkbox-icon {
    font-size: 1.05rem;
    line-height: 1;
}
/* Bloc transversal du haut (arrondissements, coup de cœur, gratuit, patrimoine, fermés) —
   conteneur visuel distinct de la section "TYPE DE LIEU" : fond teinté, radius, gap uniforme
   entre les cases (pas de margin-bottom individuelle, c'est le gap du flex qui gère). */
.ptm-map-sidebar-top-block {
    display: flex;
    flex-direction: column;
    gap: 10px;
    background: rgba(44,95,141,0.06);
    border-radius: 8px;
    padding: 12px;
    margin-bottom: 18px;
}
html.is-dark-mode .ptm-map-sidebar-top-block {
    background: rgba(122,174,214,0.1);
}
/* Classe conservée pour compatibilité, désormais sans effet dans le bloc du haut (le gap du
   conteneur gère l'espacement). */
.ptm-map-sidebar-arr-toggle {
    margin-bottom: 0;
}
/* Section proximité (scénario A, cf. map-cluster.js buildSidebar()) — en tête de colonne,
   au-dessus du reste des filtres qui restent accessibles en dessous. */
.ptm-map-sidebar-proximity {
    margin-bottom: 18px;
    padding-bottom: 16px;
    border-bottom: 1px solid #e3ded4;
}
.ptm-map-proximity-pill {
    display: flex;
    align-items: center;
    gap: 8px;
    background: rgba(212,129,107,0.08);
    border: 1px solid rgba(212,129,107,0.3);
    border-radius: 8px;
    padding: 8px 10px;
    margin-bottom: 12px;
    font-size: 0.82rem;
}
.ptm-map-proximity-pill-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ptm-map-proximity-clear {
    flex-shrink: 0;
    background: none;
    border: none;
    font-size: 1.1rem;
    line-height: 1;
    color: #D4816B;
    cursor: pointer;
    padding: 0 2px;
}
.ptm-map-sidebar-proximity-row {
    display: flex;
    justify-content: space-between;
    font-size: 0.82rem;
    margin-bottom: 6px;
}
.ptm-map-sidebar-proximity-row span:last-child {
    font-weight: 700;
}
/* Thumb stylisé en dur (taille fixe 16px, identique aux 2 pseudo-éléments navigateur ci-dessous)
   — indispensable pour que le padding de .ptm-map-proximity-hints (8px = moitié du thumb) aligne
   vraiment les repères "3/5/7/10/15/20" sur la course réelle du curseur : la taille par défaut
   d'un thumb natif non stylisé varie selon navigateur/OS, impossible à deviner un padding qui
   marche partout sans fixer le thumb soi-même. padding:0 + border:none obligatoires : le thème
   a une règle globale `input[type="range"]{padding:0.375rem 1rem;border:2px solid...}` (style de
   formulaire générique, pensé pour les champs texte) qui s'appliquait aussi ici sans que ce
   sélecteur #id ne l'écrase — je ne déclarais pas ces 2 propriétés, donc rien à écraser malgré
   une spécificité CSS supérieure. Racine du décalage 3↔20 (confirmé par mesure DOM en direct,
   pas par supposition — 2 essais précédents corrigeaient le mauvais problème). */
#ptm-proximity-slider {
    width: 100%;
    margin-bottom: 4px;
    padding: 0;
    border: none;
    -webkit-appearance: none;
    appearance: none;
    height: 4px;
    border-radius: 2px;
    background: #ddd;
    outline: none;
}
#ptm-proximity-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #D4816B;
    cursor: pointer;
}
#ptm-proximity-slider::-moz-range-thumb {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #D4816B;
    border: none;
    cursor: pointer;
}
html.is-dark-mode #ptm-proximity-slider {
    background: #555;
}
.ptm-map-proximity-hints {
    display: flex;
    justify-content: space-between;
    font-size: 0.7rem;
    color: #999;
    margin-bottom: 8px;
    /* 8px = moitié de la largeur du thumb (16px) ci-dessus — aligne "3" sous le centre du thumb
       à sa position mini, "20" sous son centre à sa position maxi. */
    padding: 0 8px;
}
.ptm-map-proximity-count {
    margin: 0;
    font-size: 0.85rem;
    font-weight: 600;
    color: #2C5F8D;
}
html.is-dark-mode .ptm-map-sidebar-proximity {
    border-bottom-color: #404040;
}
html.is-dark-mode .ptm-map-proximity-pill {
    background: rgba(212,129,107,0.12);
    border-color: rgba(212,129,107,0.35);
}
.ptm-proximity-center-pin {
    filter: drop-shadow(0 2px 3px rgba(0,0,0,0.45));
}
html.is-dark-mode .ptm-map-proximity-count {
    color: #7AAED6;
}
.ptm-map-checkbox-list-collapsed .ptm-map-checkbox-extra {
    display: none;
}
.ptm-map-sidebar-more {
    align-self: flex-start;
    margin-top: 4px;
    padding: 2px 0;
    background: transparent;
    border: none;
    color: var(--evp-bleu-parisien, #2C5F8D);
    font-weight: 700;
    font-size: 0.8rem;
    text-transform: none;
    letter-spacing: normal;
    text-decoration: underline;
    cursor: pointer;
}
/* Le thème réaffirme son style CTA (fond noir, texte blanc) sur les <button> au focus/actif, pas
   seulement au repos — un simple clic (état :active/:focus juste après) suffisait à faire
   apparaître une pilule noire par-dessus le lien transparent voulu (retour utilisateur). Fond/
   couleur explicitement reposés sur ces deux états, pas juste au repos comme avant. */
.ptm-map-sidebar-more:focus,
.ptm-map-sidebar-more:active {
    background: transparent;
    color: var(--evp-bleu-parisien, #2C5F8D);
    outline: none;
}
.ptm-map-sidebar-footer {
    padding-top: 14px;
    border-top: 1px solid rgba(0,0,0,0.1);
}
.ptm-map-sidebar-results {
    margin: 0 0 10px;
    font-size: 0.82rem;
    color: #555;
}
.ptm-map-sidebar-results-icon {
    vertical-align: -3px;
    margin-right: 4px;
}
.ptm-map-sidebar-results-empty {
    color: #c00;
}
.ptm-map-sidebar-reset {
    display: block;
    width: 100%;
    padding: 8px;
    background: transparent;
    border: 1px solid rgba(0,0,0,0.15);
    border-radius: 6px;
    font-weight: 600;
    font-size: 0.82rem;
    text-transform: none;
    letter-spacing: normal;
    color: #333;
    cursor: pointer;
}
.ptm-map-sidebar-reset:hover {
    background: rgba(44, 95, 141, 0.08);
    border-color: var(--evp-bleu-parisien, #2C5F8D);
}
.ptm-map-sidebar-reset:focus,
.ptm-map-sidebar-reset:active {
    background: transparent;
    color: #333;
    outline: none;
}

html.is-dark-mode .ptm-map-sidebar {
    background: #1f1f1f;
    border-color: #444;
    scrollbar-color: rgba(255,255,255,0.25) transparent;
}
html.is-dark-mode .ptm-map-sidebar::-webkit-scrollbar-thumb {
    background: rgba(255,255,255,0.25);
}
html.is-dark-mode .ptm-map-sidebar-header,
html.is-dark-mode .ptm-map-sidebar-footer {
    border-color: #444;
}
html.is-dark-mode .ptm-map-sidebar-title,
html.is-dark-mode .ptm-map-sidebar-checkbox,
html.is-dark-mode .ptm-map-sidebar-reset {
    color: #e8e0d5;
}
@media (max-width: 768px) {
    html.is-dark-mode .ptm-map-layout-sidebar-open .ptm-map-sidebar-header,
    html.is-dark-mode .ptm-map-layout-sidebar-open .ptm-map-sidebar-footer {
        background: #1f1f1f; /* même fond que .ptm-map-sidebar en dark — sans ça, seul le fond
                                 clair par défaut s'appliquerait ici, alors que header/footer ont
                                 leur propre fond explicite (#fff) qu'il faut aussi adapter. */
    }
    html.is-dark-mode .ptm-map-sidebar-footer .ptm-map-sidebar-results {
        color: #e8e0d5;
    }
    html.is-dark-mode .ptm-map-sidebar-close {
        /* Fond clair (0,0,0,0.06) quasi invisible sur fond sombre — même correctif que
           .ptm-carte-back en dark mode (header compact). */
        background: rgba(255,255,255,0.1);
        color: #e8e0d5;
    }
    html.is-dark-mode .ptm-map-sidebar-close:hover,
    html.is-dark-mode .ptm-map-sidebar-close:focus,
    html.is-dark-mode .ptm-map-sidebar-close:active {
        background: rgba(255,255,255,0.18);
        color: #e8e0d5;
    }
    html.is-dark-mode .ptm-map-sidebar-show-results {
        background: #7AAED6;
        color: #1a2530;
    }
    html.is-dark-mode .ptm-map-sidebar-show-results:hover,
    html.is-dark-mode .ptm-map-sidebar-show-results:focus,
    html.is-dark-mode .ptm-map-sidebar-show-results:active {
        background: #6b9cc4;
        color: #1a2530;
    }
}
@media (min-width: 769px) {
    html.is-dark-mode .ptm-map-layout-sidebar-open .ptm-map-sidebar-header {
        background: #1f1f1f;
    }
    html.is-dark-mode .ptm-map-sidebar-header .ptm-map-sidebar-results {
        color: #e8e0d5;
    }
}
/* Le thème pose `html.is-dark-mode input:focus{outline:2px solid #7AAED6}` (sélecteur générique
   sans qualificatif de type — matche donc aussi les cases à cocher), avec une spécificité
   supérieure à `.ptm-map-sidebar-checkbox input:focus` (le préfixe `html.is-dark-mode` y ajoute un
   sélecteur de type que notre règle n'a pas) : notre `outline:none` était donc battu spécifiquement
   en dark mode, malgré le même correctif appliqué et fonctionnel en mode clair (retour utilisateur :
   "ok en clair, ko en dark"). Règle dédiée, plus spécifique que celle du thème, pour regagner. */
html.is-dark-mode .ptm-map-sidebar-checkbox input:focus {
    outline: none;
}
html.is-dark-mode .ptm-map-sidebar-section-title {
    color: #aaa;
}
html.is-dark-mode .ptm-map-sidebar-subgroup-label {
    color: #ccc;
}
html.is-dark-mode .ptm-map-sidebar-results {
    color: #b0b0b0;
}
html.is-dark-mode .ptm-map-sidebar-more {
    color: #7AAED6;
}
html.is-dark-mode .ptm-map-sidebar-reset {
    border-color: #555;
}
/* Dark mode sur .ptm-map-filters-toggle — revient sur la décision initiale ("contrôle flottant
   façon Leaflet, toujours clair") : jugé "ko" une fois la sidebar elle-même passée en dark mode
   (rond blanc plein qui jure sur le fond noir, retour utilisateur). Mêmes teintes que le reste de
   la sidebar en dark mode (fond #1f1f1f, bordures #555, accent #7AAED6). */
html.is-dark-mode .ptm-map-filters-toggle {
    background: #2a2a2a;
    border-color: #555;
    color: #e8e0d5;
}
/* Fond plein (pas rgba à faible opacité) — même piège que le hover clair déjà corrigé plus haut :
   ce bouton flotte seul sur la carte, sans fond de sidebar opaque derrière lui contrairement à
   .ptm-map-sidebar-reset (d'où ce style était recopié), donc toute transparence y reste visible
   (retour utilisateur : "hover est transparent"). */
html.is-dark-mode .ptm-map-filters-toggle:hover {
    background: #384854;
    border-color: #7AAED6;
}
html.is-dark-mode .ptm-map-filters-toggle:focus,
html.is-dark-mode .ptm-map-filters-toggle:active {
    background: #2a2a2a;
    color: #e8e0d5;
}
html.is-dark-mode .ptm-map-sidebar-reset:hover {
    background: rgba(122, 174, 214, 0.15);
    border-color: #7AAED6;
}
html.is-dark-mode .ptm-map-sidebar-more:focus,
html.is-dark-mode .ptm-map-sidebar-more:active {
    background: transparent;
    color: #7AAED6;
}
html.is-dark-mode .ptm-map-sidebar-reset:focus,
html.is-dark-mode .ptm-map-sidebar-reset:active {
    background: transparent;
    color: #e8e0d5;
}

/* Statut chargement / erreur (aria-live) */
/* Bandeau flottant sur la carte plutôt qu'une ligne dans le flux normal — une ligne réservée en
   permanence (même vide) sous la carte faisait dépasser le bas de la sidebar de 26px sous celui
   de la carte (retour utilisateur : "le bas toujours pas bon"), la sidebar remplissant toute la
   hauteur disponible alors que la carte s'arrêtait plus tôt pour laisser la place au statut. En
   overlay, la carte remplit 100% de .ptm-map-main (aligné avec la sidebar) et le message flotte
   par-dessus seulement quand il y a quelque chose à afficher (`:empty{display:none}`). Fond clair
   fixe (pas de dark mode) — même logique que le bouton chevron : un contrôle qui flotte sur la
   carte reste lisible sur des tuiles claires quel que soit le thème de la page. */
.ptm-map-status {
    position: absolute;
    left: 16px;
    bottom: 12px;
    z-index: 550;
    max-width: calc(100% - 32px);
    padding: 4px 10px;
    border-radius: 6px;
    background: rgba(255,255,255,0.92);
    box-shadow: 0 1px 4px rgba(0,0,0,0.2);
    font-size: 0.85rem;
    color: #5c6a6a;
}
.ptm-map-status-error {
    color: #c00;
}
.ptm-map-status:empty {
    display: none;
}

/* Bouton "Recentrer sur Paris" — hérite de .leaflet-bar a (leaflet.css) pour la taille/bordure,
   mais son hover générique gris clair (#f4f4f4) était jugé peu visible (retour utilisateur) —
   surchargé ici en teinte bleu marque, cohérent avec le reste des contrôles du filtre. Emoji
   agrandi (15px→19px) : trop petit pour bien identifier l'icône dans un bouton 26×26px. */
.ptm-recenter-btn {
    display: flex !important;
    align-items: center;
    justify-content: center;
    font-size: 19px;
}
/* Fond plein (pas rgba à faible opacité) — même piège déjà corrigé deux fois sur
   .ptm-map-filters-toggle (clair puis dark) : rgba(44,95,141,0.15) au survol laisse la carte
   transparaître à travers le bouton, malgré le fond blanc plein de Leaflet au repos (retour
   utilisateur : "transparente en dark ou clair" — ce n'est pas lié au thème, la même règle
   s'applique dans les deux cas puisqu'elle n'est pas scoping par mode). */
.ptm-recenter-btn:hover,
.ptm-recenter-btn:focus-visible {
    background-color: #dce8f0 !important;
}
.ptm-recenter-btn:focus-visible {
    outline: 2px solid #0073aa;
    outline-offset: -2px;
}
/* Dark mode — même raisonnement que pour .ptm-map-filters-toggle : un bouton toujours blanc jure
   une fois la sidebar/le reste de l'UI passés en sombre. */
html.is-dark-mode .ptm-recenter-control .ptm-recenter-btn {
    background-color: #2a2a2a !important;
}
html.is-dark-mode .ptm-recenter-btn:hover,
html.is-dark-mode .ptm-recenter-btn:focus-visible {
    background-color: #384854 !important;
}

/* Bouton "Me localiser" — même famille visuelle que .ptm-recenter-btn (hérite de .leaflet-bar a
   pour la taille/bordure, fond plein reposé au repos/hover/dark, jamais de rgba à faible opacité
   — même piège déjà corrigé deux fois ailleurs sur cette carte, cf. commentaire .ptm-recenter-btn). */
.ptm-geolocate-btn {
    display: flex !important;
    align-items: center;
    justify-content: center;
    font-size: 16px;
}
.ptm-geolocate-btn[aria-busy="true"] {
    opacity: 0.6;
    pointer-events: none;
}
.ptm-geolocate-btn:hover,
.ptm-geolocate-btn:focus-visible {
    background-color: #dce8f0 !important;
}
.ptm-geolocate-btn:focus-visible {
    outline: 2px solid #0073aa;
    outline-offset: -2px;
}
html.is-dark-mode .ptm-geolocate-control .ptm-geolocate-btn {
    background-color: #2a2a2a !important;
}
html.is-dark-mode .ptm-geolocate-btn:hover,
html.is-dark-mode .ptm-geolocate-btn:focus-visible {
    background-color: #384854 !important;
}

/* Marqueur "vous êtes ici" — point bleu + halo pulsant, CSS pur (pas d'image/icône externe,
   cohérent avec le reste du projet). Convention universelle (Google Maps/Uber/etc.), distincte
   des marqueurs de lieux pour ne pas laisser croire qu'il s'agit d'un lieu du catalogue. */
.ptm-user-location-icon {
    background: transparent;
    border: none;
}
.ptm-user-location-dot {
    /* Même taille que .ptm-search-result-dot (22px + bordure 3px = 28px, cf. iconSize associé
       dans buildUserLocationMarker()) — retour utilisateur : point "vous êtes ici" trop discret
       comparé au marqueur de résultat de recherche, alors que les deux jouent un rôle similaire
       (repère ponctuel, pas un lieu du catalogue). */
    position: absolute;
    top: 3px;
    left: 3px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: #1a73e8;
    border: 3px solid #fff;
    box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5);
}
.ptm-user-location-pulse {
    position: absolute;
    top: 0;
    left: 0;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: rgba(26, 115, 232, 0.35);
    animation: ptm-user-location-pulse 2s ease-out infinite;
}
@keyframes ptm-user-location-pulse {
    0%   { transform: scale(0.4); opacity: 1; }
    100% { transform: scale(1.6); opacity: 0; }
}

/* Contrôle zoom Leaflet natif (+/-) en dark mode — le thème (style-final.css) passe déjà le texte
   en #ccc via `html.is-dark-mode .leaflet-control-zoom a{color:#ccc!important}`, mais ne touche
   jamais le fond, resté blanc (hérité de leaflet.css) : texte gris clair sur fond blanc, contraste
   insuffisant (retour utilisateur). Fond sombre ajouté ici en complément, cohérent avec le reste
   des contrôles de la carte en dark mode.
   DUPLICATION CONNUE : cette même règle a été recopiée dans le thème
   (overflow-child/style.css, ~ligne 3963) car ce fichier-ci n'est chargé que sur
   /carte-paris/ et les archives, pas sur single-lieu.php (leaflet-custom.css n'a
   pas cette règle). Sur /carte-paris/ les deux fichiers se chargent ensemble —
   valeurs identiques actuellement (#2a2a2a / #384854), à garder synchronisées. */
html.is-dark-mode .leaflet-control-zoom a {
    background-color: #2a2a2a !important;
}
html.is-dark-mode .leaflet-control-zoom a:hover,
html.is-dark-mode .leaflet-control-zoom a:focus {
    background-color: #384854 !important;
}

/* Labels numérotés des arrondissements */
.ptm-arr-label-icon {
    background: transparent;
    border: none;
}
.ptm-arr-label {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 18px;
    font-size: 0.7rem;
    font-weight: 700;
    background: rgba(255,255,255,0.9);
    border: 1px solid;
    border-radius: 3px;
}
html.is-dark-mode .ptm-arr-label {
    background: rgba(26,26,26,0.85);
}
/* Sans ça, un clic sur une zone d'arrondissement lui donne le focus et le navigateur dessine son
   contour de focus par défaut — pour une forme SVG, ce contour suit la *bounding box* du tracé,
   pas son contour réel (rectangle moche autour d'une forme irrégulière, retour utilisateur). Ces
   zones n'ont aucune action au clic (juste survol/tooltip informatif) — rien à perdre en
   accessibilité clavier à supprimer ce contour ici. */
.ptm-arr-zone:focus {
    outline: none;
}

/* Fallback noscript */
.ptm-map-fallback {
    margin-top: 10px;
    font-size: 14px;
}
.ptm-map-fallback a {
    color: #0073aa;
    text-decoration: none;
}
.ptm-map-fallback a:hover {
    text-decoration: underline;
}

/* Clusters — touch zone 50px min (WCAG), contraste > 4.5:1 */
.ptm-cluster-icon {
    background: transparent;
    border: none;
}
.ptm-cluster {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 50px;
    height: 50px;
    border-radius: 50%;
    color: #fff;
    font-weight: 700;
    font-size: 0.9rem;
    box-shadow: 0 2px 6px rgba(0,0,0,0.3);
    border: 2px solid #fff;
    cursor: pointer;
}
.ptm-cluster-sm { background: #2E7D32; } /* vert — 4.5:1 sur blanc */
.ptm-cluster-md { background: #E65100; } /* orange */
.ptm-cluster-lg { background: #C62828; } /* rouge */

/* Popup lieu — toute la carte est cliquable (photo + titre + méta), comme Booking/Airbnb */
.leaflet-popup-content-wrapper {
    border-radius: 8px;
}
.ptm-map-popup {
    display: flex;
    flex-direction: column;
    max-width: min(240px, 60vw);
    color: inherit;
    text-decoration: none;
    border-radius: 6px;
    outline-offset: 2px;
}
.ptm-map-popup:hover .ptm-map-popup-title,
.ptm-map-popup:focus-visible .ptm-map-popup-title {
    text-decoration: underline;
}
.ptm-map-popup img {
    width: 100%;
    height: auto;
    max-height: 90px;
    object-fit: cover;
    border-radius: 4px;
    margin-bottom: 6px;
}
.ptm-map-popup-body {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.ptm-map-popup-title {
    font-size: 0.95rem;
    font-weight: 700;
    color: #1a1a1a;
}
.ptm-map-popup-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 5px;
    margin-top: 2px;
}
.ptm-map-popup-badge {
    display: inline-block;
    font-size: 0.72rem;
    font-weight: 700;
    color: #fff;
    background: var(--evp-bleu-parisien, #2C5F8D);
    padding: 2px 8px;
    border-radius: 10px;
    white-space: nowrap;
}
.ptm-map-popup-location {
    font-size: 0.8rem;
    font-weight: 500;
    color: #333; /* contraste renforcé (~12:1 sur blanc) */
}
/* Fermeture du jour (_ptm_jours_fermeture, calculé côté JS — cf. isClosedToday() dans
   map-cluster.js) — même gabarit de pastille que .ptm-map-popup-badge, teinte alerte dédiée,
   au-dessus du titre (align-self : le parent .ptm-map-popup-body est en colonne). */
.ptm-map-popup-closed-today {
    display: inline-block;
    align-self: flex-start;
    font-size: 0.72rem;
    font-weight: 700;
    color: #7a3400;
    background: #ffd9a8;
    padding: 2px 8px;
    border-radius: 10px;
    white-space: nowrap;
}

/* Dark mode */
/* Leaflet garde un fond de popup blanc par défaut — assombri ici pour que les couleurs
   de texte dark mode ci-dessous restent lisibles (sinon texte clair sur fond blanc). */
html.is-dark-mode .leaflet-popup-content-wrapper,
html.is-dark-mode .leaflet-popup-tip {
    background: #262626;
}
html.is-dark-mode .ptm-map-popup-title { color: #f5f0e8; }
html.is-dark-mode .ptm-map-popup-badge { color: #1a1a1a; background: #7AAED6; }
html.is-dark-mode .ptm-map-popup-location { color: #ccc; }
html.is-dark-mode .ptm-map-popup-closed-today { color: #fff3e0; background: #7a3400; }
.ptm-map-popup-patrimoine {
    display: inline-block;
    align-self: flex-start;
    font-size: 0.72rem;
    font-weight: 700;
    color: #3d1a54;
    background: #e8d5f5;
    padding: 2px 8px;
    border-radius: 10px;
}
html.is-dark-mode .ptm-map-popup-patrimoine { color: #e8d5f5; background: #3d1a54; }

/* Signalement fermeture Google (DEV118) — même gabarit de pastille que les badges ci-dessus,
   teinte plus soutenue que "Fermé aujourd'hui" (routine) pour marquer un signal plus sérieux. */
.ptm-map-popup-closure-warning {
    display: inline-block;
    align-self: flex-start;
    font-size: 0.72rem;
    font-weight: 700;
    color: #7a3400;
    background: #ffcc80;
    padding: 2px 8px;
    border-radius: 10px;
    white-space: nowrap;
}
.ptm-map-popup-closure-warning--perm {
    color: #7a1414;
    background: #ffb3b3;
}
html.is-dark-mode .ptm-map-popup-closure-warning { color: #fff3e0; background: #7a3400; }
html.is-dark-mode .ptm-map-popup-closure-warning--perm { color: #ffe0e0; background: #7a1414; }

/* Icône invisible constatée en test réel (2026-08-08) malgré stroke="currentColor" inline —
   même correctif que .ptm-card-infos .ptm-closure-warning svg (single-lieu.php) : couleur et
   dimensions forcées explicitement plutôt que de compter sur l'héritage seul. */
.ptm-map-popup-closure-warning svg {
    stroke: currentColor !important;
    width: 12px !important;
    height: 12px !important;
    vertical-align: -1px;
    flex-shrink: 0;
}

/* Popup Data Paris (WC/Fontaines/Wifi) — simple <div>, pas un <a> comme les popups Lieux : pas
   de soulignement au survol (hériterait sinon de .ptm-map-popup:hover, pensé pour un lien). */
.ptm-map-popup-dp {
    padding: 4px 2px;
}
.ptm-map-popup-dp:hover .ptm-map-popup-title,
.ptm-map-popup-dp:focus-visible .ptm-map-popup-title {
    text-decoration: none;
}
/* Ligne RATP dans la popup carte (.ptm-line-badge/.ptm-transport-badges/.ptm-info-icon-svg
   viennent du thème, cf. single-lieu.php — couleur bleu parisien + variante dark mode déjà
   gérées par .ptm-info-icon-svg) — préfixe (icône M / texte "RER") + badge sur une ligne. */
.ptm-map-popup-line {
    align-items: center;
    margin-bottom: 4px;
}
.ptm-map-popup-line-icon svg {
    display: block;
}
.ptm-map-popup-line-prefix {
    font-size: 0.85rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    color: var(--evp-bleu-parisien, #1a3a5c);
}
html.is-dark-mode .ptm-map-popup-line-prefix {
    color: #7aaed6;
}
/* Badge ♿ (station métro avec ascenseur recensé, cf. p.pmr dans map-cluster.js) — fond fixe,
   pas d'override dark mode : même logique que les couleurs de ligne/couche Data Paris ci-dessus,
   déjà pensées indépendantes du thème clair/sombre. */
.ptm-map-popup-pmr {
    display: inline-block;
    margin-top: 6px;
    font-size: 0.92rem;
    font-weight: 700;
    color: #fff;
    background: #27ae60;
    padding: 4px 12px;
    border-radius: 12px;
}
/* Horaires OSM (opening_hours) — champ facultatif, présent uniquement sur les DAB qui l'ont
   renseigné dans OSM. Taille réduite, couleur neutre : info secondaire, pas une donnée éditoriale
   vérifiée. Pas de dark-mode override : même convention que les autres blocs Data Paris fixes. */
.ptm-map-popup-oh {
    margin-top: 5px;
    font-size: 0.82rem;
    color: #666;
    word-break: break-word;
}
/* Liens "Y aller ?" (Google Maps/Apple Maps/Citymapper, cf. buildDirectionsLinksHtml() dans
   map-cluster.js) — <div> séparé du <a> englobant de la popup lieu (pas de <a> imbriqué), donc
   pas de :hover partagé avec .ptm-map-popup — sa propre bordure de séparation en haut. */
.ptm-map-popup-directions {
    display: flex;
    align-items: center;
    gap: 11px;
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.ptm-map-popup-directions-label {
    font-size: 0.72rem;
    font-weight: 700;
    color: #666;
    flex-shrink: 0;
}
/* Pastilles rondes — vrais favicons des 3 services (cf. buildDirectionsLinksHtml() dans
   map-cluster.js, assets/images/directions/), fond blanc uniforme derrière chacune : leurs
   favicons sources n'ont pas tous le même traitement (pin Google transparent, cercle blanc
   Apple déjà présent, carré plein Citymapper) — un fond commun les aligne visuellement en
   rangée plutôt que de laisser paraître ces différences. */
.ptm-map-popup-directions-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: #fff;
    border: 1px solid rgba(0, 0, 0, 0.08);
    text-decoration: none;
}
.ptm-map-popup-directions-icon img {
    width: 24px;
    height: 24px;
    object-fit: contain;
    border-radius: 5px; /* adoucit les coins du carré plein Citymapper une fois réduit */
}
.ptm-map-popup-directions-icon:hover,
.ptm-map-popup-directions-icon:focus-visible {
    box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.12);
    outline: none;
}
html.is-dark-mode .ptm-map-popup-directions {
    border-top-color: rgba(255, 255, 255, 0.15);
}
html.is-dark-mode .ptm-map-popup-directions-label {
    color: #ccc;
}
html.is-dark-mode .ptm-map-popup-directions-icon {
    border-color: rgba(255, 255, 255, 0.15);
}
html.is-dark-mode .ptm-map-popup-directions-icon:hover,
html.is-dark-mode .ptm-map-popup-directions-icon:focus-visible {
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.25);
}

/* Clusters + marqueurs individuels des couches Data Paris — couleur dédiée par couche
   (cf. DATA_PARIS_LAYERS en JS), volontairement distincts des clusters Lieux (verts/orange/
   rouges par densité) et du point bleu "vous êtes ici", pour qu'on ne les confonde jamais. */
.ptm-dp-cluster {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    font-weight: 600;
    font-size: 0.85rem;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}
.ptm-dp-marker {
    /* Fond blanc + anneau coloré (pas un fond plein coloré) : l'emoji (🚻/🚰/📶) a ses propres
       couleurs opaques qui recouvraient presque tout un fond plein, rendant la couleur de couche
       quasi invisible (retour utilisateur — "design différent" entre cluster plein et marqueur
       individuel, alors que non voulu). Grammaire retenue : rempli = cluster (agrégat), anneau =
       point individuel — cohérente dans les deux sens plutôt qu'un raté visuel. */
    width: 26px;
    height: 26px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    line-height: 1;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
    background: #fff;
    border: 3px solid #fff;
}

/* ── Marqueur Journées du Patrimoine ⚜ ────────────────────────────────────── */
.ptm-patrimoine-marker-icon {
    background: transparent;
    border: none;
}
.ptm-patrimoine-marker {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: #5c2d7a;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 15px;
    line-height: 1;
    color: #fff;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
    border: 2px solid #fff;
}
