/* VELO — l'habillage.
 *
 * Une carte de securite se lit d'un coup d'oeil : la couleur porte le sens
 * (vert on passe, rouge on ne passe pas), le reste doit s'effacer. L'interface
 * est donc une serie de surfaces posees sur la carte, jamais un cadre qui
 * l'enserre. Rien n'est en dur ici : toutes les couleurs sont des variables,
 * et les couleurs de la carte elle-meme ne changent jamais — c'est la
 * signalisation, elle ne se decline pas.
 */
:root {
  /* la carte : intangible */
  --velo-mer:            #cfe3ea;
  --velo-cote:           #7fa3b0;
  --velo-fond:           #f4f1e4;
  --velo-voirie:         #ffffff;
  --velo-filet:          #ddd8c6;
  --velo-propre:         #004f18;
  /* LA BANDE CYCLABLE QUITTE LE VERT — 28/09/2026.

     Gwendoline Brazier, de la CC Nievre et Somme, apres deux echanges :
     « la V30 est un chemin de halage entierement amenage en piste cyclable,
     a aucun moment elle ne longe une departementale ». Elle avait raison, et
     je lui avais repondu le contraire.

     Ce qu'elle voyait en vert tirete etait « partage avec les pietons »
     (#5f9e77, 186 troncons sur la V30) et non « bande cyclable » (12
     troncons). Mesure : entre les deux, l'ecart de couleur valait 11 — sur
     un trait de 2,5 pixels en pointilles, personne ne les distingue. Moi
     compris, en lui repondant.

     LA REGLE ETAIT DEJA ECRITE, deux fois, plus bas : « la couleur dit pas
     de voiture », et « une bande ou les voitures ont le droit de rouler ne
     peut pas porter la couleur de ce qui protege ». Une bande cyclable longe
     le trafic : les voitures n'y entrent pas, mais elles sont a cote. Elle
     n'avait donc rien a faire dans le vert — elle y etait restee parce
     qu'elle date de la palette d'origine, et que la refonte du 14/09 ne l'a
     pas revisitee.

     Ecarts mesures avec ce brun dore : 53 contre le partage, 30 contre le
     chaucidou, 22 contre la departementale. Distincte des trois. */
  --velo-bande:          #8e5613;
  --velo-bande-fort:     #5c360a;
  --velo-interdit:       #d62828;
  --velo-departementale: #e8a33d;

  /* LES DANGERS SIGNALES — 17/09/2026. Les couleurs du panneau routier
     francais : bord rouge, fond blanc, symbole noir. On ne cherche pas
     l'harmonie avec la carte, on cherche a etre reconnu au premier coup
     d'oeil, comme au bord de la route. */
  --velo-danger-bord:    #d62828;
  --velo-danger-fond:    #ffffff;
  --velo-danger-trait:   #1a1a1a;
  /* LE RUBAN DES VELOROUTES BALISEES — 12/09/2026.
     Un violet, parce que c'est la seule famille de teintes que la carte
     n'utilise pas : le vert dit « protege », l'orange « prudence », le rouge
     « interdit », le bleu « votre itineraire ». Le ruban ne dit AUCUN de ces
     quatre-la — il dit « c'est balise » — et il lui fallait donc sa propre
     famille, pas une nuance d'une existante. */
  /* LES CHEMINS DE TERRE, DESSINES DANS L'EDITEUR SEULEMENT — 13/09/2026.
     Une teinte de terre, en pointille fin : ils ne sont pas des voies
     cyclables et ne doivent pas en avoir l'air. */
  --velo-chemin:         #a08a6e;
  --velo-veloroute:      #7a5cc4;
  --velo-veloroute-fort: #4b2e9e;
  /* DEUX FAMILLES NEES DU COURRIER DU COLLECTIF VELO DIOIS — 14/09/2026.

     VOIE PARTAGEE. La donnee dit `segregated=no` : on roule la, mais au milieu
     des pietons et sans separation. Ce n'est pas une piste, et ce n'est pas
     rien non plus — on y est protege des voitures. D'ou un vert de la meme
     famille que « protege », mais desature et en tirets : la couleur dit
     « pas de voiture », le trait dit « pas pour vous tout seul ».

     SENTIER INTERDIT. Un `bicycle=no` sur un sentier de randonnee ne dit pas
     la meme chose que sur une route. Autour de Die, les 184 traits rouges
     etaient a 100 % des sentiers et des chemins forestiers : le seul signal
     que cette carte a promis de donner — « n'engagez pas votre velo sur cette
     route » — y etait introuvable. Une terre rougie, en pointille fin, pour
     qu'ils existent sans crier. */
  --velo-partage:        #3c9154;
  --velo-partage-fort:   #1f5c33;
  /* LE CHAUCIDOU — 15/09/2026, sur signalement de Lucile a Die.
     Une bande CONSEILLEE, ou les voitures ont le droit de rouler : ce n'est
     plus du vert, puisque ce n'est plus « protege », et ce n'est pas encore
     l'orange du grand axe. Un olive, entre les deux, exactement comme la
     chose elle-meme. */
  --velo-chaucidou:      #b2a852;
  --velo-chaucidou-fort: #736b26;
  --velo-sentier:        #b5766b;
  --velo-sentier-fort:   #8c4a3e;
  /* LE CHEMIN OUVERT AU VELO — 29/09/2026.

     Un gris, et c'est la seule teinte honnete. Toutes les autres affirment
     quelque chose : vert on protege, brun on a peint, olive les voitures
     entrent, violet c'est balise. Sur un chemin ouvert au velo, on ne sait
     que ceci : on a le DROIT d'y rouler. Le revetement, personne ne l'a
     declare. Le gris ne promet rien, et c'est exactement le message.

     Le creneau de clarte etait le seul libre : 25,3 entre la piste (28,5) et
     rien en dessous. Un brun a 19 aurait ete range par l'oeil avec les bandes
     (41,9) malgre les 23 points d'ecart — la teinte prime sur la clarte quand
     elle est partagee. Mesure sur le rendu, pas estimee. */
  --velo-ouverte:        #3c3c3c;
  --velo-ouverte-fort:   #1a1a1a;
  /* Les boucles locales flechees ne sont pas des veloroutes. Meme violet
     puisque c'est bien du balisage, mais pali et aminci : la hierarchie du
     reseau se lit a l'oeil au lieu d'etre gommee. */
  --velo-boucle:         #a794d8;
  --velo-boucle-fort:    #6d52b0;
  /* HAUTE LISIBILITE : les memes couleurs, poussees jusqu'au contraste maximal
     sur fond clair. Le vert passe de 4,6:1 a 7,4:1, le rouge de 4,5:1 a 8,1:1 —
     au-dela du seuil AAA, pour que le trait reste vu meme sur un ecran au
     soleil ou par un oeil qui fatigue. */
  --velo-propre-fort:    #00330f;
  --velo-interdit-fort:  #9e0f0f;
  --velo-departementale-fort: #8a5200;
  --velo-service:        #2f827f;   /* les commerces et bornes : couleur de la maison */
  --velo-service-clair:  #5a99ad;   /* le libre-service : l'ardoise du logo TE */
  /* LA FLECHE NE PEUT PAS ETRE BLEUE — 09/09/2026.
     La fleche bleue se confondait avec les pointilles du guidage : la position
     et le guidage partageaient
     la meme encre, donc le marqueur se lisait comme un morceau du trace.
     SUR CETTE CARTE CHAQUE TEINTE FORTE PORTE DEJA UN SENS : vert = piste,
     rouge = interdit, orange = departementale et trace des calques, sarcelle =
     services, bleu = guidage. Le magenta est la seule teinte forte a laquelle
     rien n'est attache : elle ne peut donc pas etre lue comme une categorie.
     Le contraste sur le fond creme est de 4,5:1 ; contre le vert des pistes il
     tombe a 1,0:1 — meme luminosite. C'est le lisere blanc de 3,5 px et
     l'ombre portee qui font la separation, pas la couleur. */
  --velo-position:       #d6006e;
  --velo-guidage:        #1f5f8b;
  --velo-encre:          #14140f;
  --velo-doux:           #3a3a30;

  /* l'habillage : adaptable */
  --surface:        #ffffff;
  --surface-2:      #f6f5f0;
  --surface-voile:  rgba(16, 18, 16, .55);
  --texte:          #16180f;
  --texte-doux:     #5b6055;
  --bord:           #e3e2d8;
  --bord-fort:      #cfcec2;
  --accent:         #1b7f4b;
  --accent-clair:   #e7f3ec;
  --accent-texte:   #ffffff;
  /* LA MAISON TOUSENSEMBLES : le disque du logo, releve sur l'original —
     turquoise en haut a gauche, ardoise en bas, horizon montant vers la
     droite. Ces couleurs-la ne se declinent pas selon le theme : c'est une
     marque, pas une decoration. */
  --te:             #2f827f;
  --te-ciel-1:      #8fe6d3;
  --te-ciel-2:      #7fd3c8;
  --te-ciel-3:      #c8d5dc;
  --te-terre-1:     #5a99ad;
  --te-terre-2:     #93aec0;
  --ombre-1:        0 1px 2px rgba(16, 18, 16, .08), 0 2px 8px rgba(16, 18, 16, .06);
  --ombre-2:        0 2px 6px rgba(16, 18, 16, .10), 0 12px 32px rgba(16, 18, 16, .16);
  --rayon:          14px;
  --rayon-s:        10px;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
          "Helvetica Neue", Arial, sans-serif;
}

/* L'habillage suit le reglage du systeme ; la carte, elle, ne bouge pas : une
   piste verte doit rester verte a minuit comme a midi. */
@media (prefers-color-scheme: dark) {
  :root {
    --surface:       #1b1e1a;
    --surface-2:     #23271f;
    --surface-voile: rgba(8, 10, 8, .66);
    --texte:         #f2f3ec;
    --texte-doux:    #b3b8ab;
    --bord:          #333828;
    --bord-fort:     #464c3a;
    --accent:        #2f9d61;
    --accent-clair:  #14301f;
    --ombre-1:       0 1px 2px rgba(0, 0, 0, .4), 0 2px 10px rgba(0, 0, 0, .35);
    --ombre-2:       0 2px 8px rgba(0, 0, 0, .45), 0 16px 40px rgba(0, 0, 0, .5);
  }
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }
/* Seule la page de carte se fige : les pages de texte doivent defiler. */
body.plein { overflow: hidden; }
body {
  font-family: var(--sans);
  color: var(--texte);
  background: var(--surface);
  display: flex;
  flex-direction: column;
  -webkit-text-size-adjust: 100%;
}
:where(button, input, a):focus-visible {
  outline: 3px solid var(--velo-guidage);
  outline-offset: 2px;
}

/* ------------------------------------------------------------- la barre -- */
.barre {
  flex: none;
  display: flex;
  align-items: center;
  gap: .9rem;
  padding: .55rem .9rem;
  padding-top: max(.55rem, env(safe-area-inset-top));
  background: var(--surface);
  border-bottom: 1px solid var(--bord);
  position: relative;
  z-index: 30;
}
.marque { margin: 0; display: flex; align-items: center; gap: .55rem;
          font-size: 1rem; font-weight: 400; }
.marque-signe { width: 2.6rem; height: 2.6rem; flex: none; display: block; }
.marque-texte { display: flex; flex-direction: column; line-height: 1.15; }
.marque-mot { font-size: 1.06rem; font-weight: 800; letter-spacing: .13em; }
/* Le lien vers TousEnsembles est la promotion du service : il est ecrit, pas
   cache dans un dessin. Discret, mais toujours present. */
.marque-sous { font-size: .66rem; color: var(--texte-doux); text-decoration: none; }
.marque-sous:hover { color: var(--texte); text-decoration: underline; }
.accroche {
  margin: 0;
  font-size: .84rem;
  color: var(--texte-doux);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.barre-actions { margin-left: auto; display: flex; gap: .45rem; flex: none;
                 align-items: center; }

/* ------------------------------------------------------------- le menu -- */
.menu-boite { position: relative; }
.bouton-menu { display: flex; align-items: center; gap: .45rem; padding-left: .7rem; }
.bouton-menu svg { width: 20px; height: 20px; fill: none; stroke: currentColor;
                   stroke-linecap: round; }
.menu { position: absolute; right: 0; top: calc(100% + .5rem); z-index: 40;
        min-width: 15rem; padding: .4rem;
        background: var(--surface); border-radius: var(--rayon);
        box-shadow: var(--ombre-2); display: flex; flex-direction: column; }
.menu[hidden] { display: none; }
.menu a { padding: .7rem .8rem; border-radius: var(--rayon-s);
          font-size: .92rem; color: var(--texte); text-decoration: none; }
.menu a:hover, .menu a:focus { background: var(--accent-clair); }
@media (max-width: 480px) { .bouton-menu span { display: none; } }

/* LE BOUTON MENU ETAIT HORS ECRAN SUR TOUS LES TELEPHONES — 08/09/2026.
 *
 * Sur telephone, il fallait faire defiler l'ecran pour voir le bouton de menu.
 * Mesure sur la page publiee :
 *
 *     320 px  document 411 px   Menu de 360 a 411   hors ecran
 *     360 px  document 411 px   Menu de 360 a 411   hors ecran
 *     390 px  document 411 px   Menu de 360 a 411   hors ecran
 *     430 px  document 430 px   Menu visible
 *
 * La barre ne tenait qu'a partir de 430 px, c'est-a-dire sur les plus grands
 * iPhone. Sur tout le reste, le menu — donc l'aide, la reglementation, les
 * affichettes, tout — n'etait atteignable qu'en faisant defiler la page
 * horizontalement. Personne ne pense a faire ca.
 *
 * ON CONTINUE LA STRATEGIE DEJA EN PLACE : la marque se depouille a mesure que
 * l'ecran retrecit. « un service TousEnsembles » disparait a 780 px, le mot
 * « Menu » a 480 ; le mot « VELO » disparait ici, et la goutte reste — c'est
 * elle la marque, et le nom du site est de toute facon dans l'onglet et sous
 * l'icone de l'application.
 */
@media (max-width: 430px) {
  .marque-mot { display: none; }
  .barre { gap: .4rem; padding-left: .5rem; padding-right: .5rem; }
  /* Sans ces deux lignes, la barre depasse encore de quatre pixels a 360 px —
     la largeur Android la plus repandue — et repasse a la ligne. Quatre
     pixels coutaient cinquante pixels de carte. */
  .bouton { padding-left: .7rem; padding-right: .7rem; }
  .barre-actions { gap: .35rem; }
}

/* Le filet de securite : sous 320 px, ou avec une police agrandie par
   l'utilisateur, la barre passe a la ligne plutot que de rejeter un bouton
   hors de l'ecran. Une barre plus haute se voit ; un bouton invisible, non. */
.barre { flex-wrap: wrap; }

.bouton {
  font: 600 .85rem/1 var(--sans);
  padding: .62rem .9rem;
  border-radius: 999px;
  border: 1px solid var(--bord-fort);
  background: var(--surface);
  color: var(--texte);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, transform .1s ease;
}
.bouton:hover { background: var(--surface-2); }
.bouton:active { transform: translateY(1px); }
.bouton[aria-expanded="true"] { background: var(--accent-clair); border-color: var(--accent); }
.bouton-plein {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-texte);
}
.bouton-plein:hover { filter: brightness(1.06); background: var(--accent); }

/* -------------------------------------------------------------- la carte -- */
main { position: relative; flex: 1; min-height: 0; }
/* Positionnement absolu et non height:100% : sur un enfant de conteneur
   flexible, le pourcentage ne se resout pas toujours et rend zero. */
#carte {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: block;
  touch-action: none;
  cursor: grab;
  background: var(--velo-fond);
}
#carte:active { cursor: grabbing; }

/* L'ITINERAIRE, VISIBLE — 17/09/2026. En haut au centre de la carte : la barre
   est a sa largeur limite sur telephone (mesure du 08/09), le bas appartient
   aux feuilles de guidage, le coin gauche au panneau des calques. Le bouton
   s'efface pendant qu'un trajet est prepare ou suivi. */
.bouton-itineraire {
  position: absolute; top: .8rem; left: 50%; z-index: 13;
  transform: translateX(-50%);
  display: flex; align-items: center; gap: .45rem;
  box-shadow: var(--ombre-2);
}
.bouton-itineraire:active { transform: translateX(-50%) translateY(1px); }
.bouton-itineraire[hidden] { display: none; }
.bouton-itineraire svg { width: 18px; height: 18px; fill: currentColor;
                         stroke: currentColor; stroke-linecap: round; }

/* ------------------------------------------------------------ les outils -- */
.outils {
  position: absolute;
  right: .8rem;
  top: .8rem;
  display: flex;
  flex-direction: column;
  gap: .55rem;
  z-index: 12;
}
.rond-groupe {
  display: flex;
  flex-direction: column;
  border-radius: var(--rayon);
  overflow: hidden;
  box-shadow: var(--ombre-1);
}
.rond-groupe .rond { border-radius: 0; box-shadow: none; }
.rond-groupe .rond + .rond { border-top: 1px solid var(--bord); }
.rond {
  width: 2.9rem; height: 2.9rem;
  display: grid; place-items: center;
  border: 0;
  border-radius: var(--rayon);
  background: var(--surface);
  color: var(--texte);
  box-shadow: var(--ombre-1);
  cursor: pointer;
  transition: background .15s ease;
}
/* L'AIDE est un LIEN, pas un bouton : elle change de page. Elle prend
   l'apparence des ronds voisins, sans leur soulignement de lien ni la couleur
   d'accent — dans cette colonne, un « ? » se lit tout seul. */
.rond-aide { text-decoration: none; font-weight: 700; font-size: 1.35rem;
  line-height: 1; color: var(--texte); }
.rond-aide:hover { color: var(--accent); }

.rond:hover { background: var(--surface-2); }
.rond svg { width: 21px; height: 21px; fill: currentColor; stroke: currentColor; }
.rond[aria-pressed="true"] { background: var(--velo-position); color: #fff; }

/* ----------------------------------------------------------- les calques -- */
/* UN PANNEAU NE DEBORDE PAS DE LA CARTE — 15/09/2026.

   Emmanuel, sur telephone : « le menu calque est trop long a present et on ne
   peut pas le faire defiler ». Mesure sur iPhone 13 : le panneau commence a
   70 px du haut, mesure 751 px, et se termine donc 157 px SOUS le bas de
   l'ecran. Sa derniere ligne — « Noms de lieux » — etait injoignable.

   Ce n'est pas une regression d'affichage, c'est une limite qu'on a fini par
   franchir : les couches se sont ajoutees une a une (veloroutes balisees,
   boucles locales, voies partagees, chaucidou), et la liste a depasse l'ecran
   sans que rien ne soit prevu pour ca. Il n'y avait ni `max-height` ni
   `overflow`, donc le trop-plein etait simplement coupe.

   LA BORNE EST LE PARENT, PAS L'ECRAN. `<main>` porte la carte, il est en
   position relative et de hauteur definie : s'y limiter garde le panneau au-
   dessus de la barre du bas sur telephone, sans avoir a connaitre la hauteur
   de l'en-tete ni celle de cette barre. C'est la meme forme que le
   `max-width` juste au-dessus, qui borne deja la largeur sur ce parent.

   `overscroll-behavior: contain` : arrive en bas de la liste, le geste ne doit
   pas se propager a la carte — sinon on deplace la France en voulant lire la
   derniere couche. */
.panneau {
  position: absolute;
  left: .8rem; top: .8rem;
  width: 17.5rem; max-width: calc(100% - 1.6rem);
  max-height: calc(100% - 1.6rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  z-index: 14;
  background: var(--surface);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-2);
  padding: .85rem .9rem .8rem;
}
.panneau[hidden] { display: none; }
.panneau-titre {
  margin: 0 0 .5rem;
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .13em;
  color: var(--texte-doux);
}
.calques { list-style: none; margin: 0; padding: 0; }
.calque {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .42rem .3rem;
  border-radius: var(--rayon-s);
  cursor: pointer;
  font-size: .88rem;
}
.calque:hover { background: var(--surface-2); }
.calque-nom { flex: 1; line-height: 1.25; }
.calque-nom small { display: block; font-size: .72rem; color: var(--texte-doux); }
.calque input { position: absolute; opacity: 0; width: 0; height: 0; }

/* L'interrupteur est dessine, mais c'est bien une case a cocher native qui
   porte l'etat : le clavier et les lecteurs d'ecran voient une case. */
.bascule {
  flex: none;
  width: 2.3rem; height: 1.3rem;
  border-radius: 999px;
  background: var(--bord-fort);
  position: relative;
  transition: background .18s ease;
}
.bascule::after {
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: calc(1.3rem - 4px); height: calc(1.3rem - 4px);
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .3);
  transition: transform .18s ease;
}
.calque input:checked ~ .bascule { background: var(--accent); }
.calque input:checked ~ .bascule::after { transform: translateX(1rem); }
.calque input:focus-visible ~ .bascule { outline: 3px solid var(--velo-guidage); outline-offset: 2px; }

.cle { flex: none; width: 26px; height: 0; border-top: 3px solid var(--bord-fort); }
.cle-cyc   { border-top-color: var(--velo-propre); }
.cle-int   { border-top: 4px dashed var(--velo-interdit); }
.cle-dep   { border-top: 4px solid var(--velo-departementale); }
/* Le ruban est epais et pale sur la carte : la cle le montre tel quel. */
.cle-route { border-top: 7px solid var(--velo-veloroute); opacity: .55; }
.cle-boucle { border-top: 4px solid var(--velo-boucle); }
.cle-bande { border-top: 4px dashed var(--velo-bande); }
/* Des POINTS, comme sur la carte depuis le 28/09/2026 : la pastille
   annoncait des tirets, donc elle mentait sur ce qu'on allait voir. */
.cle-part  { border-top: 4px dotted var(--velo-partage); }
.cle-chauc { border-top: 4px dashed var(--velo-chaucidou); }
/* Le CSS ne sait pas faire un tireté-pointillé : la clé le suggère par un
   tiret plus serré que celui de la bande. Le vrai motif est sur la carte. */
.cle-ouv   { border-top: 4px dashed var(--velo-ouverte); }
.cle-sent  { border-top: 3px dotted var(--velo-sentier); }
.cle-chemin { border-top: 3px dotted var(--velo-chemin); }
.cle-rue   { border-top: 4px solid var(--velo-filet); }
.cle-guide { border-top: 4px dashed var(--velo-guidage); }
.cle-ign   { border-top: 4px solid var(--velo-cote); }
.cle-nom   { border-top: 3px dotted var(--velo-encre); }
.cle-service { width: 13px; height: 13px; background: var(--velo-service);
               border: 0; border-radius: 50% 50% 50% 0; transform: rotate(-45deg);
               margin-left: 7px; }

/* La cle des dangers est le panneau lui-meme, en miniature : un triangle a
   bord rouge. Pas de fioriture, c'est la forme qui fait reconnaitre. */
/* LA CLE DES DANGERS EST LE PANNEAU LUI-MEME — 18/09/2026. Emmanuel : « dans le
   menu calque l'icone dangers signales est petite et pas claire ni lisible ».
   C'etait un triangle dessine en CSS, de 12 px et sans symbole : il ne disait
   rien. On met le fichier du panneau, celui qu'on voit sur la carte. */
.cle-danger { width: 22px; height: 22px; background: url('velo-danger-autre.svg') center/contain no-repeat;
              border: 0; margin-left: 2px; }

.panneau-note {
  display: flex;
  align-items: flex-start;
  gap: .55rem;
  margin: .6rem 0 0;
  padding-top: .65rem;
  border-top: 1px solid var(--bord);
  font-size: .76rem;
  line-height: 1.45;
  color: var(--texte-doux);
}
.panneau-note .cle { margin-top: .55em; }

/* ------------------------------------------------------------- le guidage -- */
.feuille {
  position: absolute;
  left: .8rem; right: .8rem;
  bottom: .8rem;
  bottom: max(.8rem, env(safe-area-inset-bottom));
  /* Au-dessus du bandeau d'installation tant qu'il est affiche (pwa.js publie
     sa hauteur ; zero sinon). */
  bottom: calc(max(.8rem, env(safe-area-inset-bottom)) + var(--velo-install-h, 0px));
  z-index: 16;
  margin-inline: auto;
  max-width: 34rem;
  padding: .85rem 1rem;
  border-radius: var(--rayon);
  background: var(--velo-encre);
  color: #fff;
  box-shadow: var(--ombre-2);
  border-left: 5px solid var(--velo-guidage);
  font-size: 1rem;
  line-height: 1.35;
  animation: monte .18s ease-out;
}
@keyframes monte { from { transform: translateY(8px); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .feuille { animation: none; } }
.feuille[hidden] { display: none; }
.feuille b { display: block; font-size: 1.02rem; }
.feuille span { display: block; margin-top: .15rem; font-size: .85rem; opacity: .85; }
.feuille i { font-style: normal; font-weight: 700; }
.feuille i.ok { color: #7fe0a8; }
.feuille i.ko { color: #ffb4a8; }
.feuille.sur-piste { border-left-color: var(--velo-propre); }
/* Aucun itineraire : on le DIT. Une direction fausse est pire qu'une absence
   de direction — c'est ce qui a envoye un cycliste sur un chemin interdit. */
.feuille.sans-route { border-left-color: var(--velo-interdit); }

/* La fiche d'un point se pose AU-DESSUS du guidage : elle repond a un geste —
   on vient de cliquer dessus — donc elle passe devant.

   ELLE NE LE FAISAIT PAS, corrige le 25/08/2026. Les deux cartes avaient le
   meme z-index, et #proche est declare APRES #service : a egalite, le dernier
   du document gagne. Tant que le guidage tenait en deux lignes, il restait
   sous les 6.2rem et personne ne voyait rien. L'ajout de la ligne des virages,
   le meme jour, l'a fait grandir juste assez pour recouvrir le BAS de la fiche
   — donc sa derniere ligne, celle qui porte « y aller ». Sans elle, la feuille
   annonce le point sans offrir d'y aller : un bouton invisible n'existe pas.

   Deux verrous plutot qu'un : le z-index rend l'ordre explicite au lieu de le
   laisser dependre de l'ordre des balises, et la marge du bas laisse la place
   d'un guidage a trois lignes pour qu'ils ne se touchent meme pas. */
.feuille-service { bottom: calc(7.8rem + var(--velo-install-h, 0px)); z-index: 17; border-left-color: var(--velo-service); }
.feuille.vers-point { border-left-color: var(--velo-service); }
.feuille .liens button { font: inherit; color: #fff; background: none; border: 0;
                         padding: 0; text-decoration: underline; cursor: pointer; }
#aller-service { font-weight: 700 !important; }
.feuille .adresse { display: block; margin-top: .3rem; font-size: .88rem; opacity: .95; }
.feuille .liens { margin-top: .5rem; font-size: .86rem; opacity: 1; }

/* L'INSTRUCTION DE VIRAGE — la seule ligne qu'on lit d'un coup d'oeil en
   roulant. Elle passe devant le reste : pleine opacite, un cran plus grande
   que les lignes de detail, et detachee de ce qui la suit. */
.feuille .manoeuvre { font-size: .98rem; font-weight: 600; opacity: 1;
  margin-top: .35rem; }

/* La signature TousEnsembles au bas de l'ecran d'accueil : presente, lisible,
   jamais criarde. Elle se detache du reste par un filet, pas par du bruit. */
.signature { margin: 1.1rem 0 0; padding-top: .9rem; border-top: 1px solid var(--bord);
  font-size: .82rem; line-height: 1.5; color: var(--texte-doux); }
.signature b { color: var(--texte); }
.signature a { color: var(--accent); font-weight: 600; white-space: nowrap; }
.feuille .liens a { color: #9fd8ff; }
.feuille .liens button { font: inherit; color: #fff; background: none; border: 0;
                         padding: 0; text-decoration: underline; cursor: pointer; }

/* -------------------------------------------------------------- l'entree -- */
/* L'ATTRIBUT hidden DOIT GAGNER : une regle d'auteur display:grid ecrase le
   display:none du navigateur, et ce panneau est deja reste au-dessus de la
   carte, opaque, pendant des heures. */
.voile {
  position: absolute; inset: 0;
  z-index: 24;
  display: grid;
  place-items: center;
  padding: 1rem;
  overflow: auto;
  background: var(--surface-voile);
  backdrop-filter: blur(2px);
}
.voile[hidden] { display: none; }
.feuille-entree {
  width: min(29rem, 100%);
  background: var(--surface);
  border-radius: var(--rayon);
  box-shadow: var(--ombre-2);
  padding: 1.35rem 1.35rem 1.2rem;
}
/* L'ENSEIGNE DE LA PAGE D'ACCUEIL. Dans la barre du haut, la marque fait deux
   centimetres et se remarque a peine ; c'est ici, sur l'ecran d'accueil, qu'on
   a la place de la montrer — et c'est le seul moment ou l'on regarde autre
   chose que la carte. */
.enseigne { text-align: center; margin: 0 0 1.1rem; }
.enseigne-signe { width: 5.4rem; height: 5.4rem; display: block; margin: 0 auto .5rem; }
.enseigne-mot { margin: 0; font-size: 1.55rem; font-weight: 800; letter-spacing: .16em; }
.enseigne-sous { margin: .15rem 0 0; font-size: .78rem; }
.enseigne-sous a { color: var(--texte-doux); text-decoration: none; }
.enseigne-sous a:hover { color: var(--texte); text-decoration: underline; }

.feuille-entree h2 { margin: 0 0 .35rem; font-size: 1.4rem; letter-spacing: -.01em; }
.chapo { margin: 0 0 1.1rem; font-size: .9rem; line-height: 1.5; color: var(--texte-doux); }
.feuille-entree h2, .feuille-entree .chapo { text-align: center; }
.feuille-entree label { display: block; font-size: .8rem; font-weight: 600; margin-bottom: .35rem; }

.primaire {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  width: 100%;
  font: 600 1rem/1 var(--sans);
  padding: .95rem 1rem;
  border: 0;
  border-radius: var(--rayon-s);
  background: var(--accent);
  color: var(--accent-texte);
  cursor: pointer;
  transition: filter .15s ease, transform .1s ease;
}
.primaire:hover { filter: brightness(1.06); }
.primaire:active { transform: translateY(1px); }
.primaire[disabled] { opacity: .6; cursor: default; }
.primaire svg { width: 19px; height: 19px; fill: currentColor; stroke: currentColor; }

.ou {
  display: flex; align-items: center; gap: .75rem;
  margin: 1rem 0;
  font-size: .72rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--texte-doux);
}
.ou::before, .ou::after { content: ""; flex: 1; border-top: 1px solid var(--bord); }

.ligne { display: flex; gap: .45rem; }
.ligne input {
  flex: 1; min-width: 0;
  font: 400 1rem/1 var(--sans);
  padding: .8rem .85rem;
  border: 1px solid var(--bord-fort);
  border-radius: var(--rayon-s);
  background: var(--surface-2);
  color: var(--texte);
}
.ligne input::placeholder { color: var(--texte-doux); }
.ligne input:focus { border-color: var(--accent); background: var(--surface); }
.ligne .bouton-plein { padding-inline: 1.15rem; border-radius: var(--rayon-s); }

#resultats { list-style: none; margin: .55rem 0 0; padding: 0; max-height: 13rem; overflow: auto; }
#resultats:empty { margin: 0; }
#resultats button {
  display: flex; align-items: baseline; gap: .5rem;
  width: 100%; text-align: left;
  font: 400 .95rem/1.3 var(--sans);
  padding: .6rem .65rem;
  border: 0;
  border-radius: var(--rayon-s);
  background: transparent;
  color: var(--texte);
  cursor: pointer;
}
#resultats button:hover, #resultats button:focus { background: var(--accent-clair); }
#resultats b { font-weight: 600; }
#resultats small { color: var(--texte-doux); }

.msg {
  margin: .9rem 0 0;
  padding: .8rem .9rem;
  border-radius: var(--rayon-s);
  border-left: 4px solid var(--velo-interdit);
  background: var(--accent-clair);
  font-size: .88rem;
  line-height: 1.5;
}
.msg[hidden] { display: none; }
.msg ol { margin: .45rem 0 0; padding-left: 1.15rem; }
.msg li + li { margin-top: .25rem; }
.note { margin: 1rem 0 0; font-size: .78rem; line-height: 1.5; color: var(--texte-doux); }

/* --------------------------------------------------------------- le pied -- */
footer {
  flex: none;
  padding: .5rem .9rem;
  padding-bottom: max(.5rem, env(safe-area-inset-bottom));
  font-size: .7rem;
  line-height: 1.5;
  color: var(--texte-doux);
  background: var(--surface);
  border-top: 1px solid var(--bord);
}
footer a { color: var(--texte-doux); }

@media (max-width: 780px) {
  .accroche { display: none; }
  /* Sous 780 px la ligne « un service TousEnsembles » passait a la ligne et
     epaississait la barre. Elle n'est pas perdue : l'ecran d'accueil la porte
     en grand, juste sous la marque. */
  .marque-sous { display: none; }
  .marque-mot { font-size: 1.05rem; }
  .detail { display: none; }
  .panneau { left: .6rem; right: .6rem; width: auto; top: .6rem; }
  .outils { right: .6rem; top: .6rem; }
  .feuille { left: .6rem; right: .6rem; }
  footer { font-size: .64rem; }
  .barre { gap: .5rem; }
}

/* Mode vitrine : la carte occupe tout, le reste disparait. */
body.vitrine .barre,
body.vitrine footer,
body.vitrine .outils,
body.vitrine .panneau,
body.vitrine .feuille { display: none; }

/* ------------------------------------------ le bandeau d'installation --
 *
 * En bas de l'ecran, comme sur TE.
 *
 * Il flotte au-dessus de la carte plutot que de pousser la mise en page : la
 * carte occupe exactement la hauteur de la fenetre, et lui ajouter une barre
 * la rognerait. Il se ferme, et ne revient plus.
 */
/* « display: flex » ecrase la regle « [hidden] { display: none } » du
   navigateur : sans cette ligne, le bandeau reste visible meme apres qu'on
   l'a ferme, et s'affiche a qui l'avait refuse la veille. */
.velo-install[hidden] { display: none; }

.velo-install {
  position: fixed;
  left: .6rem; right: .6rem;
  bottom: .6rem;
  bottom: max(.6rem, env(safe-area-inset-bottom));
  z-index: 60;
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-wrap: wrap;
  padding: .7rem .8rem;
  border-radius: var(--rayon);
  border: 1px solid var(--bord-fort);
  background: var(--surface);
  box-shadow: var(--ombre-2);
  font: 500 .85rem/1.35 var(--sans);
  color: var(--texte);
}
.velo-install__mot { flex: 1 1 12rem; min-width: 0; }
.velo-install__btn,
.velo-install__aide {
  font: 600 .82rem/1 var(--sans);
  padding: .55rem .85rem;
  border-radius: 999px;
  border: 1px solid var(--bord-fort);
  background: var(--surface);
  color: var(--texte);
  cursor: pointer;
  flex: none;
}
.velo-install__btn {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-texte);
}
.velo-install__btn:hover,
.velo-install__aide:hover { filter: brightness(1.06); }
.velo-install__btn:focus-visible,
.velo-install__aide:focus-visible,
.velo-install__fermer:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; }
/* La croix n'est pas un pictogramme decoratif : c'est le seul moyen de refuser
   definitivement. Elle porte donc un aria-label dans le HTML, et une cible
   assez grande pour un pouce. */
.velo-install__fermer {
  flex: none;
  width: 2rem; height: 2rem;
  line-height: 1;
  font-size: 1.25rem;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--texte-doux);
  cursor: pointer;
}
.velo-install__fermer:hover { background: var(--surface-2); color: var(--texte); }

/* Sur les ecrans etroits, le mot passe seul sur sa ligne et les boutons se
   rangent dessous, alignes a droite. */
@media (max-width: 430px) {
  .velo-install { gap: .45rem; padding: .6rem .65rem; }
  .velo-install__mot { flex-basis: 100%; }
  .velo-install__aide, .velo-install__btn { margin-left: auto; }
}

/* ══════════════════════════════════════════════════════════════════════
   LES QUATRE FAMILLES S'ETALENT SUR LA CLARTE — 28/09/2026

   Isabelle Breton, de l'association « Chaumont a pied, a velo » :
   « j'ai du mal a voir la difference de couleur entre les voies partagees
   voitures et pietons, c'est dommage ».

   ELLE A RAISON, ET J'AVAIS MESURE AVEC LE MAUVAIS INSTRUMENT. La veille,
   j'avais separe « bande » de « partage » en comparant des delta-E — qui
   pesent surtout la TEINTE. Sur un trait de 2,5 px en pointilles, ce que
   l'oeil lit c'est la CLARTE. Les quatre familles tenaient dans 17 points :

     protege 46,9 · bande 54,2 · partage 60,1 · chaucidou 64,5

   Partage et chaucidou — « pietons » et « voitures », la distinction la
   plus importante de cette carte — n'etaient separes que de 4,4 points.
   Invisible, exactement comme elle le dit.

   Elles s'etalent maintenant de 28 a 68, teintes conservees : le vert dit
   « pas de voiture », l'ambre et l'olive disent « voiture ».

     protege 28,5 · bande 41,9 · partage 53,9 · chaucidou 68,1

   Partage / chaucidou : 14,2 points d'ecart au lieu de 4,4. Et chaque
   trait garde au moins 26 points d'ecart avec le fond beige.
   ══════════════════════════════════════════════════════════════════════ */
