/* LA SCÈNE — LE CADRE DE LA CARTE SUR L'ACCUEIL.
 *
 * CE FICHIER NE REDESSINE PAS LA CARTE. public/map.css porte toute la mise en
 * page de l'application — la toile, le volet, sa poignée, la ligne de résultat,
 * les paliers. Elle est chargée (home.html, map=True) et on ne fait ici que
 * trois choses :
 *   1. redéclarer les cinq variables que map.css pose sur `.nearby-map-page`
 *      et qui n'existent donc pas sous `.home-page` ;
 *   2. neutraliser trois déclarations qui fuient de contract-sellers-map.css ;
 *   3. composer l'entête, la rangée de pastilles et le cadre.
 *
 * POINTS D'APPUI : 560, 860, 1180. Aucun autre. Le socle décrit 375px.
 */

/* ==========================================================================
 * 1. LES VARIABLES QUE map.css ATTEND — ET LE PIÈGE QU'ELLES REFERMENT
 *
 * `.nearby-map-shell` calcule sa hauteur en `calc(100dvh - var(--nearby-
 * header-height) - …)` et `.nearby-map-results` la sienne à partir de
 * --nearby-sheet-peek / -collapsed / -expanded. Ces cinq variables ne sont
 * déclarées que sur `.nearby-map-page`. Le corps de l'accueil est `home-page`.
 *
 * UNE var() NON RÉSOLUE REND LE calc() INVALIDE, ET UNE DÉCLARATION INVALIDE
 * EST JETÉE EN SILENCE : le volet prendrait une hauteur `auto`, la carte
 * n'aurait plus de tiroir, et rien n'apparaîtrait dans la console. Ces valeurs
 * ne sont donc pas du confort — elles sont la condition pour que le module
 * réemployé fonctionne.
 * ========================================================================== */
.home-page {
    /* Recopiée de map.css. C'est une constante, et c'est un risque : elle est
     * SURVEILLÉE là-bas par apps/core/test_carte_lisible.py, qui la recalcule
     * depuis site-header-public.css et rougit dès qu'elles divergent. La
     * recopier ici la sort de cette surveillance. */
    /* LA HAUTEUR DE L'EN-TETE, RECOPIEE FAUTE DE POUVOIR MESURER UN FRERE.
       Elle valait 118 : deux respirations de 10, deux rangees de 44 et 46, une
       gouttiere de 10. Le lot du pouce (08/09) a resserre les respirations a 6,
       la gouttiere a 6 et la recherche a la cible tactile de 44 — l'en-tete
       dessine desormais 106. Sans cette mise a jour, la coque de carte serait
       douze points trop courte et c'est le bas du volet qui paierait.
       `apps/core/test_carte_lisible.test_la_hauteur_d_entete_recopiee_est_encore_la_bonne`
       refait l'addition a chaque execution : cette copie ne peut plus deriver
       en silence. */
    --nearby-header-height: 106px;
    --nearby-map-gap: 10px;

    /* LE TIROIR SE MESURE EN POURCENTAGE DU CADRE, PAS DE LA VUE.
     * map.css écrit `min(32dvh, 268px)` parce que la carte y occupe la vue
     * entière. Ici le cadre fait 280px : 32dvh en mangeraient les trois quarts.
     * Le volet est en `position: absolute` dans `.nearby-map-app` : un
     * pourcentage s'y résout contre la hauteur du cadre. 42 % de 280 = 118px —
     * la poignée, la ligne de compte et UN résultat entier. Le reste se tire du
     * doigt. */
    --nearby-sheet-collapsed: 88px;
    /* 40 % : LA HAUTEUR QU'IL FAUT POUR TROIS RESULTATS, PAS UN POINT DE PLUS.
     *
     * Julien, 09/09 : « ya moyen de faire plus compact ». La reponse est
     * d'abord dans le CONTENU — l'en-tete est passe de deux lignes a une, la
     * ligne de resultat de 50 points de pas a 44 — et le compte, une fois pose,
     * dit ce qu'il manque :
     *
     *   34 % d'un cadre de 555 font 188,7 points. Retire la poignee (44, c'est
     *   une cible tactile), les respirations du volet (14) et l'en-tete
     *   compacte (22) : il reste 108 points de liste, soit DEUX lignes de 44
     *   et rien de la troisieme.
     *
     *   40 % en font 222. La liste recoit 142 points : trois lignes entieres
     *   (132) et huit points de la quatrieme, qui disent qu'il y en a d'autres
     *   sans en promettre le contenu.
     *
     * CE QUE CES 33 POINTS COUTENT, ET A QUI. Ils ne touchent NI la hauteur du
     * cadre (555, arbitree au point pres le 09/09 et non rediscutee ici), NI
     * l'etat par defaut de l'accueil, qui est `collapsed` a 88 points : le
     * premier ecran est identique au point pres. Le tiroir entrouvert n'existe
     * qu'apres un toucher sur un marqueur — c'est-a-dire au moment precis ou le
     * visiteur demande la liste. Lui rendre trois reponses au lieu d'une et
     * demie vaut 33 points de carte a cet instant-la.
     *
     * EN POURCENTAGE ET PAS EN dvh : le volet est en `position: absolute` dans
     * le cadre, un pourcentage s'y resout contre la hauteur du CADRE — c'est
     * bien de lui qu'on parle, pas de la vue. */
    --nearby-sheet-peek: 40%;
    --nearby-sheet-expanded: calc(100% - 48px);

    /* LA HAUTEUR DE LA SCÈNE — LE SEUL BOUTON DE L'ARBITRAGE.
     *
     * La spec demande « carte plein écran » au pouce. On sert 280px, et voici
     * pourquoi, en trois faits mesurés :
     *   - dev rend 49 points dont UN vendeur. Une carte plein écran serait un
     *     plein écran de vide ;
     *   - le garde-fou produit exige que le catalogue reste à UN scroll ; à
     *     100dvh il est à un scroll et demi une fois l'en-tête déduit ;
     *   - le plein écran EXISTE : c'est /carte/, que la pastille centrale
     *     surélevée de la barre basse atteint déjà.
     *
     * EN PIXELS AU POUCE, ET PAS EN dvh — C'EST DÉLIBÉRÉ. La lecture de feuille
     * des contrats sait convertir rem, vw et px ; elle ne sait pas convertir
     * dvh. Une hauteur en dvh sortirait la scène de toute mesure de contrat, et
     * les contrats de premier écran continueraient de tomber juste en ignorant
     * 280 pixels. Un vert qui ne mesure rien est pire que pas de contrat.
     *
     * Le jour où le recrutement remplit la carte, cette seule valeur change et
     * tout le reste suit. */
    /* 420 : LA CARTE EST L'OUTIL DE VENTE, ELLE PREND LA PLACE.
     * Julien, 09/09 : « la carte c'est pas assez grands ». Le paragraphe du
     * pouce, en bas de cette feuille, dit d'ou sortent les nombres. */
    --home-scene-h: 420px;
}

/* ==========================================================================
 * 2. LA SECTION
 *
 * `.nearby-map-shell` porte `height: calc(100dvh - …)` et `min-height: 420px`,
 * taillés pour une page qui n'est QUE la carte. Ici la section est un bloc
 * parmi cinq : elle reprend une hauteur automatique.
 * `.home-scene.nearby-map-shell` fait 0-2-0 contre 0-1-0 — on gagne
 * franchement, pas par l'ordre de chargement.
 * ========================================================================== */
.home-scene.nearby-map-shell {
    display: grid;
    gap: 8px;
    width: 100%;
    height: auto;
    min-height: 0;
    margin-top: 8px;
    overflow: visible;
}

.home-scene__entete {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}

.home-scene__titre {
    margin: 0;
    color: var(--hp-green, #245A3B);
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.1;
}

.home-scene__grand {
    flex: 0 0 auto;
    color: var(--hp-green, #245A3B);
    font-size: .8rem;
    font-weight: 700;
    text-decoration: none;
}

.home-scene__grand:focus-visible {
    outline: 3px solid var(--focus);
    outline-offset: 2px;
}

/* ==========================================================================
 * 3. LA BARRE DE FILTRES — UNE PASTILLE PAR CRITÈRE, ET UNE FEUILLE DESSOUS
 *
 * Elle remplace DEUX rangées de valeurs : les quatre intentions du hero et les
 * familles de la carte. Le motif est celui que Julien a nommé le 09/09
 * (« un système type leboncoin ») : la pastille porte le NOM du critère au
 * repos, la VALEUR une fois posée, et une croix pour l'effacer.
 *
 * ELLE RESTE SOUS LA CARTE, ET C'EST MESURÉ. À 390x844 la rangée tombe entre
 * 579 et 627 points du haut — soit les 69-74 % bas de l'écran, la zone où le
 * pouce arrive sans changer de prise. Posée sous la recherche, elle serait à
 * 107 points, c'est-à-dire dans les 13-18 % hauts que la règle du pouce
 * réserve à ce qu'on LIT et jamais à ce qu'on TOUCHE. C'est la place que le
 * lot du 08/09 avait déjà donnée aux familles, pour ce motif exact.
 *
 * AUCUN `mask-image` SUR LA RANGÉE, ET CE N'EST PAS UN OUBLI. Un masque crée
 * un bloc conteneur pour tout descendant en `position: fixed` — exactement
 * comme `transform` et `filter`. Les feuilles de cette barre SONT en
 * `position: fixed` au pouce : le masque les enfermerait dans une rangée de
 * quarante-huit points de haut. Le dégradé de bord est donc peint par un
 * `::after` du formulaire, qui ne change aucun bloc conteneur.
 * ========================================================================== */
.home-filtres {
    position: relative;
    min-width: 0;
}

.home-filtres__rangee {
    display: flex;
    /* LES 32 POINTS QUI MANQUENT SE PRENNENT LA OU ILS NE SE VOIENT PAS.
       Chaque pastille porte DEUX glyphes — celui du critere et le chevron qui
       dit qu'une feuille s'ouvre. A `--ui-icon-xs` par defaut (5vw, soit 19,5
       a 390 points), les trois pastilles demandent 384 points pour 374
       disponibles : la derniere est tranchee. Le glyphe descend a 15 — au-dessus
       d'un corps de 11,9, il reste plus grand que la lettre —, la respiration
       laterale de 14 a 10 et la gouttiere interne de 6 a 4. La rangee tient, et
       la hauteur tactile ne bouge pas d'un point : 44.
       C'est le meme arbitrage, aux memes valeurs, que celui que la rangee du
       hero avait paye le 08/09. */
    --ui-icon-xs: 15px;
    gap: 6px;
    overflow-x: auto;
    padding-block: 2px;
    scrollbar-width: none;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
}

.home-filtres__rangee::-webkit-scrollbar { display: none; }

/* LE BORD QUI S'EFFACE EST LA SEULE CHOSE QUI DISE « ça continue ». La rangée
   était coupée NET au bord droit et rien ne signalait qu'on pouvait pousser.
   Vingt-six points de fondu, sans zone tactile mangée : `pointer-events` est
   coupé, la pastille qui passe dessous reste cliquable. */
.home-filtres::after {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 26px;
    /* LE FONDU SE PEINT DANS LA COULEUR DU FOND REEL, PAS D'UNE COULEUR
       VOISINE. La coque de l'accueil est `--home-cream` (#f8f5ef, contract-
       shell.css) ; un degre vers `--hp-surface-warm` (#FFF8EC) laisserait une
       bande claire de vingt-six points le long du bord droit — un defaut qu'on
       ne voit qu'a la loupe et qu'on ne s'explique jamais. */
    background: linear-gradient(to right, rgba(248, 245, 239, 0), var(--home-cream, #f8f5ef));
    pointer-events: none;
    content: "";
}

.home-filtres__critere {
    position: relative;
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    scroll-snap-align: start;
}

/* LE MARQUEUR NATIF DE `<summary>` N'A RIEN À FAIRE ICI : la pastille est déjà
   un objet composé, un triangle en plus la rendrait bavarde. Même geste que le
   sélecteur de lieu de l'en-tête. */
.home-filtres__pastille {
    min-height: var(--tap-size);
    padding-inline: 10px;
    gap: 4px;
    font-size: .85rem;
    cursor: pointer;
    list-style: none;
}

.home-filtres__pastille::-webkit-details-marker { display: none; }

/* LA PASTILLE POSÉE SE REMPLIT, ET LA CROIX LUI EST COLLÉE.
   Pleine, elle se lit d'un coup d'œil au milieu de celles qui ne le sont pas —
   c'est tout ce que le motif demande. La croix perd l'arrondi de gauche pour
   que les deux ne fassent qu'un objet à l'œil, et reste une cible à part
   entière au doigt. */
.home-filtres__critere.is-active .home-filtres__pastille {
    border-color: var(--hp-green, #245A3B);
    background: var(--hp-green, #245A3B);
    color: var(--hp-surface-warm, #FFFDF7);
    border-end-end-radius: 0;
    border-start-end-radius: 0;
    padding-inline-end: 8px;
}

.home-filtres__croix {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 38px;
    min-height: var(--tap-size);
    padding-inline-end: 6px;
    border: 1px solid var(--hp-green, #245A3B);
    border-inline-start: 0;
    border-radius: 0 999px 999px 0;
    background: var(--hp-green, #245A3B);
    color: var(--hp-surface-warm, #FFFDF7);
}

.home-filtres__croix:focus-visible,
.home-filtres__pastille:focus-visible,
.home-filtres__tout-effacer:focus-visible {
    outline: 3px solid var(--focus);
    outline-offset: 2px;
}

/* Le chevron dit qu'il y a quelque chose derrière, et tourne quand c'est
   ouvert. Le jeu d'icônes maison ne porte pas de `chevron-down` : on tourne le
   `chevron-right`, plutôt que de tracer un quarante-deuxième glyphe pour un
   quart de tour. */
.home-filtres__chevron {
    display: inline-flex;
    rotate: 90deg;
    transition: rotate .18s var(--ui-motion-ease, ease);
}

.home-filtres__boite[open] .home-filtres__chevron { rotate: -90deg; }

.home-filtres__couche {
    flex: 0 0 auto;
    min-height: var(--tap-size);
    font-size: .85rem;
    scroll-snap-align: start;
}

.home-filtres__choix-compte {
    margin-inline-start: 4px;
    opacity: .72;
    font-variant-numeric: tabular-nums;
}

/* « Tout effacer » N'EST PAS UNE PASTILLE DE PLUS. Il ne pose rien : il défait.
   Il se rend donc en trait, à la fin de la rangée, et il ne paraît que
   lorsqu'il a quelque chose à défaire. */
.home-filtres__tout-effacer {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex: 0 0 auto;
    min-height: var(--tap-size);
    padding-inline: 10px;
    border-radius: 999px;
    color: var(--hp-orange, #C86138);
    font-size: .8rem;
    font-weight: 700;
    text-decoration: none;
}

.home-filtres__compte {
    display: inline-grid;
    place-items: center;
    min-width: 20px;
    min-height: 20px;
    padding-inline: 5px;
    border-radius: 999px;
    background: var(--hp-orange, #C86138);
    color: #FFFFFF;
    font-size: .7rem;
    font-variant-numeric: tabular-nums;
}

/* --- LA FEUILLE ---------------------------------------------------------
 *
 * Même mécanique que le sélecteur de lieu (css/components/location-selector.css)
 * et pour les mêmes raisons : `<details>` porte l'ouverture, le CSS décide de
 * la forme — volet bas au pouce, popover ancré au desktop. Aucun script.
 * ------------------------------------------------------------------------ */
.home-filtres__feuille {
    display: grid;
    gap: 8px;
    padding: 14px;
    background: var(--ui-plan-raised, #FFFDF8);
    color: var(--ui-color-ink, #241D16);
}

.home-filtres__anse { display: none; }

.home-filtres__titre {
    margin: 0;
    font-family: var(--ui-font-display, Georgia, serif);
    font-size: 1.02rem;
    font-weight: 600;
}

.home-filtres__choix {
    display: grid;
    gap: 2px;
    max-height: 46dvh;
    margin: 0;
    padding: 0;
    overflow-y: auto;
    list-style: none;
}

/* LE CHOIX EST UN `<label>` QUI ENVELOPPE SON RADIO : toute la ligne devient
   la cible, et le rapport libellé/contrôle est porté par le balisage plutôt
   que par un `for` à tenir à jour. */
.home-filtres__choix-ligne {
    display: flex;
    align-items: center;
    gap: 9px;
    min-height: var(--tap-size);
    padding: 6px 10px;
    border-radius: var(--ui-radius-sm, 8px);
    cursor: pointer;
}

.home-filtres__choix-ligne:hover,
.home-filtres__choix-ligne:focus-within {
    background: var(--ui-plan-sunk, #F4EBD9);
}

.home-filtres__choix-mot { flex: 1 1 auto; }

.home-filtres__pied {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding-top: 4px;
}

.home-filtres__effacer {
    min-height: var(--tap-size);
    display: inline-flex;
    align-items: center;
    padding-inline: 6px;
    color: var(--hp-muted, #6E6252);
    font-size: .82rem;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* CE BOUTON N'EST PAS `.ui-cta`, ET C'EST UNE RÈGLE DE LA MAISON : `.ui-cta`
   désigne LE geste que la page attend, et il n'y en a qu'un par écran. Un
   bouton rangé dans un panneau replié n'est pas celui-là — un contrat de
   l'écran d'inscription l'a déjà rappelé en rougissant. Même habillage que
   `.lieu__geoloc`, qui a tranché la même question. */
.home-filtres__voir {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--tap-size);
    padding-inline: 16px;
    border: 0;
    border-radius: 999px;
    background: var(--hp-green, #245A3B);
    color: var(--hp-surface-warm, #FFF8EC);
    font: inherit;
    font-size: .85rem;
    font-weight: 700;
    cursor: pointer;
}

@media (max-width: 899px) {
    .home-filtres__boite[open] .home-filtres__feuille {
        position: fixed;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 200;
        max-height: 82dvh;
        padding: 16px 16px calc(18px + env(safe-area-inset-bottom));
        border-radius: 20px 20px 0 0;
        overflow-y: auto;
        box-shadow: 0 -18px 44px rgba(22, 41, 28, .26);
    }

    /* Le voile derrière, dessiné par la feuille elle-même plutôt que par un
       élément de plus : un `<details>` ouvert n'a qu'un enfant à habiller.
       C'est le geste de location-selector.css, repris tel quel. */
    .home-filtres__boite[open] .home-filtres__feuille::before {
        position: fixed;
        inset: 0;
        z-index: -1;
        background: rgba(11, 24, 18, .42);
        content: "";
    }
}

@media (min-width: 900px) {
    .home-filtres__boite[open] .home-filtres__feuille {
        position: absolute;
        top: calc(100% + 9px);
        left: 0;
        z-index: 60;
        width: 302px;
        border: 1px solid var(--ui-color-sable, #E7DCC6);
        border-radius: var(--ui-radius-card, 14px);
        box-shadow: 0 18px 38px rgba(22, 41, 28, .18);
    }
}

/* ==========================================================================
 * 4. LE CADRE — LA CARTE DEVIENT UN OBJET, PAS UN TROU DANS LA PAGE
 *
 * Même rayon d'angle, même filet sable, même ombre que les cartes produit du
 * bandeau juste dessous : la scène appartient à la même famille visuelle, elle
 * est simplement la plus grande. Une carte à fond perdu ferait un trou.
 * ========================================================================== */
.home-scene__cadre {
    position: relative;
    height: var(--home-scene-h);
    overflow: hidden;
    border: 1px solid var(--hp-border-strong, #DFD4C3);
    border-radius: 18px;
    background: #DFE8DC;
    box-shadow: 0 10px 26px rgba(27, 29, 24, .10);
    /* NI transform, NI filter, NI backdrop-filter, NI contain ICI. Chacun
     * créerait un bloc conteneur pour tout descendant en `position: fixed` — un
     * seul pixel suffit — et la barre basse de l'accueil atterrirait dans la
     * carte. */
    isolation: isolate;
}

/* map.css pose `grid-template-rows: auto minmax(0, 1fr)` parce que la première
   rangée accueillait map_controls.html. Ici il n'y a plus de mobilier dans le
   cadre : une seule rangée, et la toile la remplit. */
.home-scene .nearby-map-app {
    grid-template-rows: minmax(0, 1fr);
    height: 100%;
    border-radius: inherit;
}

/* ==========================================================================
 * 5. LES TROIS DÉCLARATIONS QUI FUIENT DE contract-sellers-map.css
 *
 * C'est le seul vrai effet de bord de ce lot, et il est nommé plutôt que subi.
 *
 * contract-sellers-map.css déclare encore `.nearby-map-canvas` — l'ancienne
 * carte d'accueil, dont AUCUN gabarit ne rend plus les classes. Jusqu'ici les
 * deux feuilles ne se croisaient jamais : map.css n'était chargée que sur
 * /carte/, contract-sellers-map.css que sur `/`. Charger les deux met les deux
 * blocs `.nearby-map-canvas` dans la même cascade, à égalité de spécificité
 * (0-1-0). map.css est chargée APRÈS et l'emporte sur `position`, `z-index` et
 * `background` — mais TROIS déclarations qu'elle ne redéclare pas passent au
 * travers :
 *
 *     min-height: 235px            forcerait la toile à 235px dans un cadre
 *                                  qui pourrait un jour être plus court
 *     border: 1px solid …          un second filet À L'INTÉRIEUR du cadre
 *     border-radius: 14px          un second arrondi, 4px hors du nôtre
 *
 * On les annule explicitement, avec 0-2-0. L'alternative — supprimer les
 * 630 lignes — casse test_home_map_visual_contract.py, qui exige que
 * `.home-page .nearby-map-canvas .leaflet-control-zoom a` y soit déclarée.
 * Ce nettoyage est l'incrément d'hygiène, pas celui-ci.
 * ========================================================================== */
.home-scene .nearby-map-canvas {
    min-height: 0;
    border: 0;
    border-radius: 0;
}

/* Le bouton « Me localiser » est calibré pour une carte plein écran. Dans un
   cadre de 280px, il se resserre — mais SEULEMENT en respiration laterale.
   LA POSITION DU BOUTON N'EST PLUS DECIDEE ICI.
   Elle l'etait — `top: 8px; right: 8px` — et elle gagnait sur map.css par sa
   specificite, si bien que la descente du bouton dans la zone du pouce n'aurait
   pris que sur /carte/ et pas sur l'accueil. Un geste, une regle : map.css. */
.home-scene .nearby-map-locate {
    padding: 0 10px;
}

/* Le volet épouse l'arrondi du cadre par le bas. */
.home-scene .nearby-map-results {
    border-radius: 18px 18px 0 0;
}

/* LA PATERNITÉ A QUITTÉ LE CADRE, ET ELLE N'A PAS DISPARU (09/09).
 *
 * Elle vivait ici, en surimpression dans le coin haut gauche de la toile, et
 * ce coin est la partie la plus utile de la carte. Mesurée à 390x844 sur le
 * rendu servi : trois lignes, 28,6 points de haut sur 360 de large, posées à
 * six points du bord haut du cadre — et écrites en 8,68 px (`.62rem` sur une
 * racine de 14) à 80 % d'opacité. C'est-à-dire qu'elle coûtait de la carte
 * SANS être lisible, ce qui est le pire des deux mondes pour une mention que
 * la licence impose.
 *
 * Julien, 09/09 : « le bandeau des provenances des datas on le mets tout en
 * bas de la pages pour gagner en lisibilité ».
 *
 * Elle est désormais rendue par `partials/map_paternite.html`, tout en bas du
 * fil de l'accueil, et habillée par `public/map.css` — une seule règle pour
 * les deux pages cartographiques. `test_paternite_des_cartes.py` exige sa
 * présence sur toute page qui porte une carte, et son corps de lecture.
 */

/* CE QUI SE LIT AU POUCE REMONTE A .78rem MINIMUM. Les corps du volet sont
   dimensionnes dans map.css pour une carte plein ecran regardee de pres ;
   dans un cadre au fil de la page, ils tombaient sous le seuil de lecture
   confortable. On ne retaille que sous notre toit (.home-scene). */
.home-scene .nearby-map-status {
    font-size: .78rem;
}

.home-scene .nearby-map-results__header h2 {
    font-size: 1.02rem;
}

/* SUR UN GRAND TELEPHONE, C'EST LE CONTENU QUI GRANDIT, PAS LA CARTE.
   « Les telephones hauts ont droit a plus de carte » disait la regle d'ici, et
   elle donnait 430px de cadre des 780px de hauteur d'ecran. C'etait vrai tant
   que la carte etait le seul contenu ; ca ne l'est plus depuis que Julien a
   constate, sur ce meme ecran haut, qu'il n'y voyait AUCUN produit.
   Le palier « max-width: 559px and min-height: 780px » donnait 430px de cadre
   aux telephones hauts. Il est mort : la regle du pouce, plus bas, borne
   desormais la carte pour toutes les largeurs de telephone. Deux paliers qui
   se disputaient la meme valeur, c'etait un duel qui ne se lisait nulle part. */

/* ==========================================================================
 * 560px — la scène respire un peu
 * ========================================================================== */
@media (min-width: 560px) {
    .home-page { --home-scene-h: clamp(420px, 58dvh, 620px); }
}

/* ==========================================================================
 * 860px — LA SCÈNE PASSE EN DEUX COLONNES
 *
 * map.css ne bascule /carte/ en panneau latéral qu'à 1024px, et rend la liste
 * sur DEUX colonnes dans le tiroir entre 700 et 1024. Correct pour une carte
 * plein écran ; faux dans un cadre de 432px, où le tiroir mangerait la moitié
 * de la scène. On bascule donc plus tôt ICI, et SEULEMENT ici : /carte/
 * conserve exactement ses paliers.
 * ========================================================================== */
@media (min-width: 860px) {
    .home-page { --home-scene-h: clamp(520px, 62dvh, 760px); }

    /* ON TRAVAILLE AVEC LES AREAS DE map.css, PAS CONTRE ELLES.
     *
     * A 1024px, map.css place la carte par `grid-template-areas`
     * ("controls map" / "results map"). Le premier jet redeclarait les
     * COLONNES sans toucher aux AREAS : mes tailles gagnaient, leurs
     * placements aussi — et la liste heritait de la colonne LARGE pendant que
     * la carte prenait l etroite. Exactement l inverse du but.
     *
     * On declare donc les areas nous-memes : le volet a gauche, etroit — une
     * table des matieres — et la carte a droite, en majeste. C est elle
     * l outil de vente.
     */
    .home-scene .nearby-map-app {
        grid-template-columns: clamp(280px, 24vw, 340px) minmax(0, 1fr);
        grid-template-rows: minmax(0, 1fr);
        grid-template-areas: "results map";
        /* map.css habille .nearby-map-app d un cadre complet a 1024px —
         * bordure, fond creme, ombre. Le notre existe deja (__cadre) :
         * deux cadres emboites feraient un passe-partout. */
        gap: 0;
        border: 0;
        border-radius: inherit;
        background: transparent;
        box-shadow: none;
    }

    .home-scene .nearby-map-viewport {
        grid-area: map;
        margin: 0;
        border-radius: 0;
        min-height: 0;
    }

    .home-scene .nearby-map-canvas {
        border: 0;
        border-radius: 0;
        box-shadow: none;
    }

    /* Le volet quitte la surimpression et devient la colonne de gauche :
     * une table des matieres le long de la carte, pas un rideau devant. */
    .home-scene .nearby-map-results {
        grid-area: results;
        position: relative;
        right: auto;
        bottom: auto;
        left: auto;
        height: auto;
        min-height: 0;
        margin: 0;
        border: 0;
        border-inline-end: 1px solid var(--hp-border-strong, #DFD4C3);
        border-radius: 0;
        box-shadow: none;
        backdrop-filter: none;
        transition: none;
        overflow-y: auto;
    }

    /* Les états du tiroir n'ont plus de sens en colonne. On les neutralise
       EXPLICITEMENT : sans ça, un appui antérieur sur la poignée laisserait une
       hauteur figée au redimensionnement. */
    .home-scene[data-sheet-state] .nearby-map-results { height: auto; }

    .home-scene[data-sheet-state="collapsed"] .nearby-map-list,
    .home-scene .nearby-map-list {
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
    }

    /* La poignée ne sert qu'à un tiroir. En colonne, elle n'ouvre rien — et un
       bouton qui ne répond à rien fait croire que le site est cassé. */
    .home-scene .nearby-map-results__handle { display: none; }
}

@media (min-width: 1180px) {
    .home-scene .nearby-map-app {
        grid-template-columns: clamp(300px, 22vw, 380px) minmax(0, 1fr);
    }
}

@media (prefers-reduced-motion: reduce) {
    .home-scene .nearby-map-results { transition: none; }
}


/* ==========================================================================
 * LE LIEN EPINGLE <-> LIGNE, EN CLAIR
 *
 * Le script fait deja la moitie du travail : toucher une epingle allume la
 * ligne et la fait defiler ; survoler une ligne active l epingle. Mais les
 * styles de map.css disent ce lien en murmure — une ombre, indiscernable d un
 * survol. Sous notre toit, la ligne active parle la langue de la marque : le
 * trait terracotta a gauche, le fond qui se teinte, et l epingle qui grossit
 * franchement. Un geste, une reponse — la signature du site.
 * ========================================================================== */
/* LA LIGNE ACTIVE SE PEINT SUR LE PSEUDO-ELEMENT, COMME LE RESTE DE LA LIGNE.
   Depuis que la cible (44) et la peinture (38) sont deux boites distinctes, un
   fond pose sur le bouton deborderait de trois points en haut et en bas de
   tout ce que la ligne montre — le trait terracotta se retrouverait plus haut
   que le cadre qu'il est cense border. */
.home-scene .nearby-map-item.is-active::before {
    border-color: var(--hp-orange, #C86138);
    border-inline-start: 4px solid var(--hp-orange, #C86138);
    background: rgba(200, 97, 56, .07);
    box-shadow: 0 8px 18px rgba(200, 97, 56, .14);
}

.home-scene .nearby-leaflet-marker.is-active {
    transform: translate(-50%, -100%) scale(1.22);
    filter: drop-shadow(0 6px 12px rgba(27, 29, 24, .3));
}

@media (prefers-reduced-motion: reduce) {
    .home-scene .nearby-map-item.is-active,
    .home-scene .nearby-leaflet-marker.is-active { transition: none; }
}

/* CE QUI SE LIT AU POUCE NE DESCEND PAS SOUS .78rem — LA LIGNE DE RESULTAT
   COMPRISE. map.css dimensionne le volet pour une carte plein ecran regardee
   de pres ; dans le cadre du fil de l'accueil, le nom tombait a 11,5 px et la
   commune a 9,5 px sur une racine de 14. Ce sont les deux seules choses qu'on
   lit dans cette liste : elles remontent, sans que la ligne grandisse — c'est
   la respiration qui a ete rendue, pas le texte. */
.home-scene .nearby-map-item strong {
    font-size: .88rem;
}

.home-scene .nearby-map-item small {
    font-size: .74rem;
}


/* Le mot qui porte la promesse du titre de scene. */
.home-scene__titre em {
    font-style: normal;
    color: var(--hp-orange, #C86138);
}

/* Densite mobile ciblee (26/08) : l'accroche de la scene cede la
   place a la carte et aux familles — c'est elle qu'on vient chercher. */
@media (max-width: 639px) {
    .home-scene__titre,
    .home-scene h2 {
        font-size: 1.02rem;
    }

    .home-scene__sous {
        font-size: .74rem;
    }
}

/* LA CARTE PREND SOIXANTE-DEUX POUR CENT DE L'ECRAN, ET VOICI L'ADDITION.
   Julien, telephone en main le 09/09 : « la carte c'est pas assez grands ».
   Elle valait 278,5 points sur les 748 utiles d'un iPhone 390x844 — 37 %, une
   vignette. `clamp(330px, 55dvh, 520px)` en donne 464,2, soit 62,1 %.
   D'OU VIENNENT LES 55 dvh, ET POURQUOI PAS 70. Le premier ecran doit encore
   montrer le nom et le prix d'un produit — c'est le garde-fou du 08/09, et il
   n'est pas rediscute. L'addition, mesuree par
   apps/public_site/test_premier_ecran_pouce.py : 57 d'en-tete, 9 de
   respiration, 33 de hero, 8+8 de gouttieres, 48 de barre de filtres, 7+44
   pour le titre du bandeau produit. Reste 748 - 214 - 60 = 474 points pour le
   cadre. 464 les tient, avec dix de marge.
   CE QUE 464 POINTS MONTRENT VRAIMENT : le tiroir replie occupe 88 points du
   bas du cadre, il reste donc 376 points de carte — un tiers de plus que le
   CADRE ENTIER d'avant. Et c'est la carte, pas une bande grise.
   LE PLANCHER EST A 330 ET PAS A 400, ET C'EST UN PETIT TELEPHONE QUI L'A
   DECIDE. A 375x667 — l'iPhone SE, encore massivement en service — 55 dvh font
   367 points, au-dessus du plancher : celui-ci ne sert donc qu'aux ecrans plus
   courts encore. Pose a 400, il aurait force 400 points de carte sur un ecran
   qui n'en offre que 571 d'utiles, et pousse la premiere rubrique hors du
   premier ecran — ce que le navigateur mesure dans apps/core/test_capture.py.
   Un plancher se cale sur le plus petit ecran, pas sur celui qu'on regarde.

   EN PIXELS ET EN dvh, JAMAIS EN %. La lecture de feuille des contrats sait
   convertir rem, vw, vh et dvh ; elle ne sait pas resoudre un % sans bloc
   conteneur. Une hauteur en % sortirait la scene de toute mesure. */
@media (max-width: 639px) {
    .home-page {
        /* 62dvh ET NON 55 — Julien, 09/09, telephone en main apres la
         * livraison de 14 h : « ok mais la carte un peu plus grande stp ».
         * A 844 points de haut, on passe de 464 a 510 points de carte.
         *
         * ON NE VA PAS PLUS HAUT, ET LA RAISON EST MESUREE : la premiere
         * fiche produit montrait 122 points au-dessus du pli, pour un minimum
         * contractuel de 60. Les 46 points repris a la fiche lui en laissent
         * 76. Le contrat `test_la_premiere_fiche_produit_affleure_au_dessus_
         * du_pli` tient l'autre bout : au-dela, c'est lui qui rougit, et il a
         * raison — une carte plus grande qui cache le prix du premier produit
         * n'est plus une carte, c'est un fond d'ecran. */
        /* 555 ET PAS UN PIXEL DE PLUS — LA BORNE EST CALCULEE.
         *
         * Le budget du premier ecran, mesure par
         * `test_premier_ecran_pouce`, est celui-ci a 390x844 :
         *   en-tete 57 + respiration 9 + scene 8 + respiration produits 7
         *   + titre du carrousel 44 = 125 points incompressibles,
         *   pour un pli a 748.
         * Il reste donc 623 points a partager entre la carte et la premiere
         * fiche produit, et cette fiche doit en montrer 60 — c'est le seuil
         * en dessous duquel son nom et son prix disparaissent.
         * 623 - 60 = 563 au maximum. On prend 555, et les 8 points d'ecart
         * sont la marge qui evite qu'un demi-pixel d'arrondi fasse rougir
         * le contrat.
         *
         * Ces 45 points de plus qu'hier viennent du hero, masque juste en
         * dessous : c'est l'arbitrage que Julien a accepte le 09/09 a 17 h. */
        --home-scene-h: clamp(330px, 66dvh, 555px);
    }

    /* L'ENTÊTE DE LA SCÈNE NE PAIE PLUS SA PLACE AU POUCE.
     * « Près de chez vous » et « Ouvrir la carte » coûtaient 23,7 points —
     * un titre pour dire ce qu'une carte montre, et un lien déjà porté par la
     * pastille surélevée de la barre basse (qui est masquée ici depuis le
     * 08/09). Le nom accessible de la section survit : `aria-labelledby`
     * désigne un titre que le calcul de nom lit même masqué, et c'est la seule
     * chose que ce titre avait encore à faire ici. */
    .home-scene__entete {
        display: none;
    }

    /* « Carte en grand » MENE OU MENE DEJA LA PASTILLE CENTRALE SURELEVEE de
       la barre basse : /carte/. Deux commandes pour une destination, dont une
       hors de portee du pouce — et elle coutait au titre la moitie de sa
       largeur, donc une ligne de plus. Elle revient des 640px, la ou la barre
       basse commence a s'effacer. */
    .home-scene__grand {
        display: none;
    }
}

/* ==========================================================================
 * 6. LE BOUTON DES FILTRES, ET LA FENÊTRE QU'IL OUVRE (09/09)
 *
 * Julien, iPhone en main : « Le système de filtre faut un petit bouton en haut
 * à droite de la carte qui ouvre une pop UP JS pour faire les sélections là
 * c'est nul ».
 *
 * PETIT À L'ŒIL, GRAND AU DOIGT. La cible fait `--tap-size` (44 points, le
 * plancher de WCAG 2.5.8) et elle est TRANSPARENTE ; ce qui se voit est une
 * pastille de 34 points centrée dedans. Les dix points de différence sont du
 * rembourrage invisible : le bouton se pose sur la carte sans la manger, et le
 * pouce le trouve quand même.
 *
 * IL EST EN HAUT À DROITE, ET CE COIN ÉTAIT LIBRE. Le zoom de Leaflet vit en
 * haut à gauche, « Me localiser » en bas à droite (map.css l'y a descendu le
 * 08/09, dans la zone du pouce), le volet monte du bas. Rien à déplacer.
 * ========================================================================== */
.home-filtres-bouton {
    position: absolute;
    top: 5px;
    right: 5px;
    z-index: 34;
    display: inline-grid;
    place-items: center;
    min-width: var(--tap-size, 44px);
    min-height: var(--tap-size, 44px);
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--hp-surface-warm, #FFFDF7);
    cursor: pointer;
}

.home-filtres-bouton__pastille {
    position: relative;
    display: inline-grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border: 1px solid rgba(255, 253, 247, .82);
    border-radius: 999px;
    background: rgba(36, 90, 59, .94);
    box-shadow: 0 10px 22px rgba(27, 29, 24, .22);
}

/* LE FOCUS SE DESSINE SUR CE QUI SE VOIT, PAS SUR LA CIBLE TRANSPARENTE : un
   anneau tracé autour des 44 points invisibles flotterait à dix points de la
   pastille et donnerait l'impression d'entourer du vide. */
.home-filtres-bouton:focus-visible { outline: none; }

.home-filtres-bouton:focus-visible .home-filtres-bouton__pastille {
    outline: 3px solid var(--focus);
    outline-offset: 2px;
}

/* LE COMPTE DES FILTRES POSÉS, EN PASTILLE. Il ne paraît que s'il y a quelque
   chose à compter — un « 0 » sur un bouton est un bruit — et il reprend
   l'orange de « Tout effacer », qui est déjà la couleur de ce qui est posé. */
.home-filtres-bouton__compte {
    position: absolute;
    top: -5px;
    right: -5px;
    display: inline-grid;
    place-items: center;
    min-width: 18px;
    min-height: 18px;
    padding-inline: 4px;
    border: 1px solid var(--hp-surface-warm, #FFFDF7);
    border-radius: 999px;
    background: var(--hp-orange, #C86138);
    color: #FFFFFF;
    font-size: .62rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

/* --- LA FENÊTRE ---------------------------------------------------------
 *
 * `hidden` FAIT TOUT LE TRAVAIL D'ÉTAT, ET AUCUNE RÈGLE NE LE CONTREDIT ICI.
 * map.css a déjà payé cette leçon en toutes lettres : `[hidden] { display:
 * none }` vit dans la feuille de l'AGENT, et la moindre déclaration d'auteur
 * de `display` la bat. Aucune règle de ce fichier ne déclare donc `display`
 * sur `.home-filtres-modale` : elle est `position: fixed`, ses deux enfants
 * sont placés absolument, et son `display: block` par défaut suffit. Le
 * module se contente de poser et de retirer l'attribut.
 * ------------------------------------------------------------------------ */
.home-filtres-modale {
    position: fixed;
    inset: 0;
    z-index: 210;
}

.home-filtres-modale__voile {
    position: absolute;
    inset: 0;
    background: rgba(11, 24, 18, .46);
}

/* AU POUCE, LA FENÊTRE EST UNE FEUILLE QUI MONTE DU BAS. C'est le motif de
   toute la maison — sélecteur de lieu, feuilles de la barre de filtres — et
   c'est le seul qui mette le contenu sous la main plutôt qu'au milieu de
   l'écran. Elle plafonne à 88 % de la vue : la bande de carte qui reste
   visible au-dessus dit qu'on n'a pas changé de page. */
.home-filtres-modale__boite {
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    max-height: 88dvh;
    border-radius: 20px 20px 0 0;
    background: var(--ui-plan-raised, #FFFDF8);
    color: var(--ui-color-ink, #241D16);
    box-shadow: 0 -18px 44px rgba(22, 41, 28, .28);
}

.home-filtres-modale__form {
    display: grid;
    grid-template-rows: auto minmax(0, 1fr) auto;
    max-height: 88dvh;
}

.home-filtres-modale__entete {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 10px;
    padding: 8px 14px 6px;
}

/* L'ANSE DIT « ÇA SE TIRE ET ÇA SE POUSSE ». Elle est décorative : la fenêtre
   ne se glisse pas au doigt, mais le trait est le signe que tout le monde
   associe à une feuille qui monte du bas. */
.home-filtres-modale__anse {
    grid-column: 1 / -1;
    justify-self: center;
    width: 42px;
    height: 4px;
    border-radius: 999px;
    background: var(--ui-color-sable, #E7DCC6);
}

.home-filtres-modale__titre {
    margin: 0;
    font-family: var(--ui-font-display, Georgia, serif);
    font-size: 1.12rem;
    font-weight: 600;
}

.home-filtres-modale__croix {
    display: inline-grid;
    place-items: center;
    min-width: var(--tap-size, 44px);
    min-height: var(--tap-size, 44px);
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--hp-muted, #6E6252);
    cursor: pointer;
}

.home-filtres-modale__croix:focus-visible,
.home-filtres-modale__voir:focus-visible {
    outline: 3px solid var(--focus);
    outline-offset: 2px;
}

/* C'EST LE CORPS QUI DÉFILE, ET LUI SEUL. Chaque liste de choix porte de
   la barre repliée un `max-height: 46dvh` et son propre défilement — utile dans un
   volet de critère unique, absurde ici : trois zones de défilement empilées
   dans une feuille qui défile déjà. On les rend au fil du corps. */
.home-filtres-modale__corps {
    display: grid;
    gap: 14px;
    padding: 4px 14px 12px;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.home-filtres-modale__choix {
    max-height: none;
    overflow: visible;
}

.home-filtres-modale__critere {
    margin: 0;
    padding: 0;
    border: 0;
}

.home-filtres-modale__question {
    margin: 0 0 4px;
    padding: 0;
    color: var(--hp-green, #245A3B);
    font-size: .82rem;
    font-weight: 700;
    letter-spacing: .01em;
    text-transform: uppercase;
}

/* LE PIED EST COLLÉ AU BAS DE LA FEUILLE, ET C'EST LE PIÈGE DU POUCE.
 * Sur un 390x844 tenu à une main, le haut d'une feuille de 88 % de la vue est
 * hors d'atteinte. Le geste de validation se pose donc là où le pouce retombe,
 * et il ne défile pas avec les choix : on doit pouvoir valider sans remonter.
 * La zone sûre du bas est rendue à l'écran, sinon le bouton passe sous la
 * barre d'accueil de l'iPhone. */
.home-filtres-modale__pied {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 10px 14px calc(12px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--ui-color-sable, #E7DCC6);
    background: var(--ui-plan-raised, #FFFDF8);
}

.home-filtres-modale__voir { flex: 1 1 auto; }

/* LE FOND NE DÉFILE PAS PENDANT QU'ON CHOISIT. Sans ce verrou, un glissement
   qui dépasse la feuille emporte la page derrière elle, et on rouvre les yeux
   ailleurs. `overscroll-behavior: contain` sur le corps arrête la chaîne au
   bord de la liste ; cette règle-ci arrête le document lui-même. */
.home-filtres-verrou {
    overflow: hidden;
}

/* AU-DELÀ DU TÉLÉPHONE, C'EST UNE BOÎTE CENTRÉE. Une feuille pleine largeur
   sur un écran de 1200 points serait un bandeau de trois mètres. */
@media (min-width: 640px) {
    .home-filtres-modale__boite {
        top: 50%;
        right: auto;
        bottom: auto;
        left: 50%;
        width: min(420px, calc(100vw - 48px));
        max-height: 80dvh;
        translate: -50% -50%;
        border-radius: var(--ui-radius-card, 14px);
        box-shadow: 0 24px 60px rgba(22, 41, 28, .30);
    }

    .home-filtres-modale__form { max-height: 80dvh; }

    .home-filtres-modale__anse { display: none; }
}
