
@font-face{font-family:"Newsreader";src:url(/fonts/newsreader-400.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Newsreader";src:url(/fonts/newsreader-600.woff2) format("woff2");font-weight:600;font-style:normal;font-display:swap}
@font-face{font-family:"Public Sans";src:url(/fonts/public-sans-400.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"Public Sans";src:url(/fonts/public-sans-600.woff2) format("woff2");font-weight:600;font-style:normal;font-display:swap}

:root{
  /* La page est plus sombre que la feuille : le contenu se lit comme un
     document posé dessus, ce qui donne au site sa tenue éditoriale.
     Le blanc et le gris sont refroidis, l'accent passé du sarcelle au bleu
     profond : le sujet est l'eau, et la teinte le dit avant le titre. La
     saturation reste sous 0,02 sur les fonds — un papier franchement bleu
     aurait fait basculer la page du côté du site institutionnel. Les trois
     couleurs d'état, elles, ne bougent pas : elles ont été calibrées sous
     simulation de dichromatie et restent valides sur ce fond légèrement
     plus clair. */
  --fond:#e3e8ec;
  --papier:#f8fafc;
  --papier-2:#eef3f7;
  --papier-3:#dfe8ee;
  --encre:#111619;
  --encre-2:#444d55;
  --encre-3:#5b656e;
  --filet:#dde5ec;
  --filet-fort:#d1dce5;
  --accent:#0d4f7c;
  --accent-clair:#dbe7f2;
  /* Les trois états, choisis par mesure et non à l'œil. Sous simulation de
     dichromatie (Viénot-Brettel-Mollon), l'ancien triplet mettait « proche du
     seuil » et « au-dessus du seuil » à ΔE 0,9 en tritanopie — la même
     couleur — et « conforme » à 14,7 de « au-dessus » en deutéranopie.
     Celui-ci tient ΔE ≥ 26 sur les six paires × quatre visions, en gardant
     4,5:1 de contraste sur --papier ET --papier-2. */
  --ok:#31754c;
  --alerte:#9d5f09;
  --grave:#6d030c;
  --focus:#0d4f7c;
  --serif:"Newsreader",'Iowan Old Style',Palatino,Georgia,serif;
  --sans:"Public Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
  /* Le monospace porte tout l'appareil de lecture — surtitres, fil d'Ariane,
     unités, graduations, dates. Il sépare d'un coup d'œil ce qui est mesure
     de ce qui est prose, et ne coûte aucun fichier de police. */
  --mono:ui-monospace,Menlo,Consolas,"Liberation Mono",monospace;
  /* Trame de fond commune à tous les graphiques : elle les rattache les uns
     aux autres et signale « ici, c'est de la donnée ». */
  --trame:rgba(13,79,124,.10);
  /* Rampe ordonnée à cinq crans, partagée par la répartition, la carte et la
     matrice. Les deux derniers crans réclament une encre claire. */
  --ramp-1:#d5e3ef;
  --ramp-2:#a3c3dd;
  --ramp-3:#6d9dc4;
  --ramp-4:#3a739f;
  --ramp-5:#0d4f7c;
  --gouttiere:clamp(1.15rem, 0.7rem + 2vw, 2.3rem);
  --largeur:74rem;
}

/* Thème clair uniquement, et c'est un choix assumé, pas un oubli.
   La direction a été dessinée en clair : le contraste de la feuille sur la
   page, la rampe ordonnée à cinq crans et les trois couleurs d'état sont
   calibrés dessus. Un mode sombre re-dérivé à la main donnait une palette
   que personne n'avait validée. color-scheme empêche au passage le
   navigateur d'assombrir de lui-même les champs de formulaire. */
:root{color-scheme:light}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--fond);
  color:var(--encre-2);
  font-family:var(--sans);
  font-size:1.0625rem;
  line-height:1.55;
  font-variant-numeric:tabular-nums;
  text-rendering:optimizeLegibility;
}
::selection{background:var(--accent-clair)}
img,svg{max-width:100%;height:auto}
a{color:inherit;text-decoration:underline;text-decoration-color:var(--filet-fort);text-underline-offset:.18em;text-decoration-thickness:1px}
a:hover{text-decoration-color:var(--accent);color:var(--accent)}
a:focus-visible,button:focus-visible,input:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:2px}

/* ── charpente ─────────────────────────────────────────────── */
/* L'en-tête et le corps forment une seule feuille de papier sur la page :
   même largeur, même fond, un filet qui en fait le tour. */
.enveloppe{max-width:var(--largeur);margin:0 auto;padding:0 var(--gouttiere)}
.feuille{
  background:var(--papier);
  border:1px solid var(--filet-fort);border-top:0;
  padding-bottom:1rem;margin-bottom:2.5rem;
}
.entete{background:var(--papier);border:1px solid var(--filet-fort);border-bottom:1px solid var(--filet);
  max-width:var(--largeur);margin:1.75rem auto 0}
.entete-int{display:flex;align-items:baseline;gap:1.5rem;padding:.9rem var(--gouttiere)}
@media (max-width:52rem){
  .entete{margin-top:0;border-left:0;border-right:0}
  .feuille{border-left:0;border-right:0;margin-bottom:0}
}
.marque{font-family:var(--serif);font-weight:600;font-size:1.32rem;letter-spacing:-.015em;text-decoration:none;white-space:nowrap;flex:none}
.marque span{color:var(--accent)}
.nav{display:flex;gap:1.15rem;flex-wrap:wrap;margin-left:auto;font-size:.9rem}
.nav a{text-decoration:none;color:var(--encre-2)}
.nav a:hover{color:var(--accent)}

/* Sur un téléphone, la navigation glisse horizontalement au lieu de passer
   à la ligne : deux lignes d'en-tête mangent le premier écran. */
@media (max-width:46rem){
  .entete-int{gap:.9rem;align-items:center}
  .marque{font-size:1.15rem}
  .nav{
    font-size:.84rem;gap:.95rem;flex-wrap:nowrap;overflow-x:auto;
    scrollbar-width:none;-webkit-overflow-scrolling:touch;
  }
  .nav::-webkit-scrollbar{display:none}
  .nav a{white-space:nowrap}
}

/* Sur un téléphone, la bande défilante ne tenait plus. Mesuré à 375 px : la
   navigation réclamait 361 px pour 232, soit 36 % hors champ, et deux entrées
   sur cinq invisibles — dont « Filtrer son eau », qui porte le cluster d'achat.
   Rien ne signalait la coupure, contrairement aux tableaux qui, eux, portent une
   ombre. Rétrécir la gouttière et la marque laissait encore 50 px cachés : il
   faut la marque sur sa propre ligne ET un libellé court. Les 28 px d'en-tête
   que ça coûte valent deux entrées qu'on ne découvrait pas.
   Ce bloc vient APRÈS celui de 46 rem : les deux s'appliquent sur un téléphone,
   et c'est le dernier qui l'emporte. */
@media (max-width:30rem){
  .entete-int{flex-wrap:wrap;gap:.35rem .9rem;align-items:baseline}
  .nav{margin-left:0;width:100%}
  /* La FIN du libellé s'efface, le libellé ne se dédouble pas : deux textes
     dont un caché donnaient « Filtrer son eauFiltrer » à qui lit le HTML sans
     le mettre en page. */
  .nav-suite{display:none}
}
/* Les écrans de 320 px existent encore. À cette largeur « Méthode » se coupait
   de 27 px : la gouttière entre entrées est le seul poste qui reste à prendre,
   et 0,6 rem tient encore les cibles tactiles à l'écart les unes des autres. */
@media (max-width:21rem){
  .nav{gap:.6rem;font-size:.82rem}
}

/* Bandeau de fil d'Ariane : monospace, sur un fond légèrement creusé, il
   sépare la navigation du document sans ajouter de trait. */
.fil{
  font-family:var(--mono);font-size:.82rem;color:var(--encre-3);
  background:var(--papier-2);border-bottom:1px solid var(--filet);
  margin:0 calc(-1 * var(--gouttiere)) 0;padding:.6rem var(--gouttiere);
  display:flex;gap:.45rem;flex-wrap:wrap;
}
.fil a{text-decoration:none;color:var(--encre-3)}
.fil a:hover{text-decoration:underline;color:var(--accent)}
.fil span:last-child{color:var(--encre)}

main{display:block;padding:2.6rem 0 3.5rem}
.colonnes{display:grid;grid-template-columns:1fr;gap:clamp(1.5rem, 1rem + 2vw, 3rem)}
/* Un élément de grille a min-width:auto : il refuse de descendre sous la
   largeur mini de son contenu. Un tableau en white-space:nowrap imposait
   donc 890 px à la colonne, et toute la page débordait horizontalement sur
   téléphone au lieu de laisser le tableau défiler dans son .defile. */
.colonnes>*{min-width:0}
/* Le rail n'apparaît qu'à 72rem, et non 62. Entre les deux il prenait
   20,5rem fixes sur un écran de 1 010 px : il ne restait que 600 px de
   colonne, et cinq pages y voyaient leurs tableaux déborder alors qu'ils
   tiennent tous dans les 940 px que donne la pleine largeur. */
@media (min-width:72rem){
  .colonnes{grid-template-columns:minmax(0,1fr) 20.5rem}
  /* align-self, mais SURTOUT PAS position:sticky. Un rail collé plus haut que
     la fenêtre épingle son sommet et rend son bas définitivement
     inatteignable : le troisième encart n'était visible que sur 8 % du
     défilement. Sans align-self, l'aside s'étire par ailleurs sur toute la
     hauteur de la ligne de grille — 9 409 px de boîte pour 712 px de
     contenu, invisible aujourd'hui mais c'est la boîte que tout futur fond
     suivrait. */
  .rail{align-self:start}
}

/* ── titres ────────────────────────────────────────────────── */
/* Le serif est composé en 400 : à ce corps, une graisse de titrage écrase la
   page. C'est <strong> qui porte l'accent, et lui seul. */
h1{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(1.75rem, 1.25rem + 2.1vw, 2.6rem);
  line-height:1.2;letter-spacing:-.012em;margin:0 0 .7rem;
  color:var(--encre);text-wrap:pretty;
}
h1 strong{font-weight:600}
h2{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(1.35rem, 1.1rem + 1vw, 1.75rem);
  line-height:1.2;letter-spacing:-.01em;margin:0 0 .55rem;
  color:var(--encre);text-wrap:pretty;
}
h2 strong{font-weight:600}
h3{font-family:var(--sans);font-weight:600;font-size:1.0625rem;margin:1.7rem 0 .4rem;letter-spacing:-.005em;color:var(--encre)}
p{margin:0 0 1rem;max-width:64ch;text-wrap:pretty}
/* Même bride que les paragraphes pour les listes sans classe : la liste
   ordonnée de « comment choisir » courait à 122 caractères par ligne en
   pleine largeur. Les listes qui portent une classe (pastilles, tuiles,
   navigation) gèrent leur propre largeur. */
ol:not([class]),ul:not([class]){max-width:64ch}
/* 38em, et non 46 : à 46 le chapeau tenait 89 caractères par ligne sur une
   fenêtre de 1 010 px, là où le rail ne s'affiche pas encore et où la colonne
   prend toute la largeur. C'est le premier paragraphe que le lecteur croise,
   et au-delà de 75 caractères l'œil rate la ligne suivante au retour. */
.chapeau{font-size:clamp(1rem, .96rem + .25vw, 1.12rem);line-height:1.55;color:var(--encre-2);max-width:38em;margin-bottom:1.6rem}

/* Entrée de page : le verdict. Il a porté un filet vertical de couleur
   d'état ; on l'a retiré. Il répétait exactement la couleur du chiffre clé de
   la phrase, et son retrait de 1,5 rem décalait le titre de la marge où tout
   le reste de la page est calé. L'état se lit dans les mots et dans le
   chiffre — un troisième canal ne disait rien de plus. */
.entree{margin-bottom:1.6rem}
.surtitre{
  font-family:var(--mono);font-size:.8rem;letter-spacing:.03em;text-transform:uppercase;
  color:var(--encre-3);margin:0 0 .8rem;max-width:none;
}
.entree h1{margin-bottom:.5rem}
/* Le constat. Il occupait le H1 ; il est passé juste dessous le jour où l'on a
   mesuré que la locution cible n'apparaissait alors nulle part dans le corps
   d'une fiche. Il reste composé en serif et garde son chiffre en couleur, à un
   corps intermédiaire entre le titre et le chapeau : deux lignes à cette taille
   pèsent toujours plus, à l'œil, que le titre court qui les surplombe. */
.verdict{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(1.2rem, 1.02rem + .75vw, 1.5rem);
  line-height:1.35;letter-spacing:-.008em;
  color:var(--encre);max-width:38em;margin:0 0 .9rem;text-wrap:pretty;
}
.verdict strong{font-weight:600}
.entree.est-ok .verdict strong:first-of-type{color:var(--ok)}
.entree.est-alerte .verdict strong:first-of-type{color:var(--alerte)}
.entree.est-grave .verdict strong:first-of-type{color:var(--grave)}

/* Accroche du hub : un chiffre, et la question qu'il pose. Le nombre tient la
   colonne étroite, le texte la large — l'inverse ferait un titre écrasé par
   sa statistique. */
.accroche{display:flex;flex-wrap:wrap;gap:2.5rem;align-items:flex-start;margin-bottom:.5rem}
.accroche-nb{flex:1 1 14rem;display:flex;flex-direction:column;gap:.35rem}
.accroche-val{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(3.2rem, 2.2rem + 4vw, 5.4rem);
  line-height:.9;letter-spacing:-.03em;color:var(--encre);
  font-variant-numeric:tabular-nums lining-nums;
}
.accroche-nb p{margin:0;font-size:1rem;color:var(--encre-2);max-width:22em}
.accroche-texte{flex:2 1 22rem}
.accroche-texte .chapeau{margin-bottom:1rem}
.lien-fort{font-weight:600;color:var(--accent);text-decoration-color:var(--accent)}

/* Tuiles « entrer par le problème » : un nombre réel par tuile, jamais un
   tiret — une grille de chiffres avec un trou attire l'œil sur le vide. */
/* 11,5 rem de colonne mini : les cinq tuiles tiennent sur une seule ligne au
   large, au lieu d'en laisser une orpheline sur un second rang. */
.tuiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(11.5rem,1fr));gap:2rem}
.tuiles + .note{margin-top:1.8rem}
.tuile{display:flex;flex-direction:column;gap:.35rem;text-decoration:none;
  border-top:1px solid var(--filet);padding-top:.9rem;transition:border-top-color .12s ease}
.tuile:hover{border-top-color:var(--accent)}
.tuile-nb{font-family:var(--serif);font-size:2.1rem;line-height:1;color:var(--accent);font-variant-numeric:tabular-nums lining-nums}
.tuile-nom{font-size:1.0625rem;font-weight:600;color:var(--encre)}
.tuile-note{font-size:.9rem;color:var(--encre-3)}

/* ── grille de fiches ──────────────────────────────────────── */
/* Quatre blocs du site — les guides, les trois portes d'entrée de l'accueil,
   les procédés, « avant d'acheter » — étaient des listes de phrases : titre
   gras, virgule, résumé, filet, au suivant. Rien n'y séparait le nom du sujet
   de son explication, et sept entrées se lisaient comme un seul paragraphe.
   Ici, une grille de fiches. Elles reprennent exactement la grammaire des
   tuiles — filet haut d'un pixel qui prend l'accent au survol, aucun cadre,
   aucune ombre — et ajoutent trois choses : un pictogramme au trait qui donne
   au regard un point d'accroche par sujet, le titre détaché de son résumé, et
   un pied en monospace comme tout l'appareil de lecture du site.
   19 rem de colonne mini : au-delà, un résumé passe à sept lignes et la grille
   se déséquilibre ; en deçà, les colonnes deviennent trop étroites pour le pied. */
.fiches{display:grid;grid-template-columns:repeat(auto-fit,minmax(19rem,1fr));gap:1.6rem 2rem;margin:.4rem 0 1rem;padding:0;list-style:none}
.fiche{
  display:flex;flex-direction:column;gap:.4rem;height:100%;
  text-decoration:none;color:inherit;
  border-top:1px solid var(--filet);padding-top:.9rem;
  transition:border-top-color .12s ease;
}
a.fiche:hover{border-top-color:var(--accent)}
/* 28 px et non les 24 du dessin : contre un titre de 17 px en demi-gras, un
   glyphe au trait de 24 se lisait comme une poussière plutôt que comme un
   repère. Le trait suit l'échelle (1,25 unité de grille = 1,46 px rendu). */
.fiche .icone{display:block;width:28px;height:28px;color:var(--accent);margin-bottom:.15rem;flex:none}
.fiche-titre{font-size:1.0625rem;font-weight:600;color:var(--encre);line-height:1.3}
a.fiche:hover .fiche-titre{color:var(--accent);text-decoration:underline;text-decoration-color:var(--accent);text-underline-offset:.18em}
.fiche-texte{font-size:.9rem;color:var(--encre-3);line-height:1.5;margin:0}
/* Le pied se cale en bas pour que les limites, les portées et les renvois
   s'alignent d'une colonne à l'autre malgré des résumés de longueurs
   différentes. */
.fiche-pied{
  margin-top:auto;padding-top:.55rem;
  font-family:var(--mono);font-size:.76rem;letter-spacing:.02em;
  color:var(--encre-3);
}
.fiche-pied a{color:var(--accent);text-decoration-color:var(--accent)}
/* Le renvoi vers une page d'index bouche le trou qu'une grille de trois
   colonnes laisse sous sept fiches, mais il ne doit pas se faire passer pour
   un huitième sujet : titre en couleur d'accent, et un pied qui annonce un
   tableau au lieu d'une mesure. */
.fiche.est-renvoi .fiche-titre{color:var(--accent)}
@media (prefers-reduced-motion:reduce){.fiche{transition:none}}

.section{border-top:1px solid var(--filet);padding-top:1.35rem;margin-top:3rem}
/* Surtitre : monospace comme tout l'appareil de lecture. */
.etiquette{
  font-family:var(--mono);font-size:.78rem;letter-spacing:.05em;text-transform:uppercase;
  color:var(--encre-3);margin:0 0 .7rem;display:block;
}

/* ── entrée d'accueil : le bandeau d'ouverture ──────────────────────────
   La référence proposée posait une photo d'eau sous un dégradé bleu et un
   encadré ombré. Ni l'une ni l'autre ne se traduisent ici : la feuille de
   papier ne supporte pas d'aplat photographique, et une ombre portée est le
   seul effet que la charte s'interdit partout ailleurs. Reste ce qui portait
   vraiment la page : un texte à gauche, un relevé chiffré à droite, et un
   fond qui bouge assez peu pour qu'on lise par-dessus.
   Le fond est fait de quatre ondes au trait, à la même couleur d'accent que
   les graphiques, décalées en phase et en vitesse. Aucune image, aucun script,
   ~1 ko de balisage, et le mouvement s'arrête net si le système le demande. */
.entree-eau{position:relative;overflow:hidden;background:var(--papier-2);border-bottom:1px solid var(--filet);margin:0 calc(-1 * var(--gouttiere)) 2.4rem;padding:2.6rem var(--gouttiere) 2.4rem}
main:has(.entree-eau),main:has(.paysage){padding-top:0}

/* ── ouverture sur média : le paysage ───────────────────────────────────
   Une photographie sur une feuille de papier, c'est le seul endroit du site
   où l'on pose un aplat d'image, et il fallait qu'elle ne se comporte pas
   comme une bannière rapportée. Trois couches y travaillent :
   un voile à la couleur d'accent, qui ramène des bleus de synthèse trop
   saturés dans la gamme du site ; un fondu vers la feuille sur le bord bas,
   pour que l'image se dissolve dans la page au lieu de s'arrêter net ; et un
   écran clair sur la gauche, qui rend le texte lisible sans caisson ni ombre
   portée — la mesure donne 8,2:1 pour l'encre sur la zone de titre.
   Le média est en position absolue et le texte en flux : la hauteur du
   bandeau est donc dictée par le texte, jamais par l'image, et une vidéo
   glissée à la place du fichier ne changera pas une ligne de mise en page. */
.paysage{position:relative;isolation:isolate;overflow:hidden;margin:0 calc(-1 * var(--gouttiere)) 2.6rem;padding:clamp(2.6rem,2rem + 5vw,6rem) var(--gouttiere) clamp(2.4rem,1.6rem + 4vw,4.5rem)}
.paysage-media{position:absolute;inset:0;z-index:-1}
.paysage-media img,.paysage-media video{width:100%;height:100%;object-fit:cover;object-position:60% 45%;display:block;filter:saturate(.72) contrast(.94) brightness(1.03)}
/* Le voile et le fondu, en deux dégradés posés sur le média. */
.paysage-media::after{
  content:"";position:absolute;inset:0;
  background:
    linear-gradient(to bottom,color-mix(in srgb,var(--accent) 22%,transparent) 0%,transparent 42%),
    linear-gradient(to top,var(--papier) 0%,color-mix(in srgb,var(--papier) 55%,transparent) 14%,transparent 38%),
    linear-gradient(to right,var(--papier) 0%,color-mix(in srgb,var(--papier) 88%,transparent) 30%,color-mix(in srgb,var(--papier) 30%,transparent) 55%,transparent 78%);
}
.paysage-int{position:relative;max-width:var(--largeur);margin:0 auto}
.paysage h1{max-width:15em;margin-bottom:.7rem}
.paysage .chapeau{max-width:34em;margin-bottom:1.4rem;color:var(--encre-2)}
.paysage .recherche{margin-top:0;max-width:32rem}
/* Le champ posé sur une image a besoin d'un bord franc : le filet clair du
   reste du site disparaîtrait sur le ciel. */
.paysage .recherche-champ{border-color:var(--filet-fort);box-shadow:0 1px 0 rgba(17,22,25,.06)}
.paysage-note{font-family:var(--mono);font-size:.78rem;color:var(--encre-3);margin:1.1rem 0 0;max-width:none}
.paysage + .releve{margin-top:0}
/* Sur un téléphone, le texte ne passe plus PAR-DESSUS l'image, il passe
   DESSOUS. Superposer les deux à 390 px demandait un écran clair sur toute
   la surface : le paysage se réduisait alors à une brume derrière quatre
   lignes de titre, et on payait 300 ko pour un fond gris. Ici l'image
   redevient une bande en tête, à son propre cadrage, et le titre commence
   dans son fondu — l'image garde sa présence, le texte garde son contraste
   plein, et le média reste le même fichier.
   L'ordre du balisage est déjà le bon : rien à réordonner. */
@media (max-width:52rem){
  .paysage{padding:0 0 .4rem;margin-bottom:2rem}
  .paysage-media{position:relative;inset:auto;z-index:0;aspect-ratio:16/10}
  .paysage-media img,.paysage-media video{object-position:64% 42%}
  .paysage-media::after{
    background:
      linear-gradient(to bottom,color-mix(in srgb,var(--accent) 20%,transparent) 0%,transparent 40%),
      linear-gradient(to top,var(--papier) 0%,color-mix(in srgb,var(--papier) 55%,transparent) 20%,transparent 52%);
  }
  /* Le titre remonte dans le fondu : la couture entre l'image et la feuille
     disparaît, et le premier écran ne se termine pas sur une bande vide. */
  .paysage-int{padding:0 var(--gouttiere);margin-top:-2.2rem}
  .paysage h1{max-width:none}
  .paysage .chapeau{margin-bottom:1.1rem}
  .paysage-note{line-height:1.6}
  /* Mesuré à 375 px : « Les 26 communes au-dessus de la limite PFAS » ne
     tient pas sur une ligne, et le nowrap du renvoi fléché le faisait ROGNER
     par l'overflow du bandeau — le texte disparaissait sans défilement pour
     le retrouver. Sur petit écran le lien reprend le retour à la ligne. */
  .actions .lien-fleche{white-space:normal}
}
/* 320 px : la bande se raccourcit, sinon elle mange le premier écran à elle
   seule et la recherche — la seule action de la page — tombe sous la ligne
   de flottaison. */
@media (max-width:24rem){
  .paysage-media{aspect-ratio:16/12}
  .paysage-note{font-size:.74rem}
}
/* Une boucle de paysage est un agrément, jamais une information : si le
   système demande moins de mouvement, la vidéo n'est jamais branchée (le
   script de la page le vérifie) et il ne reste que le poster. Cette règle est
   la ceinture qui va avec les bretelles, pour le cas où le média serait
   rebranché à la main. */
@media (prefers-reduced-motion:reduce){
  .paysage-media video{display:none}
  .paysage-media{background:url(/paysage-lac.jpg) 60% 45%/cover no-repeat}
}

/* ── affordance des liens et des appels à l'action ──────────────────────
   Le lien de prose était en couleur d'encre, souligné d'un filet crème :
   à l'échelle de la page, rien ne le distinguait d'un mot en gras, et les
   renvois de fin de section — qui sont le seul chemin vers les pages de
   fond — se lisaient comme de la ponctuation. Il prend la couleur d'accent
   et un soulignement de la même famille, qui s'épaissit au survol.
   La règle ne vise QUE la prose : la navigation, le pied, les pastilles et
   les fiches ont leur propre traitement et resteraient illisibles en bleu
   sur toute leur surface. */
p a,.note a,dd a,.liste-nue a,.question a,.tableau td a,.tableau caption a,.mention a{
  color:var(--accent);
  text-decoration-color:color-mix(in srgb,var(--accent) 38%,transparent);
  text-decoration-thickness:1px;
  transition:text-decoration-thickness .12s ease,text-decoration-color .12s ease;
}
p a:hover,.note a:hover,dd a:hover,.liste-nue a:hover,.question a:hover,.tableau td a:hover,.tableau caption a:hover,.mention a:hover{
  text-decoration-color:var(--accent);text-decoration-thickness:2px;
}
/* Renvoi fléché : la flèche est posée en CSS et non dans le texte, sinon
   elle se retrouve lue par les lecteurs d'écran et copiée avec le titre.
   Elle avance d'un cheveu au survol — le seul mouvement que le site
   s'autorise sur un lien. */
.lien-fleche{white-space:nowrap;font-weight:600}
.lien-fleche::after{content:"→";display:inline-block;margin-left:.35em;transition:transform .14s ease}
.lien-fleche:hover::after{transform:translateX(.22em)}
@media (prefers-reduced-motion:reduce){.lien-fleche::after{transition:none}}
/* Le bouton plein gagne sa flèche et un appui : au survol il passe du plein
   à l'encre plutôt qu'au vide — l'ancien état inversé donnait, l'espace d'un
   mouvement de souris, l'impression que le bouton s'était désactivé. */
.bouton{transition:background-color .12s ease,border-color .12s ease,color .12s ease}
.bouton:hover{background:var(--encre);border-color:var(--encre);color:var(--papier)}
.bouton:active{transform:translateY(1px)}
.bouton-2:active{transform:translateY(1px)}
.bouton .fleche,.bouton-2 .fleche{display:inline-block;margin-left:.4em;transition:transform .14s ease}
.bouton:hover .fleche,.bouton-2:hover .fleche{transform:translateX(.22em)}
@media (prefers-reduced-motion:reduce){.bouton,.bouton-2,.bouton .fleche,.bouton-2 .fleche{transition:none}
.bouton:active,.bouton-2:active{transform:none}}
/* La pastille de commune : elle se remplit au survol au lieu de changer
   seulement de filet. Cent noms de communes alignés, c'est une grille de
   cibles ; il faut voir laquelle on tient. */
.pastilles a{transition:background-color .12s ease,border-color .12s ease,color .12s ease}
.pastilles a:hover{background:var(--accent-clair);border-color:var(--accent);color:var(--accent)}
@media (prefers-reduced-motion:reduce){.pastilles a{transition:none}}
/* La fiche cliquable annonce sa flèche en permanence, et non au survol :
   une affordance qui n'apparaît qu'au survol n'existe pas sur un écran
   tactile, où se trouve la moitié du trafic. */
a.fiche .fiche-pied{display:flex;align-items:baseline;justify-content:space-between;gap:1rem}
a.fiche .fiche-pied::after{content:"→";color:var(--accent);transition:transform .14s ease}
a.fiche:hover .fiche-pied::after{transform:translateX(.22em)}
@media (prefers-reduced-motion:reduce){a.fiche .fiche-pied::after{transition:none}}
/* Duo d'action sous la recherche : un chemin principal, un chemin de
   parcours. Le second n'est pas un bouton — deux aplats côte à côte
   annulent la hiérarchie qu'on vient de poser. */
.actions{display:flex;flex-wrap:wrap;align-items:center;gap:.7rem 1.4rem;margin:1.1rem 0 0}
.actions .lien-fleche{color:var(--accent);text-decoration-color:color-mix(in srgb,var(--accent) 38%,transparent);text-underline-offset:.18em}
.actions .lien-fleche:hover{text-decoration-color:var(--accent);text-decoration-thickness:2px}
.ondes{position:absolute;inset:0;pointer-events:none}
.ondes svg{position:absolute;left:0;bottom:0;width:100%;height:100%;display:block;overflow:visible}
.onde{fill:none;stroke:var(--accent);stroke-width:1.5;vector-effect:non-scaling-stroke;animation:derive 34s linear infinite}
.onde-1{opacity:.20}
.onde-2{opacity:.13;animation-duration:52s;animation-direction:reverse}
.onde-3{opacity:.09;animation-duration:70s}
.onde-plein{fill:var(--accent);opacity:.045;stroke:none;animation:derive 46s linear infinite reverse}
@keyframes derive{from{transform:translateX(0)}to{transform:translateX(-300px)}}
/* Le mouvement est un agrément, jamais une information : sans lui la page est
   complète, et les ondes restent comme un filigrane fixe. */
@media (prefers-reduced-motion:reduce){.onde,.onde-plein{animation:none}}
.entree-eau-int{position:relative;max-width:var(--largeur);margin:0 auto;display:grid;gap:2.2rem;align-items:start}
@media (min-width:62rem){.entree-eau-int{grid-template-columns:minmax(0,1.25fr) minmax(0,1fr);gap:3rem}}
.entree-eau-texte{min-width:0}
.entree-eau h1{margin-bottom:.8rem}
.entree-eau .chapeau{margin-bottom:1.2rem}
.entree-eau .recherche{margin-top:0;max-width:32rem}

/* Le relevé, en panneau. Même grammaire que .encart — filet noir en tête,
   fond de feuille — pour qu'il se lise comme un encadré de journal et non
   comme une carte flottante. */
.panneau{background:var(--papier);border:1px solid var(--filet-fort);border-top:2px solid var(--encre);padding:1.1rem 1.2rem 1rem}
.panneau-tete{display:flex;justify-content:space-between;align-items:baseline;gap:.75rem;padding-bottom:.7rem;border-bottom:1px solid var(--filet)}
.panneau-titre{font-family:var(--sans);font-weight:600;font-size:.95rem;color:var(--encre)}
.panneau-maj{font-family:var(--mono);font-size:.76rem;color:var(--encre-3)}
.panneau-liste{margin:0;padding:0}
.panneau-liste>div{display:flex;justify-content:space-between;align-items:baseline;gap:1rem;padding:.7rem 0;border-bottom:1px solid var(--filet)}
.panneau-liste>div:last-child{border-bottom:0}
.panneau-liste dt{font-size:.92rem;color:var(--encre-2);max-width:16em}
.panneau-liste dd{margin:0;text-align:right;display:flex;flex-direction:column;gap:.1rem}
.panneau-liste dd b{font-family:var(--serif);font-weight:400;font-size:1.7rem;line-height:1;letter-spacing:-.015em;color:var(--encre);font-variant-numeric:tabular-nums lining-nums}
.panneau-liste dd b.est-grave{color:var(--grave)}
.panneau-liste dd span{font-family:var(--mono);font-size:.74rem;color:var(--encre-3)}
.panneau-pied{margin:.9rem 0 0;font-family:var(--mono);font-size:.76rem;color:var(--encre-3)}
.panneau-pied a{color:var(--accent);text-decoration-color:var(--accent)}

/* ── le relevé : une mesure face à sa limite ───────────────── */
/* Pas de cadre : ce qui structure, c'est le filet vertical de couleur d'état
   à gauche du chiffre. Un aplat de couleur porterait un jugement que le site
   s'interdit — la nuance entre « quantifié » et « au-dessus de la limite »
   est justement ce qu'il défend. */
.releve{
  display:grid;margin:2rem 0 0;
  grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));
  gap:2.4rem 2.75rem;
}
.mesure{display:flex;flex-direction:column;gap:.6rem}
.mesure-tete{display:flex;justify-content:space-between;align-items:baseline;gap:.75rem}
.mesure-nom{font-size:1.0625rem;font-weight:600;color:var(--encre)}
a.mesure-nom{text-decoration-color:var(--filet-fort)}
.mesure-etat{font-family:var(--mono);font-size:.82rem;color:var(--encre-3);text-align:right}
.mesure-etat.ok{color:var(--ok)}
.mesure-etat.alerte{color:var(--alerte)}
.mesure-etat.grave{color:var(--grave)}
/* Le chiffre s'aligne sur son étiquette. Le filet d'état qui l'a précédé
   était gris — donc muet — dans six des sept endroits qui posent ce bloc, et
   redondant dans le septième, où le nombre porte déjà la couleur. */
.mesure-chiffre{display:flex;align-items:baseline;gap:.4rem}
.mesure-val{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(2.2rem, 1.7rem + 2vw, 3.1rem);
  line-height:.95;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums lining-nums;color:var(--encre);
}
.mesure-val.est-texte{font-size:clamp(1.5rem, 1.2rem + 1.1vw, 2rem);line-height:1.1}
.mesure-chiffre.ok .mesure-val{color:var(--ok)}
.mesure-chiffre.alerte .mesure-val{color:var(--alerte)}
.mesure-chiffre.grave .mesure-val{color:var(--grave)}
.mesure-unite{font-family:var(--sans);font-size:1rem;color:var(--encre-3)}
.mesure-note{font-family:var(--mono);font-size:.8rem;color:var(--encre-3)}
.mesure-abs{color:var(--encre-3);font-family:var(--serif);font-size:1.6rem;font-weight:400}

/* Règle graduée : le remplissage dit la valeur, le repère noir dit la limite.
   Le repère dépasse la piste en haut et en bas pour rester lisible quand la
   valeur l'atteint presque. */
.regle{position:relative;height:.62rem;background:var(--papier-2);border-bottom:1px solid var(--filet)}
.regle i{position:absolute;left:0;top:0;bottom:0;background:var(--accent)}
.regle.est-alerte i{background:var(--alerte)}
.regle.est-grave i{background:var(--grave)}
.regle b{position:absolute;top:-.25rem;bottom:-.25rem;width:2px;background:var(--encre)}
.mesure-bornes{display:flex;justify-content:space-between;gap:.75rem;font-family:var(--mono);font-size:.8rem;color:var(--encre-3)}
.regle-seuil{font-family:var(--mono);font-size:.8rem;color:var(--encre-3)}

/* La pastille se remplit avec la gravité : creuse = conforme, à moitié =
   proche du seuil, pleine = au-dessus. La couleur seule ne portait rien qu'un
   daltonien puisse lire, et le mot à côté faisait tout le travail. */
.etat{display:inline-flex;align-items:center;gap:.4rem;font-size:.8rem;font-weight:600}
.etat::before{
  content:"";width:.6rem;height:.6rem;border-radius:50%;flex:none;
  box-shadow:inset 0 0 0 1.6px currentColor;
}
.etat.alerte::before{background:linear-gradient(to top,currentColor 50%,transparent 50%)}
.etat.grave::before{background:currentColor}
.etat.ok{color:var(--ok)}
.etat.alerte{color:var(--alerte)}
.etat.grave{color:var(--grave)}
.etat.inconnu{color:var(--encre-3)}

/* ── tableaux de données ───────────────────────────────────── */
.tableau{width:100%;border-collapse:collapse;font-size:.92rem;margin:.5rem 0 1.2rem}
.tableau caption{text-align:left;font-size:.8rem;color:var(--encre-3);padding-bottom:.5rem}
.tableau th,.tableau td{text-align:right;padding:.5rem .45rem;border-bottom:1px solid var(--filet)}
/* nowrap ne protège que ce qui se casse mal : un nombre, une date. Appliqué à
   toutes les cellules, il forçait des phrases entières sur une seule ligne —
   trois tableaux de la section filtration demandaient de faire défiler la page
   pour lire du texte. Les cellules de données portent déjà .nb ; ce sont les
   seules à en avoir besoin. */
.tableau .nb{white-space:nowrap}
/* Les en-têtes, eux, ont le droit de se replier — et c'est le seul endroit du
   tableau qui l'a. Mesuré sur /polluants/ : « MOYENNE NATIONALE », « COMMUNES
   MESURÉES » et « AU-DESSUS DE LA LIMITE » tenus sur une ligne réclamaient
   497 px à eux trois et poussaient la dernière colonne hors du cadre sur un
   écran de 1 920 px, où la colonne de texte n'en fait que 732 à côté du rail.
   Un libellé sur deux lignes se lit ; un chiffre coupé, non. La contrainte va
   donc là où elle coûte le moins.
   Aucune régression quand la place existe : la répartition des colonnes est
   automatique, donc un en-tête ne se replie que sous la pression d'une autre
   colonne. */
.tableau thead th{white-space:normal;hyphens:none}
/* Un tableau de prose n'est pas un tableau de chiffres. Le fer à droite aligne
   les unités d'une colonne de nombres ; appliqué à des phrases, il laisse un
   bord gauche déchiqueté où l'œil ne retrouve plus le début de ligne. */
.tableau-prose th,.tableau-prose td{text-align:left}
.tableau th:first-child,.tableau td:first-child{text-align:left;white-space:normal}
/* Les colonnes de chiffres sont en nowrap et prennent leur dû ; la première,
   seule à pouvoir se replier, encaissait tout le manque de place. Sur un
   téléphone elle tombait à 90 px : « Saint-Aubin-lès-Elbeuf » se cassait sur
   trois lignes et sa précision sur cinq, alors que le tableau défile déjà.
   Un plancher vaut mieux qu'un libellé illisible. */
.tableau th:first-child,.tableau td:first-child{min-width:11.5rem}
/* Quand un tableau défile, l'en-tête de ligne reste : sans lui, on lit une
   valeur sans savoir de quelle commune ou de quel paramètre elle vient. La
   matrice des procédés le faisait déjà ; ça vaut pour tous les tableaux. Le
   fond est indispensable, sinon le contenu défile sous la colonne figée. */
.defile .tableau th[scope="row"]{position:sticky;left:0;background:var(--papier);z-index:1}
.defile .tableau tbody tr:hover th[scope="row"]{background:var(--papier-2)}
.tableau thead th{font-size:.72rem;letter-spacing:.07em;text-transform:uppercase;color:var(--encre-3);font-weight:600;border-bottom:1px solid var(--filet-fort)}
/* La capitale s'arrête à l'unité. La majuscule Unicode du signe micro est le mu
   grec capital, dessiné comme un M latin : « (µg/L) » s'affichait « (MG/L) »,
   soit mille fois la valeur mesurée, sur 34 936 pages. Et « (°f) », le degré
   français de dureté, devenait « (°F) », du Fahrenheit. Le libellé est un
   micro-titre et garde la capitale ; le symbole, lui, porte du sens dans sa
   casse. La fonction unitesHorsCapitales, dans html.ts, pose l'enveloppe au
   build. */
.tableau thead th .unite{text-transform:none;letter-spacing:.04em}

/* ── repli des colonnes de qualification sur un écran étroit ────────────
   Mesuré sur un iPhone SE : le classement PFAS demandait 502 px pour 338
   disponibles. Deux colonnes sur quatre à l'écran, une coupée, une hors cadre,
   et rien pour dire à quel point il en restait.
   Ces deux colonnes-là ne se comparent pas d'une ligne à l'autre — la substance
   qui domine un point, la date de son dernier relevé qualifient CE point. Sous
   30 rem elles reviennent donc sous le nom, dans la ligne de contexte, et le
   tableau retombe à 338 px : plus aucun défilement horizontal, et le classement
   se lit en entier.
   Rien n'est masqué au lecteur : la même donnée change de place. On ne touche
   pas à la colonne classée, elle, qui est tout l'objet du tableau et doit
   rester alignée d'une ligne à l'autre.
   Ce n'est PAS le motif « une carte par ligne » : celui-là se fabrique en
   changeant la propriété display des éléments du tableau, ce qui casse leur
   sémantique
   dans certains navigateurs et laisse les lecteurs d'écran sans repère. Ici le
   tableau reste un tableau, avec deux colonnes au lieu de quatre. */
/* Le repli est masqué HORS des écrans étroits, et il faut le dire avec assez
   de poids : « .tableau th .note » est déclaré plus bas, avec une spécificité
   supérieure et un display:block. Sans les deux sélecteurs ajoutés ici, les
   spans « note repli » s'affichaient en grand écran — mesuré sur une fiche
   communale : 38 replis visibles sur 46, chacun répétant en petit corps ce que
   les colonnes voisines montraient déjà. Le défaut ne se voyait pas depuis le
   mobile, seul côté que j'avais vérifié en posant le mécanisme. */
.repli,.tableau th .note.repli,.tableau td .note.repli{display:none}
@media (max-width:30rem){
  .tableau .repliable{display:none}
  .repli{display:inline}
  /* En bloc sous le libellé, pas en ligne : c'est une ligne de qualification,
     pas la suite de la phrase. */
  .tableau th .note.repli,.tableau td .note.repli{display:block}
  /* Chaque case repliée porte son mot : la légende ferait doublon, en tête
     d'un tableau où plus aucune couleur n'est à décoder seule. */
  .legende:has(+ .defile .tableau-matrice){display:none}
  /* Déclarée ICI, et avec ce poids : « .tableau th .note.repli » ci-dessus a
     la même spécificité, donc seul l'ordre départage. La règle posée plus bas
     dans la feuille s'appliquerait à toutes les largeurs et casserait le
     format bureau. */
  .tableau th .note.repli-matrice{
    display:grid;grid-template-columns:auto 1fr auto;
    gap:.28rem .5rem;align-items:center;margin-top:.45rem;max-width:none;
  }
  /* Le plancher de 11,5 rem de la première colonne protège les noms de commune
     longs, et il vaut toujours. Mais dans un tableau qui replie, cette colonne
     porte déjà une ligne de contexte : elle se déploie de toute façon sur
     plusieurs lignes, et les 13 px qu'elle rendait ici étaient exactement ceux
     qui manquaient au tableau de détail d'une fiche communale pour tenir.
     10,5 rem est le point d'arrêt mesuré : en dessous, la largeur ne bouge plus,
     c'est le contenu qui commande. */
  .tableau:has(.repliable) th:first-child,
  .tableau:has(.repliable) td:first-child{min-width:10.5rem}
}
.tableau tbody tr:hover{background:var(--papier-2)}
.tableau .nb{font-variant-numeric:tabular-nums}
/* Précision sous un libellé de ligne : sans display:block elle se collait au
   libellé et se lisait comme la suite de la phrase. */
.tableau th .note,.tableau td .note{display:block;font-size:.78rem;font-weight:400;margin-top:.2rem;max-width:46ch}
/* Un tableau plus large que sa colonne défilait en silence : rien n'indiquait
   qu'il restait des colonnes à droite, et sur un téléphone la dernière visible
   se coupait sans prévenir. Les deux dégradés posés en local couvrent les
   bords et suivent le contenu ; les deux ombres posées en scroll restent
   collées au cadre.
   Une ombre n'apparaît donc que du côté où quelque chose est encore caché, et
   s'efface quand on atteint le bout. Aucun script. */
/* Le contour est indispensable : une zone qu'on peut atteindre au clavier
   doit dire qu'elle a le focus, sinon on défile un tableau sans savoir
   lequel. */
.defile:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.defile{
  /* position:relative est indispensable : la légende ajoutée pour les
     lecteurs d'écran est en .sr, donc en position absolue. Sans ancêtre
     positionné elle se cale sur un parent hors du conteneur de défilement et
     étire le document — le défaut déjà rencontré sur la matrice. */
  position:relative;
  overflow-x:auto;-webkit-overflow-scrolling:touch;
  background:
    linear-gradient(to right,var(--papier) 40%,rgba(248,250,252,0)) left center/2.2rem 100% no-repeat local,
    linear-gradient(to left,var(--papier) 40%,rgba(248,250,252,0)) right center/2.2rem 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%,rgba(20,23,26,.34),rgba(20,23,26,0)) left center/1.25rem 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%,rgba(20,23,26,.34),rgba(20,23,26,0)) right center/1.25rem 100% no-repeat scroll;
}

/* Matrice procédés × polluants : la case est un aplat, le mot vit dans le
   title et dans le texte réservé aux lecteurs d'écran. La première colonne
   reste visible quand le tableau défile horizontalement. */
.tableau-matrice th[scope="row"]{position:sticky;left:0;background:var(--papier);z-index:1}
.tableau-matrice .case{padding:.3rem .25rem;text-align:center}
/* Le repli de la matrice, sous 30 rem.
   Une pastille par procédé, RE-COLLÉE à son libellé et à son verdict. La
   première version repliait en texte seul : elle réglait le défilement latéral
   mais laissait quatre lignes de prose grise là où l'aplat se lisait d'un coup,
   et la légende restait affichée sans plus rien à légender. Ici la couleur
   revient, jamais seule — le remplissage de la pastille (plein / demi / vide)
   est le second indice que WCAG 1.4.1 réclame, et le mot est à côté. */
.repli-ligne{display:contents}
.repli-nom{color:var(--encre-2)}
.repli-etat{font-family:var(--mono);font-size:.76rem;text-align:right;white-space:nowrap;color:var(--encre-3)}
.repli-etat.est-plein{color:var(--accent)}
/* position:relative est indispensable : le libellé .sr de la case est en
   position:absolute, et sans ancêtre positionné il se cale sur le premier
   parent positionné en dehors du conteneur de défilement — il étirait alors
   le document à 532 px sur un écran de 390. */
.pastille{position:relative;display:block;width:100%;min-width:2.2rem;height:1.6rem;border:1px solid transparent}
i.pastille{display:inline-block;width:1rem;min-width:0;height:1rem;margin-right:.35rem;vertical-align:-2px}
.pastille.est-plein{background:var(--accent);border-color:var(--accent)}
.pastille.est-demi{background:var(--ramp-2);border-color:var(--ramp-2)}
.pastille.est-vide{background:var(--papier-2);border-color:var(--filet)}

/* barres horizontales : le classement se lit d'abord comme un tableau.
   La colonne de barres prend la moitié de la largeur — en dessous, comparer
   deux longueurs devient impossible et le graphique ne sert plus à rien. */
.tableau-barres th[scope="row"]{font-weight:400;width:30%}
.tableau-barres .barre{width:52%;padding-right:.2rem}
.tableau-barres .barre span{display:block;height:.72rem;background:var(--accent);min-width:2px;opacity:.82;
  border-radius:1px;transition:opacity .12s ease, transform .12s ease;transform-origin:left center}
.tableau-barres tbody tr:hover .barre span{opacity:1;transform:scaleY(1.18)}
.tableau-barres tr.est-courant th,.tableau-barres tr.est-courant td{font-weight:600}
.tableau-barres tr.est-courant .barre span{opacity:1}

/* ── graphiques ────────────────────────────────────────────── */
.graphe{margin:1rem 0 .4rem}
/* Trame de 4 px commune à tous les graphiques : elle les rattache les uns aux
   autres et dit « ici, c'est de la donnée », sans ajouter un seul octet
   d'image. La carte de France en est exemptée — la trame y concurrencerait
   les contours des départements. */
/* Une carte rogne à son cadre. Le débordement permis aux autres graphiques —
   pour qu'une étiquette d'axe respire — a laissé une carte mal cadrée peindre
   ses points sur toute la page, jusque hors du contenu. Le filtrage
   géométrique est la vraie correction ; ceci est le garde-fou qui fait qu'un
   défaut de coordonnées reste enfermé dans sa figure. */
/* La carte de points est carrée : sur un grand écran elle occuperait sinon
   toute la colonne en hauteur. On la borne et on la centre. */
.graphe.est-carte{max-width:34rem;margin-left:auto;margin-right:auto}
.graphe.est-carte svg{overflow:hidden}
.graphe svg{
  display:block;width:100%;height:auto;overflow:visible;
  background-color:var(--papier);
  background-image:
    repeating-linear-gradient(0deg,var(--trame) 0 1px,transparent 1px 4px),
    repeating-linear-gradient(90deg,var(--trame) 0 1px,transparent 1px 4px);
  border:1px solid var(--filet);padding:.75rem;
}
.legende{display:flex;gap:1.1rem;flex-wrap:wrap;font-family:var(--mono);font-size:.78rem;color:var(--encre-3);margin-top:.5rem}
.legende i{display:inline-block;width:.7rem;height:.7rem;margin-right:.35rem;vertical-align:-1px}

/* Porteur des tracés partagés entre plusieurs cartes d'une même page. Il ne
   montre rien, il fournit. Dimensionné à zéro plutôt que sorti du flux : un
   élément mis en absolu sans ancêtre positionné avait déjà, une fois, étiré la
   hauteur du document entier. */
.defs-carte{display:block;width:0;height:0;overflow:hidden}
.carte-fr svg{max-height:78vh;margin:0 auto;background-image:none;border:0;padding:0}
/* Deux représentations de la même donnée, une seule affichée. Sous 700 px la
   géographie rend Paris en 5,8 × 2,1 px et 19 départements sur 96 sous les
   24 px d'une cible tactile : la grille prend le relais. On masque en
   display:none — et non en visibility — pour que la figure cachée sorte aussi
   de l'arbre d'accessibilité, sinon la carte serait annoncée deux fois. */
.carte-grille{display:none}
.carte-grille svg{background-image:none;border:0;padding:0}
/* Les tuiles sont des liens, et le soulignement global des liens venait barrer
   les numéros de département à l'intérieur du SVG. */
.carte-grille a{text-decoration:none}
.carte-grille a:hover .tuile,.carte-grille .tuile:hover{fill:var(--accent)}
.carte-grille a:focus-visible .tuile{outline:2px solid var(--encre);outline-offset:1px}
@media (max-width:700px){
  .carte-fr{display:none}
  .carte-grille{display:block}
}
/* Échelle d'un choroplèthe : le dégradé reprend exactement le color-mix des
   départements, sinon la légende ment sur ce qu'elle légende. */
.echelle{display:flex;align-items:center;gap:.6rem;justify-content:center;margin-top:.6rem;font-size:.8rem;color:var(--encre-3)}
.echelle-degrade{display:block;width:min(14rem,40vw);height:.6rem;border-radius:2px;
  background:linear-gradient(to right,
    color-mix(in srgb, var(--accent) 12%, var(--papier-2)),
    color-mix(in srgb, var(--accent) 90%, var(--papier-2)))}
.carte-fr a:hover path{fill:var(--accent);fill-opacity:.9}

/* questions fréquentes */
.question{border-bottom:1px solid var(--filet);padding:.7rem 0}
.question summary{cursor:pointer;font-weight:600;list-style:none}
.question summary::-webkit-details-marker{display:none}
.question summary::before{content:"+";display:inline-block;width:1.1rem;color:var(--accent);font-weight:600}
.question[open] summary::before{content:"−"}
.question p{margin:.6rem 0 .2rem 1.1rem;color:var(--encre-2)}

/* ── repères de colonne latérale ───────────────────────────── */
/* Filet noir épais en tête plutôt qu'un cadre : le bloc se lit comme un
   encadré de journal, pas comme une publicité encapsulée. Ne portent plus que
   du repère court — les blocs de traitement sont descendus dans le fil. */
.encart{
  border:0;border-top:2px solid var(--encre);background:var(--papier-2);
  padding:1.5rem 1.4rem 1.6rem;margin:2rem 0;
}
/* h2 et h3 s'habillent pareil : un encart placé juste sous le H1 doit porter un
   h2 pour ne pas sauter un niveau, alors que dans la colonne latérale, où un h2
   a déjà été rendu plus haut dans le fil, c'est h3 qui est le bon rang. Le
   niveau suit la structure du document, pas la taille voulue. */
.encart h2,.encart h3{margin-top:0;font-family:var(--serif);font-weight:400;font-size:1.35rem;line-height:1.28}

/* ── bloc de traitement (affiliation) ──────────────────────── */
/* Il n'a ni fond, ni cadre, ni aplat : sur une page monétisée, le fond coloré
   et le formatage appuyé sont, avec l'emplacement, ce qui fait qu'un bloc se
   fait ignorer COMME une publicité. Un simple filet de séparation suffit à le
   détacher du texte qui précède, et il garde la typographie du contenu. */
.traitement{border-top:1px solid var(--filet);padding-top:1.4rem;margin:1.8rem 0 0}
.traitement h3{
  font-family:var(--serif);font-weight:400;font-size:1.3rem;line-height:1.3;
  margin:0 0 .5rem;max-width:34em;text-wrap:pretty;scroll-margin-top:1.5rem;
}
/* La citation de la mesure n'est plus en capitales. Elle fait jusqu'à trois
   lignes : or les capitales coûtent 10 à 20 % de vitesse de lecture, un prix
   qui ne se paie que sur un micro-libellé lu d'un coup d'œil, pas sur une
   phrase. Le monospace suffit à la donner pour ce qu'elle est, une citation
   de relevé. */
.traitement .declencheur{
  font-family:var(--mono);font-size:.8rem;letter-spacing:.01em;
  color:var(--encre-3);margin:0 0 .8rem;max-width:60ch;
}
.traitement .liste-nue li{border-bottom:0;padding:0 0 .7rem;font-size:1rem}
.traitement .liste-nue li strong{font-weight:600}
.divulgation{font-size:.8rem;color:var(--encre-3);margin:.4rem 0 .9rem;line-height:1.5;max-width:60ch}
.apres-traitement{margin-top:1.6rem}
.bouton{
  display:inline-block;background:var(--accent);color:var(--papier);
  padding:.62rem 1.05rem;text-decoration:none;font-weight:600;font-size:.92rem;
  border:1px solid var(--accent);
}
.bouton:hover{background:transparent;color:var(--accent);text-decoration:none}
/* Second choix, de même poids de cible mais sans l'aplat : les deux chemins
   d'un encart de traitement sont lisibles d'un coup, sans que le secondaire
   se déguise en lien de bas de page. */
.bouton-2{
  display:inline-block;background:transparent;color:var(--encre);
  padding:.62rem 1.05rem;text-decoration:none;font-weight:600;font-size:.92rem;
  border:1px solid var(--filet-fort);
}
.bouton-2:hover{border-color:var(--accent);color:var(--accent);text-decoration:none}
.boutons{display:flex;flex-wrap:wrap;gap:.6rem;margin:0 0 1rem}
.liste-nue{list-style:none;padding:0;margin:0 0 1rem}
/* Les paragraphes sont bridés à 64ch depuis toujours ; les items de liste ne
   l'étaient pas. « Ce que disent les mesures » — la section la plus lue de la
   fiche, juste sous le titre — courait donc à 124 caractères par ligne sur une
   fenêtre de 1 010 px. Au-delà de 75, l'œil rate la ligne suivante au retour
   chariot, et la compréhension chute autant qu'avec des lignes trop courtes.
   Le filet de séparation suit la même largeur : il marque la colonne de
   texte au lieu de traverser une page dont le texte n'occupe que la moitié. */
.liste-nue li{padding:.42rem 0;border-bottom:1px solid var(--filet);font-size:.92rem;max-width:64ch}
.liste-nue li:last-child{border-bottom:0}

/* ── liens internes ────────────────────────────────────────── */
.pastilles{display:flex;flex-wrap:wrap;gap:.4rem;margin:.6rem 0 1rem;padding:0;list-style:none}
.pastilles a{
  display:inline-block;padding:.28rem .62rem;border:1px solid var(--filet);
  font-size:.86rem;text-decoration:none;background:var(--papier);
}
.pastilles a:hover{border-color:var(--accent);color:var(--accent)}

/* ── recherche ─────────────────────────────────────────────── */
.recherche{position:relative;margin:1.2rem 0 0;max-width:34rem}
.recherche-champ{
  display:flex;align-items:stretch;
  border:1px solid var(--filet-fort);background:var(--papier);
}
.recherche-champ:focus-within{outline:2px solid var(--accent);outline-offset:1px}
.recherche input{
  flex:1 1 auto;min-width:0;padding:.72rem .9rem;font:inherit;font-size:1rem;
  border:0;background:transparent;color:var(--encre);
}
.recherche input:focus{outline:none}
.recherche button{
  flex:0 0 auto;border:0;padding:0 1.15rem;min-height:2.9rem;cursor:pointer;
  font:inherit;font-size:.92rem;font-weight:600;
  background:var(--accent);color:var(--papier);
}
.recherche button:hover{background:var(--encre)}
.recherche button:focus-visible{outline:2px solid var(--encre);outline-offset:-4px}
.recherche ul{
  list-style:none;margin:0;padding:0;position:absolute;left:0;right:0;z-index:5;
  background:var(--papier);border:1px solid var(--filet-fort);border-top:0;max-height:19rem;overflow:auto;
}
.recherche li a{display:block;padding:.5rem .9rem;text-decoration:none;font-size:.94rem}
.recherche li a:hover,.recherche li a:focus{background:var(--accent-clair)}
.recherche[hidden]{display:none}

/* ── pied ──────────────────────────────────────────────────── */
.pied{border-top:1px solid var(--filet);background:var(--papier-2);padding:2.2rem 0 2.6rem;font-size:.88rem;color:var(--encre-2)}
.pied-grille{display:grid;gap:1.6rem;grid-template-columns:repeat(auto-fit,minmax(13rem,1fr))}
.pied h2{font-family:var(--sans);font-size:.74rem;letter-spacing:.13em;text-transform:uppercase;color:var(--encre-3);margin-bottom:.55rem}
.pied ul{list-style:none;margin:0;padding:0}
.pied li{padding:.16rem 0}
.pied a{text-decoration:none}
.pied a:hover{text-decoration:underline}
.mention{margin-top:1.8rem;padding-top:1.1rem;border-top:1px solid var(--filet);font-size:.8rem;color:var(--encre-3);max-width:70ch}

/* ── divers ────────────────────────────────────────────────── */
.note{font-size:.85rem;color:var(--encre-3);max-width:62ch}
.sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.aller-contenu{position:absolute;left:-999px}
.aller-contenu:focus{left:.5rem;top:.5rem;position:fixed;z-index:9;background:var(--papier);padding:.5rem .8rem;border:1px solid var(--accent)}
mark{background:var(--accent-clair);color:inherit;padding:0 .15em}
.deux-cols{columns:2;column-gap:2rem}
@media (max-width:44rem){.deux-cols{columns:1}}

/* Liste de définitions : les trois postes d'un coût, le terme et sa glose. */
.definitions{display:grid;grid-template-columns:minmax(8rem,14rem) 1fr;gap:.35rem 1.5rem;margin:1.25rem 0}
.definitions dt{font-weight:600;color:var(--encre)}
/* Bridée à 64ch comme les paragraphes, et pour la même raison. Sans plafond,
   la définition prend tout le 1fr : mesuré à 1 010 px, la largeur juste
   au-dessous du seuil du rail où la page repasse en une colonne, elle courait
   à 79 caractères par ligne contre 55 aux autres largeurs. */
.definitions dd{margin:0;color:var(--encre-2);max-width:64ch}
.definitions dt+dd{border-left:2px solid var(--filet);padding-left:1rem}
@media (max-width:38rem){
  .definitions{grid-template-columns:1fr;gap:.15rem}
  .definitions dd{margin:0 0 .9rem;padding-left:1rem}
}
/* ── formulaire de contact ──────────────────────────────────────────────
   Le balisage vient de messageForm, l'implémentation partagée du dépôt : on
   ne le forke pas, on l'habille. Ses classes sont volontairement banales
   (.field .label .input .help) puisque les sites .be les remplacent par des
   noms brouillés ; ici la feuille est écrite à la main, donc on les prend
   telles quelles.
   Même grammaire que le reste : filet d'un pixel, aucun fond coloré, aucune
   ombre, et le champ posé sur la feuille plutôt que creusé. */
.contact-formulaire,form[data-messageform]{max-width:34rem;margin:1.4rem 0 0}
form[data-messageform] .field{display:flex;flex-direction:column;gap:.3rem;margin:0 0 1.1rem}
form[data-messageform] .label{font-size:.92rem;font-weight:600;color:var(--encre)}
form[data-messageform] .input{
  font:inherit;font-size:1rem;color:var(--encre);
  background:var(--papier);border:1px solid var(--filet-fort);border-radius:0;
  padding:.55rem .7rem;width:100%;
}
form[data-messageform] textarea.input{min-height:9rem;resize:vertical;line-height:1.5}
form[data-messageform] .input:focus-visible{outline:2px solid var(--focus);outline-offset:1px;border-color:var(--accent)}
/* Le message d'aiguillage d'un motif hors champ : il porte une information, pas
   une alerte, donc un filet latéral et pas un aplat. */
form[data-messageform] .help{
  font-size:.92rem;color:var(--encre-2);margin:-.5rem 0 1.1rem;
  border-left:2px solid var(--filet-fort);padding-left:.8rem;
}
form[data-messageform] .help:empty{display:none;margin:0}
form[data-messageform] button[type=submit]{
  font:inherit;font-size:.95rem;font-weight:600;
  background:var(--accent);color:var(--papier);border:1px solid var(--accent);
  border-radius:0;padding:.62rem 1.2rem;cursor:pointer;
}
form[data-messageform] button[type=submit]:disabled{
  background:transparent;color:var(--encre-3);border-color:var(--filet-fort);cursor:not-allowed;
}
form[data-messageform] button[type=submit]:not(:disabled):hover{background:var(--encre);border-color:var(--encre)}
/* Le widget de preuve de travail : il ne doit pas ressembler à une publicité,
   c'est un rouage. Filet, monospace, comme l'appareil de lecture du site. */
form[data-messageform] altcha-widget{display:block;margin:0 0 1.1rem;font-size:.86rem}
form[data-messageform] .statut,form[data-messageform] [data-messageform-status]{
  font-family:var(--mono);font-size:.85rem;margin:.7rem 0 0;
}


/* ── infobulle des graphiques ─────────────────────────────── */
.bulle{
  position:fixed;top:0;left:0;z-index:50;pointer-events:none;
  max-width:min(22rem,80vw);
  padding:.42rem .6rem;
  font-size:.82rem;line-height:1.35;
  color:var(--papier);background:var(--encre);
  border-radius:5px;
  box-shadow:0 6px 20px rgba(0,0,0,.18);
  transition:transform .06s linear;
}
@media (prefers-reduced-motion:reduce){.bulle{transition:none}}

/* ── états de survol ──────────────────────────────────────── */
figure.graphe{position:relative}
figure.graphe:focus-visible{outline:2px solid var(--accent);outline-offset:4px;border-radius:3px}

/* Courbe : toute la zone de tracé est sensible, le point le plus proche
   se met en avant. */
.zone{cursor:crosshair}
.graphe .pt{transition:r .1s ease}
.graphe .pt.est-vise{r:5.5;stroke:var(--papier);stroke-width:2}

/* histogramme annuel : la colonne visée se détache */
.barre-an{cursor:default}
.barre-an .col{transition:fill-opacity .12s ease}
.barre-an:hover .col,.barre-an.est-vise .col{fill-opacity:1}
.barre-an:hover .fond,.barre-an.est-vise .fond{fill:color-mix(in srgb,var(--accent) 7%,transparent)}

/* carte de points : la marque visée passe au premier plan */
.graphe .pt-carte{transition:fill-opacity .12s ease}
.graphe .pt-carte:hover,.graphe .pt-carte.est-vise{fill-opacity:1;stroke-width:2.5}

/* choroplèthe : le département visé s'éclaircit d'un cran */
.carte-fr .dept{transition:fill .12s ease,stroke-width .12s ease;cursor:pointer}
.carte-fr .dept:hover,.carte-fr .dept.est-vise{stroke:var(--encre);stroke-width:1.2}

/* barre de répartition : la bande visée se souligne */
.bande{transition:filter .12s ease;cursor:default}
.bande:hover,.bande.est-vise{filter:brightness(1.06)}
@media (prefers-reduced-motion:reduce){
  .graphe *{transition:none !important}
}
