/* Feuille de style du frontend EF360.

   Elle porte la maquette : jetons, gabarit d'application (M1), etat vide (M4)
   et echelle d'avertissement (M15).

   **Tout est en classes, et c'est la contrainte centrale de ce fichier.** La maquette est ecrite
   entierement en styles en ligne — chaque element porte son `style="..."`. La politique de
   securite de contenu de production dit `style-src 'self'` (docker/Caddyfile) : un attribut
   `style` est bloque, l'element se rend sans habillage, et la page est illisible **en production
   seulement** — en local, sans proxy, elle serait parfaite. Reporter la traduction, c'est donc
   garantir de decouvrir la panne au deploiement. D'ou la verification navigateur sous CSP reelle
   (`EF360_TESTS_NAVIGATEUR=1`), qui est le seul controle capable de voir ce mode de panne.

   Ce fichier ne contient aucun `!important` en dehors de l'etat desactive, ou il est repris de la
   maquette : la regle globale veut qu'un bouton indisponible soit gris quoi qu'il porte par
   ailleurs. */

/* ------------------------------------------------------------------ Archivo */

/* La police de la maquette, **servie depuis notre propre origine**.

   La maquette la charge depuis Google Fonts. Ce serait une requete sortante depuis le navigateur
   de chaque collegue — exactement ce que la regle du fond de plan proscrit. Elle est donc servie
   par nous, et la politique de securite l'accepte sans declaration particuliere : faute de
   `font-src`, elle retombe sur `default-src 'self'`, qui est notre origine.

   Jusqu'au 2026-08-15, aucun ecran n'employait donc Archivo : `--font-heading` la demandait, elle
   n'arrivait jamais, et tout s'affichait dans la police du systeme. **Une police absente se
   remplace en silence** — rien ne le signalait, et c'est en regardant les captures qu'on l'a vu.

   Les trois fichiers viennent de la version hors ligne de la maquette fournie par Antoine, qui
   les embarque. Trois sous-ensembles de caracteres, comme Google Fonts les decoupe : le latin
   suffit au francais courant, le latin etendu et le vietnamien couvrent les patronymes que le
   cadastre peut porter. 77 Ko au total, charges seulement si la page en a besoin.

   Licence : SIL Open Font License 1.1 — voir `polices/LICENCE.txt`. */

@font-face {
  font-family: "Archivo";
  font-style: normal;
  /* Fonte variable : une seule graisse declaree pour toute la plage 400-800, plutot que cinq
     fichiers. C'est ce que la maquette fait, et c'est ce qui tient en 77 Ko au total. */
  font-weight: 400 800;
  font-display: swap;
  src: url("/statique/polices/archivo-vietnamien.woff2") format("woff2");
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}

@font-face {
  font-family: "Archivo";
  font-style: normal;
  /* Fonte variable : une seule graisse declaree pour toute la plage 400-800, plutot que cinq
     fichiers. C'est ce que la maquette fait, et c'est ce qui tient en 77 Ko au total. */
  font-weight: 400 800;
  font-display: swap;
  src: url("/statique/polices/archivo-latin-etendu.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Archivo";
  font-style: normal;
  /* Fonte variable : une seule graisse declaree pour toute la plage 400-800, plutot que cinq
     fichiers. C'est ce que la maquette fait, et c'est ce qui tient en 77 Ko au total. */
  font-weight: 400 800;
  font-display: swap;
  src: url("/statique/polices/archivo-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ------------------------------------------------------------------ jetons */

/* Repris du systeme de design de la maquette pour la base, et du bloc
   `<style>` en tete de la maquette pour ce qui est propre a Energie Fonciere. Les deux sont
   recopies plutot que
   lies : le systeme de design est une passation, pas une dependance — la maquette
   dit que ce dossier ne se modifie pas ici, et une feuille liee depuis `docs/` n'entrerait pas
   dans l'image Docker.

   **La police est Archivo, servie depuis notre origine** — voir le bloc `@font-face` en tete de
   ce fichier. Ces lignes disaient le contraire jusqu'au 2026-08-22 : elles dataient d'avant
   l'embarquement des trois fichiers et affirmaient que la politique de securite interdisait la
   police et qu'on affichait celle du systeme. Les deux etaient faux, et cette phrase a suffi a
   le faire croire une seconde fois. `font-src` n'a pas besoin d'etre declare : il retombe sur
   `default-src 'self'`, qui autorise notre propre origine. Mesure au navigateur, sur la page
   servie sous la politique reelle : la police arrive, sans violation. Les graisses et les tailles
   sont celles de la maquette. */
:root {
  /* Le jaune de la sélection sur la carte et son liseré : fixes, la carte ne change pas de fond
     avec le thème. */
  --selection-jaune: #ffe600;
  --selection-lisere: #101820;
  --color-bg: #f3f2f2;
  --color-surface: #eae9e9;
  --color-text: #201e1d;
  /* Le gris des textes d'appoint : la note d'un filtre, une etape a faire. Il etait employe
     depuis le 2026-09-07 sans etre defini, et le repli « inherit » ne mettait donc rien en
     retrait. */
  --color-text-muted: color-mix(in srgb, #201e1d 72%, transparent);
  --color-divider: color-mix(in srgb, #201e1d 40%, transparent);

  --color-neutral-100: #f8f4f4;
  --color-neutral-200: #eae7e7;
  --color-neutral-300: #d7d3d3;
  --color-neutral-400: #bab6b6;
  --color-neutral-500: #9b9797;
  --color-neutral-600: #7d7979;
  --color-neutral-700: #605d5d;
  --color-neutral-800: #444141;
  --color-neutral-900: #2d2b2b;

  --color-accent: #00413B;
  --color-accent-100: #e9f2ef;
  --color-accent-200: #cde1db;
  --color-accent-300: #a3c8bf;
  --color-accent-400: #4c8d80;
  --color-accent-500: #00655a;
  --color-accent-600: #003b35;
  --color-accent-700: #00302b;
  --color-accent-800: #00211d;
  --color-accent-900: #001512;

  /* Les boutons principal et discret (doctrine, regle 8). En clair, l'accent : encre 10,33 pour 1
     au repos, 11,21 au survol ; discret 9,53 sur la surface. Leur valeur sombre est plus bas. */
  --bouton-principal: var(--color-accent);
  --bouton-principal-survol: var(--color-accent-600);
  --bouton-principal-contour-survol: var(--bouton-principal-survol);
  --bouton-principal-encre: #f3f2f2;
  --bouton-discret: var(--color-accent);

  --ef-leaf: #82C46C;
  --ef-sun: #FFCC00;

  /* L'ecart du profil altimetrique entre terrain et surface : la feuille de la marque sur le
     bati et la canopee, le rouge des refus dans un creux. */
  --profil-ecart-dessus: #82C46C;
  --profil-ecart-dessous: #C0392B;

  --ok-bg: #eaf5e4;
  --ok-ink: #2c5c1c;
  --warn-bg: #fff5d1;
  --warn-ink: #6b5300;
  /* La surface blanche des bulles et des puces du fil des échanges. */
  --crm-blanc: #ffffff;
  /* **La teinte d'un message refuse**, et elle lui est propre. `--refus-bg` existe deja, mais
     c'est le rouge franc des boutons de danger : pleine largeur sous un bandeau, il crierait.
     Un jeton a part plutot qu'une redefinition — celle-ci repeindrait les vingt-trois regles qui
     s'en servent ailleurs, dont la pastille d'erreur d'un travail long. Releve en revue le
     2026-09-21.

     **Un message « fait » n'a besoin d'aucun jeton neuf** : `--ok-bg` / `--ok-ink` disent
     exactement cela, et sont deja poses dans les deux themes. */
  --message-refus-bg: #fbe3e0;
  --message-refus-ink: #7d2d22;
  /* **Les deux niveaux de message neufs** (chantier 2, 2026-10-02) : une information sur la
     surface, une attention orangée, la teinte de `--etat-a-surveiller`. Le jaune n'en est plus. */
  --message-information-bg: #ffffff;
  --message-information-ink: #201e1d;
  --message-attention-bg: #fbeedd;
  --message-attention-ink: #6e3a03;
  --void-bg: #eae7e7;
  --void-ink: #605d5d;

  --refus-bg: #C0392B;
  --refus-ink: #ffffff;
  --refus-bord: #7B1F14;

  --rail: #00413B;
  --rail-ink: #ffffff;

  /* Le processus d'un calcul (maquette du 2026-09-26) : le bleu de l'etape qui tourne, et
     l'encre de la coche posee sur le vert de reussite. */
  --processus-bleu: #2f6fd0;
  --processus-bleu-fond: #dde8f8;
  --processus-vert: #1a7f37;
  --processus-coche: #ffffff;

  --font-heading: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body: "Archivo", system-ui, -apple-system, "Segoe UI", sans-serif;
  /* La graisse des titres, du systeme de design de la maquette. 800 et non « bold » : Archivo
     est une fonte variable declaree de 400 a 800, et 700 y est visiblement plus maigre. */
  --font-heading-weight: 800;

  --largeur-du-rail: 236px;
  --largeur-du-rail-replie: 56px;
  --hauteur-de-la-barre: 52px;
  /* La doctrine de l'interface (`docs/doctrine_ui.md`, regles 2, 3 et 6) : cinq tailles, trois
     arrondis, cinq couleurs d'etat. `tests/unit/test_doctrine_de_l_interface.py` compte ce qui
     s'en ecarte ailleurs dans la feuille. */
  --taille-etiquette: 12px;
  --taille-texte: 13px;
  --taille-ecran: 14px;
  --taille-bloc: 16px;
  --taille-titre: 20px;
  --taille-vitrine: 28px;
  --rayon-bouton: 6px;
  --rayon-cadre: 10px;
  --rayon-pilule: 999px;
  --etat-acquis: #1a7f37;
  --etat-en-cours: #4f8f3a;
  --etat-a-surveiller: #b45f06;
  --etat-bloque: #c0392b;
  --etat-neutre: #6b6767;
  /* Les technologies d'un projet, une famille de teintes par énergie (Antoine, 2026-10-01) :
     solaire, éolien, environnement, stockage et réseau. Dérogation aux règles 5 et 6 à trancher. */
  --techno-pv: #f2b705;
  --techno-agri-pv: #c3b412;
  --techno-eolien: #2b5fa8;
  --techno-repowering: #4a82c4;
  --techno-convoi: #6c8cad;
  --techno-ecologie: #2e7d4f;
  --techno-bess: #6a4c9c;
  --techno-raccordement: #9a5bb4;
  --encre-sur-clair: #201e1d;
  --encre-sur-fonce: #ffffff;
}

/* **Le theme sombre, et il est atteignable depuis le 2026-08-18.** Il l'avait ete une premiere
   fois, puis retire parce que rien ne posait `data-theme` : trente-sept lignes de jetons qu'aucun
   selecteur n'atteignait faisaient croire que la bascule existait. Elle existe maintenant —
   `src/web/theme.py` retient le choix, `base.html` pose l'attribut sur la racine, un bouton de la
   barre de titre bascule.

   **Les valeurs sont celles de la maquette, recopiees telles quelles** (son bloc `[data-theme=
   "dark"]`), a une exception pres, dite ici : la maquette ne redefinit pas les trois jetons de
   refus. Ils restent donc ceux du clair — un rouge franc sur texte blanc, qui se lit sur les deux
   fonds, et un refus doit rester le meme signal dans les deux themes.

   **`sombre` et non `dark`** : c'est notre feuille, et le reste du fichier est en francais. La
   valeur voyage entre `theme.py`, le cookie et cet attribut ; les trois disent le meme mot. */
[data-theme="sombre"] {
  /* **Graphite** (Antoine, 2026-09-28, choisie parmi trois palettes : docs/refonte_ui/mode_sombre.html).
     Des gris neutres presque noirs ; le vert de la marque, approfondi, ne sert qu'aux boutons et a
     ce qui est actif. Il remplace le vert clair, sur lequel les textes clairs ne se lisaient pas. */
  --crm-blanc: #202020;
  --color-bg: #111111;
  --color-surface: #181818;
  --color-text: #ededed;
  --color-text-muted: color-mix(in srgb, #ededed 72%, transparent);
  --color-divider: color-mix(in srgb, #ededed 30%, transparent);

  --color-neutral-100: #181818;
  --color-neutral-200: #202020;
  --color-neutral-300: #2b2b2b;
  --color-neutral-400: #454545;
  --color-neutral-500: #6e6e6e;
  --color-neutral-600: #8f8f8f;
  --color-neutral-700: #bdbdbd;
  --color-neutral-800: #d9d9d9;
  --color-neutral-900: #ededed;

  --color-accent: #2e8b6e;
  --color-accent-100: #1c2723;
  --color-accent-200: #22362f;
  --color-accent-300: #2a4a40;
  --color-accent-400: #2e6b57;
  --color-accent-500: #2e8b6e;
  --color-accent-600: #4fa88a;
  --color-accent-700: #8fd3b8;
  --color-accent-800: #bfe6d6;
  --color-accent-900: #e3f4ec;

  /* **Le principal fonce au survol, jamais n'eclaircit** (chantier 5, constat 01 §2). L'accent
     sombre portait l'encre blanche a 4,17 pour 1 au repos et 2,88 au survol (#4fa88a). Ici :
     blanc sur #267560, 5,53 pour 1 ; sur #1f6f58 au survol, 6,05. La forme du bouton sur le fond
     #111111 : 3,41 et 3,12, au-dessus du seuil de 3. Le discret, #4fa88a sur la surface #181818 :
     6,17. Calcule sur la luminance relative (WCAG 2), et garde par
     `test_chaque_paire_des_boutons_tient_son_contraste`. L'accent du theme ne bouge pas. */
  --bouton-principal: #267560;
  --bouton-principal-survol: #1f6f58;
  /* **Le contour garde la teinte du repos au survol** (revue du chantier 5, D1) : #1f6f58 sur la
     surface #181818 des panneaux ne faisait que 2,94 pour 1. #267560 y fait 3,21, et 3,41 sur le
     fond #111111 ; le fond du bouton, lui, fonce toujours. */
  --bouton-principal-contour-survol: #267560;
  --bouton-principal-encre: #ffffff;
  --bouton-discret: var(--color-accent-600);

  --ok-bg: #1f2a22;
  --ok-ink: #a8d9b8;
  --warn-bg: #2e2708;
  --warn-ink: #f3d35c;
  --message-refus-bg: #331a17;
  --message-refus-ink: #f0a89c;
  --message-information-bg: #202020;
  --message-information-ink: #ededed;
  --message-attention-bg: #2e2214;
  --message-attention-ink: #f3b678;
  --void-bg: #202020;
  --void-ink: #8f8f8f;

  --rail: #0a0a0a;
  --rail-ink: #ededed;

  --processus-bleu: #7fa8ea;
  --processus-bleu-fond: #1c2a40;
  --processus-vert: #2e8b6e;

  /* Plus sombre que la courbe, qui prend ici la feuille : la ligne du terrain reste au-dessus. */
  --profil-ecart-dessus: #2e6b57;
  --profil-ecart-dessous: #e0604f;
  --etat-acquis: #5fc27e;
  --etat-en-cours: #9bd486;
  --etat-a-surveiller: #f0a04b;
  --etat-bloque: #ef7b6c;
  --etat-neutre: #a3a3a3;
  --techno-pv: #f2c230;
  --techno-agri-pv: #cfc63e;
  --techno-eolien: #6b9ee0;
  --techno-repowering: #8ab4ea;
  --techno-convoi: #9fb6cc;
  --techno-ecologie: #4fae74;
  --techno-bess: #9a7fd0;
  --techno-raccordement: #c08ad6;
  --encre-sur-fonce: #201e1d;
}

/* **Ce qui reste sur un fond blanc en sombre garde une encre sombre** (Antoine, 2026-09-28) : la
   bulle des mesures (fond blanc de la bibliothèque de carte), les repères de la carte (fond blanc
   à 88 %) et une étiquette sans couleur du moteur (halo blanc). Leur texte suivait le thème et
   devenait clair sur blanc. */
[data-theme="sombre"] .carte__mesure-pres-du-trace,
[data-theme="sombre"] .carte__etiquette,
[data-theme="sombre"] .carte__reperes .carte__fond,
[data-theme="sombre"] .carte__reperes .carte__echelle {
  color: #2d2b2b;
}

[data-theme="sombre"] .carte__reperes .carte__echelle-titre,
[data-theme="sombre"] .carte__reperes .carte__fond-titre {
  color: #605d5d;
}

/* Le nom d'une personne sur une bulle d'« Échanges » : l'encre de sa teinte est faite pour un fond
   clair, et se perdait sur la bulle sombre. Éclaircie ici, la teinte reste reconnaissable. */
[data-theme="sombre"] .crm-bulle__pour {
  color: color-mix(in srgb, var(--crm-encre) 40%, #ffffff);
}

[data-theme="sombre"] .carte__reperes .carte__fond-choix {
  color: #2d2b2b;
  background: #ffffff;
}

/* Trois textes poses sur un vert fixe ou eclairci, releves apres le passage a Graphite : l'encre
   de l'accent y devient claire en sombre. Le niveau a encre claire garde son blanc (plus bas). */
[data-theme="sombre"] .avancement__niveaux--rampe .avancement__niveau--compris,
[data-theme="sombre"] .compte__initiales {
  color: #00211d;
}

/* La case du FGF en saisie : son fond blanc fixe portait un texte devenu clair. */
[data-theme="sombre"] .classeur-case--edition {
  background: var(--crm-blanc);
}

/* ------------------------------------------------------------------- socle */

html,
body {
  margin: 0;
  height: 100%;
}

/* **Le corps de page declare une police entiere, pas seulement une famille.**
   Il ne posait que `font-family` : tout element qui ne declarait pas la sienne heritait donc de
   la taille, de la graisse et de l'interlignage du **navigateur** — 16 px, 400, « normal » — et
   non du produit. Une douzaine d'endroits etaient dans ce cas, sur sept ecrans : l'etiquette d'un
   menu de l'administration, le bloc « l'etat n'a pas pu etre lu », les blocs de noms d'appels au
   moteur, plusieurs cartouches et compteurs.

   Ils se voyaient mal un par un et se voient d'un coup au releve : la sonde de polices de
   `la comparaison a la maquette` les a tous nommes le 2026-08-19, apres qu'Antoine eut
   suggere de chercher les polices sur un rendu plutot qu'a l'oeil. C'etait la bonne idee.

   `400` et `1.5` : la graisse et l'interlignage du texte courant du produit. Une regle qui pose
   `font:` en entier n'est pas touchee — c'est le cas de la grande majorite, et les `500` qui y
   figurent sont ceux que la maquette ecrit noir sur blanc, element par element.

   **La graisse etait a 500 jusqu'au 2026-09-02**, un cran au-dessus de la maquette, qui laisse
   son texte courant a 400 et ne monte a 500 que la ou elle le declare. Mesure au navigateur des
   deux cotes (releve du 2026-09-02) : tout ce qui herite sa graisse etait plus gras
   ici que la-bas. */
body {
  background: var(--color-bg);
  color: var(--color-text);
  font: 400 var(--taille-texte)/1.5 var(--font-body);
  -webkit-font-smoothing: antialiased;
}

/* **Les titres, dans la police des titres.** Repris tel quel du systeme de design de la maquette
   (le systeme de design de la maquette), qui pose ces deux lignes sur h1 a h4.

   Sans elles, chaque titre d'ecran heritait de la graisse « bold » du navigateur — 700 la ou la
   maquette demande 800 — et d'une police qui n'etait la bonne que par accident, parce que le
   corps de page la donne. C'est une partie de ce qu'Antoine a vu le 2026-08-18 en disant que
   certaines polices n'etaient pas les bonnes : la difference se lit sur tous les ecrans a la
   fois, et d'autant plus sur ceux ecrits avant la maquette.

   **Les tailles ne sont pas reprises.** Le systeme de design donne 42, 32, 25 et 20 px a des
   titres de page de vitrine ; nos titres portent chacun leur taille, mesuree dans la maquette
   executable a l'endroit ou ils vivent. */
h1,
h2,
h3,
h4 {
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
}

/* **Le vert de la maquette, et non une nuance voisine.** Releve le 2026-08-19 en comparant les
   couleurs peintes des deux cotes : elle emploie `--color-accent` partout ou nous avions pris
   `--color-accent-700` ou `-500`. Les jetons etaient les bons, le choix du jeton ne l'etait pas. */
a {
  color: var(--color-accent);
  text-decoration: underline;
}

a:hover {
  color: var(--color-accent);
}

/* Rayon zero partout : c'est la premiere regle du systeme visuel (README du design, Jetons). */
button,
input,
select,
textarea {
  border-radius: 0;
  font-family: inherit;
}

/* --------------------------------------------------- gabarit d'application */

/* M1 — grille `236px | 1fr` sur toute la hauteur, **sans scroll du document** : ce sont les zones
   internes qui defilent. Sans `overflow:hidden` ici, une table longue ferait defiler la page
   entiere et emporterait le rail avec elle. */
.application {
  height: 100vh;
  display: grid;
  grid-template-columns: var(--largeur-du-rail) 1fr;
  overflow: hidden;
}

/* Les pages sans rail — connexion, sante — occupent toute la largeur. Poser la meme grille avec
   une colonne vide laisserait 236 px de blanc a gauche du formulaire de connexion. */
.application--sans-rail {
  grid-template-columns: 1fr;
}

/* Le menu replie (Antoine, 2026-09-17) : la colonne se reduit aux icones, la page prend la place
   liberee. Les textes restent dans le document pour les lecteurs d'ecran : on les cache, on ne
   les retire pas, et le titre de chaque entree les montre au survol. */
.application--menu-replie {
  grid-template-columns: var(--largeur-du-rail-replie) 1fr;
}

.application--menu-replie .rail__titres,
.application--menu-replie .rail__groupe-titre,
.application--menu-replie .rail__recherche,
.application--menu-replie .rail__personne,
.application--menu-replie .carte-du-calcul__quoi,
.application--menu-replie .carte-du-calcul__temps {
  display: none;
}

/* La carte du calcul dans le menu (Antoine, 2026-09-26) : l'etape en cours, le temps ecoule et
   une barre fine ; verte a la fin, rouge sur un echec. */
.carte-du-calcul {
  display: grid;
  grid-template-columns: 8px minmax(0, 1fr) auto;
  gap: 3px 6px;
  align-items: center;
  margin: 2px 12px 6px 16px;
  padding: 6px 8px;
  border-radius: 9px;
  background: rgba(255, 255, 255, .1);
  color: var(--rail-ink);
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
  font-variant-numeric: tabular-nums;
  text-decoration: none;
}

.carte-du-calcul:hover {
  background: rgba(255, 255, 255, .16);
}

.carte-du-calcul__puce {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--carte-du-calcul-teinte);
}

.carte-du-calcul--en-cours {
  --carte-du-calcul-teinte: #8fb8f2;
}

.carte-du-calcul--termine {
  --carte-du-calcul-teinte: #7fd1b9;
}

.carte-du-calcul--arrete {
  --carte-du-calcul-teinte: #ff8a7a;
}

.carte-du-calcul--en-cours .carte-du-calcul__puce {
  animation: retour-au-travail-battement 1.2s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .carte-du-calcul--en-cours .carte-du-calcul__puce {
    animation: none;
  }
}

.carte-du-calcul__quoi {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.carte-du-calcul__barre {
  grid-column: 1 / -1;
  width: 100%;
  height: 4px;
  border: 0;
  border-radius: 999px;
  overflow: hidden;
  background: rgba(255, 255, 255, .18);
  appearance: none;
}

.carte-du-calcul__barre::-webkit-progress-bar {
  background: rgba(255, 255, 255, .18);
}

.carte-du-calcul__barre::-webkit-progress-value {
  background: var(--carte-du-calcul-teinte);
}

.carte-du-calcul__barre::-moz-progress-bar {
  background: var(--carte-du-calcul-teinte);
}

.application--menu-replie .carte-du-calcul {
  grid-template-columns: 8px;
  margin: 2px 8px 6px;
}

/* La recette de `.pour-lecture-d-ecran`, et non `display: none`, qui retirerait le nom de l'entree
   au lecteur d'ecran. */
.application--menu-replie .rail__libelle {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.application--menu-replie .rail__marque {
  justify-content: center;
  padding-left: 0;
  padding-right: 0;
}

.application--menu-replie .rail__entree {
  justify-content: center;
  padding-left: 0;
  padding-right: 0;
}

.application--menu-replie .rail__pied {
  padding-left: 0;
  padding-right: 0;
  align-items: center;
}

.application--menu-replie .rail__personne-ligne {
  flex-direction: column;
}

/* ---------------------------------------------------------------- le rail */

.rail {
  background: var(--rail);
  color: var(--rail-ink);
  display: flex;
  flex-direction: column;
  border-right: 2px solid var(--color-divider);
  overflow: hidden;
  /* La languette de repli se pose sur le bord droit, a mi-hauteur : elle se place par rapport au
     rail entier, et non dans le flux de son pied. */
  position: relative;
}

.rail__marque {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 16px 14px;
  border: 0;
  border-bottom: 2px solid rgba(255, 255, 255, .18);
  background: transparent;
  color: inherit;
  text-align: left;
  width: 100%;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  flex: none;
  text-decoration: none;
}

.rail__marque:hover {
  background: rgba(255, 255, 255, .07);
  color: inherit;
}

/* Le motif cadastral est une signature de marque : reserve aux fonds verts, jamais sous du texte
   dense (README du design, Assets). */
.rail__motif {
  opacity: .17;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  pointer-events: none;
}

.rail__logo {
  width: 30px;
  height: 30px;
  object-fit: contain;
  background: #fff;
  padding: 2px;
  position: relative;
  z-index: 2;
  flex: none;
}

.rail__titres {
  display: flex;
  flex-direction: column;
  gap: 1px;
  position: relative;
  z-index: 2;
  min-width: 0;
}

.rail__nom {
  font: 800 var(--taille-ecran)/1 var(--font-heading);
  letter-spacing: .02em;
}

/* Doctrine, regle 13 : ni la devise ni le role ne sont des etiquettes de champ, ils perdent
   donc les capitales espacees. A 12 px, elles les faisaient passer sur deux lignes. */
.rail__baseline {
  font: 600 var(--taille-etiquette)/1 var(--font-body);
  white-space: nowrap;
  opacity: .65;
}

.rail__navigation {
  flex: 1;
  overflow: auto;
  padding: 10px 0;
}

.rail__groupe {
  display: flex;
  flex-direction: column;
  margin-bottom: 14px;
}

.rail__groupe-titre {
  font: 700 var(--taille-etiquette)/1 var(--font-body);
  letter-spacing: .18em;
  text-transform: uppercase;
  opacity: .5;
  padding: 0 16px 7px;
}

/* Un item du rail. Rendu en `<a>` quand l'ecran existe, en `<span>` sinon — voir
   `_rail.html` : un lien desactive reste focalisable au clavier et annonce une destination
   qui n'existe pas. */
.rail__entree {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 16px;
  background: transparent;
  border: 0;
  color: rgba(255, 255, 255, .72);
  font: 600 var(--taille-texte)/1 var(--font-body);
  text-align: left;
  text-decoration: none;
  box-sizing: border-box;
}

a.rail__entree:hover {
  background: rgba(255, 255, 255, .07);
  color: #fff;
}

/* Item actif : fond blanc 13 % + lisere jaune, exactement la regle M1. */
/* Le dessin d'une entree. **15 px**, mesure dans la maquette executable le 2026-08-18 — pas
   estime a l'oeil. `flex: none` : sans lui, un intitule long comprimerait le dessin au lieu de
   passer a la ligne, et les douze entrees cesseraient d'etre alignees. La couleur vient du texte
   (`currentColor` dans le gabarit), donc elle suit l'entree active et le survol sans regle de
   plus. */
.rail__icone {
  width: 15px;
  height: 15px;
  flex: none;
  display: block;
}

.rail__entree--actif {
  background: rgba(255, 255, 255, .13);
  color: #fff;
  box-shadow: inset 3px 0 0 var(--ef-sun);
}

/* Ecran pas encore ecrit. **Plus aucune entree n'est dans ce cas depuis le 2026-08-18** : les
   douze ecrans existent. La regle reste — elle sert au prochain ecran ajoute, et a l'entree
   d'administration, grisee pour qui n'y a pas droit.

   **Une couleur, pas une opacite**, et c'est un correctif de revue. `opacity: .38` sur un texte
   deja pose en blanc a 72 % donnait un alpha effectif de 0,27, soit un contraste mesure de
   **2,2:1** sur le fond du rail — tres en dessous des 4,5:1 attendus pour du texte de 12,5 px.
   Le blanc a 60 % donne 5,2:1, tout en restant nettement plus terne que les 6,8:1 d'une entree
   active : la hierarchie visuelle est conservee, la lisibilite ne l'etait pas.
   `tests/unit/test_web_gabarit.py` mesure ces deux rapports plutot que de les supposer. */
.rail__entree--indisponible {
  color: rgba(255, 255, 255, .6);
  cursor: not-allowed;
}

.rail__pied {
  border-top: 2px solid rgba(255, 255, 255, .18);
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  flex: none;
}

/* La palette de commandes de la maquette, montee **desactivee** : l'ecran qu'elle ouvre n'est pas
   ecrit. Dimensions et couleurs de la maquette, y compris le fond blanc a 8 % et la bordure a
   22 % — un bouton indisponible garde sa place et sa forme, il ne devient pas un trou.

   Pas de gris supplementaire ici : le `cursor: not-allowed` et l'attribut `disabled` disent
   l'etat, et un contraste abaisse sur un fond deja sombre passerait sous le seuil de lisibilite,
   comme l'avait montre la mesure des entrees indisponibles du rail. */
.rail__recherche {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  box-sizing: border-box;
  padding: 7px 9px;
  background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .22);
  color: rgba(255, 255, 255, .8);
  font: 600 var(--taille-etiquette)/1 var(--font-body);
  text-align: left;
  cursor: pointer;
}

.rail__recherche:hover {
  background: rgba(255, 255, 255, .14);
  color: #fff;
}

/* La fenetre de la recherche du rail (2026-09-28). Sans marge interieure : un clic sur la
   fenetre elle-meme tombe alors sur le fond, et la referme. */
.rail-recherche {
  width: min(560px, calc(100vw - 32px));
  margin: 12vh auto auto;
  padding: 0;
  border: 0;
  border-radius: 14px;
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: 0 18px 48px rgba(0, 0, 0, .28);
}

.rail-recherche::backdrop {
  background: rgba(0, 0, 0, .35);
}

.rail-recherche__formulaire {
  display: grid;
  gap: 8px;
  padding: 12px;
}

.rail-recherche__champ {
  width: 100%;
  box-sizing: border-box;
  padding: 9px 12px;
  border: 1px solid var(--color-divider);
  border-radius: 999px;
  background: transparent;
  color: inherit;
  font: 500 var(--taille-ecran)/1.3 var(--font-body);
}

.rail-recherche__resultats:empty {
  display: none;
}

.rail-recherche__liste {
  display: grid;
  gap: 2px;
  max-height: 55vh;
  overflow-y: auto;
  margin: 0;
  padding: 0;
  list-style: none;
}

.rail-recherche__lien {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 10px;
  border-radius: 8px;
  color: inherit;
  text-decoration: none;
}

.rail-recherche__lien:hover,
.rail-recherche__lien:focus-visible {
  background: var(--color-neutral-100);
}

.rail-recherche__nature {
  flex: none;
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
}

.rail-recherche__phrase {
  margin: 0;
  padding: 4px 10px;
  color: var(--color-text-muted);
}

.rail__raccourci {
  font: 700 var(--taille-etiquette)/1 var(--font-body);
  opacity: .7;
}

/* Une seule rangee, comme la maquette : la pastille, le nom sur deux lignes, puis un bouton
   carre de 24 pixels. La version a deux rangees — l'identite, puis la deconnexion en toutes
   lettres en dessous — avait ete posee le 2026-08-15 parce que « Antoine Lemoine » se rendait
   « Antoin… » : le bouton mangeait la largeur. Elle a ete regardee a l'ecran et ecartee le
   2026-08-17 (`docs/DECISIONS.md`).

   Ce qui cede n'est donc plus la disposition mais le libelle du bouton. Le nom garde toute la
   largeur (`flex: 1` sur `.rail__personne`), le bouton n'en prend que 24 pixels, et le controle
   de troncature du 2026-08-15 continue de mesurer ce qu'il mesurait. */
.rail__personne-ligne {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
}

/* Le bouton qui replie et deplie le menu : discret, a droite du pied deplie, centre replie. */
/* **La languette du bord droit** (Antoine, 2026-09-18). Elle se colle a l'interieur du bord —
   le rail masque ce qui depasse — et reste a mi-hauteur, menu ouvert comme replie. */
.rail__repli {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  margin: 0;
  z-index: 2;
}

.rail__repli-bouton {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 44px;
  padding: 0;
  background: rgba(255, 255, 255, .10);
  border: 1px solid rgba(255, 255, 255, .22);
  border-right: 0;
  border-radius: 6px 0 0 6px;
  color: rgba(255, 255, 255, .8);
  cursor: pointer;
}

.rail__repli-bouton:hover {
  background: rgba(255, 255, 255, .07);
  color: #fff;
}

.rail__repli-icone {
  width: 13px;
  height: 13px;
  display: block;
}

/* Le dessin du bouton du pied. 13 px dans un bouton de 24, comme la maquette. */
.rail__signalement-icone {
  width: 13px;
  height: 13px;
  display: block;
}

.rail__initiales {
  width: 26px;
  height: 26px;
  flex: none;
  background: var(--ef-leaf);
  color: #00211d;
  font: 800 var(--taille-etiquette)/26px var(--font-heading);
  text-align: center;
}

/* Le menu du compte (Antoine, 2026-10-03). Le nom ouvre Aide, Nouveautes, Administration et Mon
   compte. **Fixe et non absolu** : le rail masque ce qui depasse, et replie il n'a que la largeur
   d'une icone. */
.rail__menu-du-compte {
  flex: 1;
  min-width: 0;
}

.rail__personne-bouton {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
  cursor: pointer;
  list-style: none;
}

.rail__personne-bouton::-webkit-details-marker {
  display: none;
}

.rail__menu {
  position: fixed;
  left: 12px;
  bottom: 56px;
  z-index: 40;
  display: flex;
  flex-direction: column;
  min-width: 210px;
  padding: 6px;
  border-radius: var(--rayon-cadre);
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: 0 0 0 1px var(--color-divider);
}

.rail__menu-entree {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 10px;
  border-radius: var(--rayon-bouton);
  color: inherit;
  font: 600 var(--taille-texte)/1.2 var(--font-body);
  text-decoration: none;
}

.rail__menu-entree:hover,
.rail__menu-entree:focus-visible,
.rail__menu-entree--actif {
  background: var(--color-bg);
}

.rail__personne {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  flex: 1;
}

.rail__nom-personne {
  font: 600 var(--taille-etiquette)/1 var(--font-body);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.rail__role {
  font: 600 var(--taille-etiquette)/1 var(--font-body);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  opacity: .6;
}

/* ----------------------------------------------------------- zone d'ecran */

.cadre {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}

.barre-de-titre {
  display: flex;
  align-items: center;
  gap: 16px;
  /* Le repere du panneau d'etat deplie, qui se pose dessous sur toute la largeur. Sans cette
     ligne, il se calerait sur la fenetre et non sur la barre. Voir `.etat-du-projet__panneau`. */
  position: relative;
  padding: 0 20px;
  /* **Le filet est compris dans la hauteur**, sans quoi la barre mesure 54 px pour un reglage de
     52 et pousse tout le contenu de deux pixels vers le bas. Releve le 2026-09-03. */
  box-sizing: border-box;
  height: var(--hauteur-de-la-barre);
  border-bottom: 2px solid var(--color-divider);
  background: var(--color-surface);
  flex: none;
}

.barre-de-titre__textes {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

/* Le titre de l'ecran. **C'est LUI qui se coupe quand la barre manque de place**, jamais le nom
   du projet : Antoine a demande le 07/09/2026 que le nom ne soit pas coupe, et il faut bien que
   quelque chose cede avant que les pastilles d'etat et la lune ne sortent du cadre. Le titre est
   ce qui coute le moins : le fil juste au-dessus le redit. */
.barre-de-titre__titre {
  margin: 0;
  font: 800 var(--taille-titre)/1 var(--font-heading);
  letter-spacing: -.01em;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Le nom du projet charge, colle aux pastilles d'etat, a leur gauche (Antoine, 07/09/2026).
   **Il ne se coupe jamais** : c'est sa demande, apres un premier jet qui le tronquait a trente
   caracteres. Un nom long referme donc l'espace souple qui le precede, et la barre le montre en
   entier. */
.barre-de-titre__projet {
  margin: 0;
  flex: none;
  white-space: nowrap;
  font: 600 var(--taille-texte)/1 var(--font-body);
  color: var(--color-text-muted);
}

/* **Rendu meme vide**, pour que htmx ait toujours ou remplacer le nom hors bande — voir
   `_nom_du_projet.html`. Sans cette regle, un ecran sans projet garderait son ecart dans la
   barre, entre le titre et les pastilles. */
.barre-de-titre__projet:empty {
  display: none;
}

/* Le vide entre le titre de l'ecran et le nom du projet. **Il peut se refermer entierement** :
   le nom passe avant lui, et c'est ce qui le laisse tenir en entier sur un nom long. */
.barre-de-titre__espace {
  flex: 1;
  min-width: 0;
}

.barre-de-titre__actions {
  display: flex;
  gap: 8px;
  flex: none;
}

/* C'est ici que ca defile, et nulle part ailleurs — voir `.application`. */
.ecran {
  flex: 1;
  overflow: auto;
  padding: 20px;
  min-height: 0;
}

/* Une page pleine dessine elle-meme ses marges — la connexion place les siennes dans chacune de
   ses deux moities. Le remplissage de `.ecran` laisserait une bande grise autour du panneau vert.

   **Le defilement reste, et ce n'est pas negociable.** Une premiere redaction posait
   `overflow: hidden` ici, pour eviter un defilement d'un ou deux pixels du a la bordure du
   panneau — un defilement qui, mesure, ne se produit pas. Ce qui se produisait, en revanche :
   sur une fenetre de 667 x 375, les deux moities s'empilent, le contenu fait 607 px, et le
   bouton « Se connecter » se retrouvait a 536 px dans un cadre de 375 — **hors de l'ecran et
   inatteignable a la souris comme au doigt**, seule la tabulation le ramenant. C'est la porte
   d'entree de l'application. Meme cause sur grand ecran : un message reporte au-dessus de
   `.connexion` — celui de la session expiree, le chemin le plus frequent vers cet ecran —
   poussait la mention du bas hors du cadre. Releve en revue, reproduit avant correction. */
.ecran--pleine-page {
  padding: 0;
  overflow: auto;
}

/* **Pleine hauteur** : le rail et la barre de titre restent, mais la zone n'a plus ni marge ni
   defilement propre — elle devient une colonne dont l'ecran occupe ce qui reste.

   Mesure de la maquette (2026-08-18, maquette executable) : sur « Carte & couches » la page ne
   defile jamais, et la carte prend exactement la place laissee par ses deux barres — 832 px sur
   une fenetre de 1 050, 682 sur une fenetre de 900. La carte etait figee a 60 % de la hauteur,
   d'ou la bande grise en dessous.

   `overflow: auto` et non `hidden`. Une premiere redaction posait `hidden`, en se fiant a la
   mesure de la maquette : le contenu tient toujours, donc rien n'a besoin de defiler. C'etait
   faux sur une fenetre **courte** — sous ~460 px de haut, la carte garde sa hauteur minimale de
   320 px et la barre du bas, qui porte le repere, le choix du fond et les trois commandes de
   sortie, se retrouvait rognee sans barre de defilement nulle part. C'est le piege que la note
   de `.ecran--pleine-page` decrit deja, sur le bouton « Se connecter ». Releve en revue.
   Avec `auto`, le rendu est identique tant que le contenu tient.
   Les bandeaux qui precedent l'ecran — l'etat inconnu de la carte, les messages — restent des
   enfants de cette colonne : ils gardent leur hauteur propre, et c'est l'ecran qui se reduit
   d'autant. C'est ce qui evite le piege deja vu deux fois, ou une nouvelle disposition deplace
   un bandeau qui etait un enfant direct. */
.ecran--pleine-hauteur {
  padding: 0;
  overflow: auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* **Les blocs « c'est vide » et « état non lu » gardent leur retrait**, sur tous les écrans et
   pas seulement sur celui du classeur.

   Un écran pleine hauteur ne pose aucune marge autour de son contenu : c'est ce qui permet à une
   carte ou à une table de toucher les bords. Mais le bloc « c'est vide » n'est pas une carte —
   collé au rail et sous la barre de titre, il se lit comme une panne d'affichage. La règle
   existait, écrite pour le seul écran du classeur le 2026-08-18 ; « Consulter une couche » et
   « Carte & couches » ne l'avaient pas, et les trois écrans ne se ressemblaient plus. Antoine l'a
   relevé le 2026-08-19 en les mettant côte à côte, et a choisi le retrait.

   Le sélecteur vise le petit-enfant (`.ecran--pleine-hauteur .etat-vide`) et non l'enfant direct :
   chaque écran enveloppe son contenu dans son propre conteneur, si bien qu'aucun de ces blocs
   n'est jamais enfant direct de l'écran. */
.ecran--pleine-hauteur .etat-vide--cadre {
  margin: 20px;
}

/* **Le bandeau d'attente d'une operation longue.** Le jaune de la maquette, pleine largeur, sous
   la barre de titre. Il n'apparait qu'au clic sur un geste qui prend du temps ; le reste du temps
   il porte `hidden` et n'occupe aucune place. */
.bandeau-d-attente {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 20px;
  background: var(--warn-bg);
  color: var(--warn-ink);
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  border-bottom: 1px solid var(--color-divider);
}

/* `hidden` seul ne suffit pas contre `display: flex`, qui l'emporte sur le style par defaut du
   navigateur : sans cette regle, le bandeau serait visible en permanence, vide. */
.bandeau-d-attente[hidden] {
  display: none;
}

.bandeau-d-attente__puce {
  width: 9px;
  height: 9px;
  flex: none;
  background: var(--ef-sun);
}

/* La phrase elle-meme : ecrite par le script au moment du clic, depuis ce que le formulaire
   declare. Elle herite de la police du bandeau ; cette regle existe pour qu'une phrase longue ne
   pousse pas la puce hors du bandeau. */
.bandeau-d-attente__phrase {
  min-width: 0;
}

/* --------------------------------------------- M2 — les trois cartouches d'etat */

/* Le motif central de la maquette : trois cartouches cote a cote sous la barre de titre, chacun
   avec sa pastille de tonalite, son kicker, son titre, son detail et au plus une action.

   `minmax(240px, 1fr)` et non `1fr` : sous 720 px de large, la rangee defile horizontalement
   plutot que d'ecraser les trois titres. C'est la valeur de la maquette. */
.cartouches {
  display: grid;
  grid-template-columns: repeat(3, minmax(240px, 1fr));
  border-bottom: 2px solid var(--color-divider);
  background: var(--color-bg);
  overflow-x: auto;
}

.cartouche {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 14px;
  border-right: 1px solid var(--color-divider);
  min-width: 0;
}

.cartouche__pastille {
  width: 10px;
  height: 10px;
  flex: none;
  display: block;
  margin-top: 4px;
}

.cartouche__textes {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  flex: 1;
}

.cartouche__kicker {
  font: 700 var(--taille-etiquette)/1 var(--font-body);
  letter-spacing: .16em;
  text-transform: uppercase;
  opacity: .75;
}

.cartouche__titre {
  font: 700 var(--taille-texte)/1.2 var(--font-heading);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cartouche__detail {
  font: 500 var(--taille-etiquette)/1.35 var(--font-body);
  opacity: .8;
}

/* Le geste d'un cartouche : un bouton secondaire commun, place sous le detail. */
.cartouche__geste {
  margin-top: 2px;
  white-space: nowrap;
  align-self: flex-start;
}

/* La zone retouchee depuis le calcul, dans le detail de l'Ecart : ses deux gestes cote a cote. */
.cartouche__gestes {
  display: flex;
  gap: 6px;
}

/* Les trois tonalites. « Inconnu » est jaune et non rouge : le serveur muet n'est pas une erreur
   de l'utilisateur, et le cartouche dit « rien a en conclure » plutot que d'affirmer une absence
   — c'est le comportement D1, qui vient d'un incident reel. */
.cartouche--present {
  background: var(--ok-bg);
  color: var(--ok-ink);
}

.cartouche--present .cartouche__pastille {
  background: var(--ef-leaf);
}

.cartouche--absent {
  background: var(--void-bg);
  color: var(--void-ink);
}

.cartouche--absent .cartouche__pastille {
  background: var(--color-neutral-500);
}

.cartouche--inconnu {
  background: var(--warn-bg);
  color: var(--warn-ink);
}

.cartouche--inconnu .cartouche__pastille {
  background: var(--ef-sun);
}

/* --- Les pastilles compactes, dans la barre de titre ------------------------------ */

/* L'endroit de la maquette : la rangee « FGF · Carto · Ecart » vit **dans** la barre de titre, a
   gauche d'« Enregistrer » et de la lune. Elle a d'abord ete collee sous la barre pour une
   raison de contrat, et Antoine ne l'a pas accepte le 2026-08-18 ; `_pastilles_d_etat.html` dit
   comment le contrat tient maintenant. */
/* Le pliage lui-meme n'a pas d'habillage : c'est un contenant, pose dans le flux de la barre. */
.etat-du-projet__pliage {
  margin: 0;
  flex: none;
}

.etat-du-projet__pliage[hidden] {
  display: none;
}

.etat-du-projet__pastilles {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  /* **Le marqueur natif est retire des trois moteurs**, et il est redessine plus bas. Chrome le
     retire de lui-meme des que le `<summary>` quitte `display: list-item` ; Firefox et Safari le
     gardent, et l'indicateur apparaitrait alors en double — un triangle a gauche, le notre a
     droite. Les deux formes sont ecrites parce qu'aucune ne couvre les trois moteurs, et que la
     verification navigateur ne mesure que Chromium. */
  list-style: none;
}

.etat-du-projet__pastilles::-webkit-details-marker {
  display: none;
}

/* Le sens du pliage, **redessine ici parce que le navigateur retire le sien**. Chrome n'affiche
   le petit triangle d'un `<summary>` que si celui-ci reste en `display: list-item` ; la rangee est
   en `flex`, donc le triangle disparait et il ne reste plus rien qui dise que ca s'ouvre. Sans
   mot a cote : la barre de titre est etroite, et le `<details>` s'annonce deja de lui-meme aux
   lecteurs d'ecran. */
.etat-du-projet__depliage {
  font: 600 var(--taille-etiquette)/1 var(--font-body);
  color: var(--color-text-muted);
}

.etat-du-projet__depliage::after {
  content: "\25BE";
}

.etat-du-projet__pliage[open] .etat-du-projet__depliage::after {
  content: "\25B4";
}

/* Le detail de l'etat : **une barre sous la barre de titre, pas un panneau detache**.

   Il etait pose en `position: absolute` et recouvrait le contenu. Antoine l'a releve le
   2026-08-19 : la maquette pousse le contenu vers le bas. Il vit donc dans le flux normal, dans
   `_barre_statut.html`, qui est le frere immediat de la barre de titre.

   `:has` porte l'ouverture : le pliage est dans la barre, le panneau apres elle, et rien d'autre
   ne peut les relier sans script — ce que la politique de securite ne nous laisse de toute facon
   pas faire en ligne. Un navigateur qui ignorerait `:has` garderait le panneau ferme : le detail
   se lit alors dans les infobulles et le texte reserve aux lecteurs d'ecran, qui portent deja la
   meme information.

   **Plus de `z-index` a tenir**, et c'est le vrai gain : le panneau ne passe plus derriere les
   commandes de la carte, puisqu'il ne passe plus devant rien. */
.etat-du-projet__panneau {
  display: none;
  background: var(--color-surface);
  border-bottom: 2px solid var(--color-divider);
}

.barre-de-titre:has(.etat-du-projet__pliage[open]) + .etat-du-projet .etat-du-projet__panneau {
  display: block;
}


/* La regle des six heures, dans le detail de l etat du projet. **En encre pleine et non dans le
   gris des explications secondaires** : elle annonce une perte possible, pas un complement. La
   meme phrase est posee dans la bibliotheque (`.bibliotheque__dechargement`), avec la meme
   couleur et pour la meme raison. */
/* **La phrase de la regle des six heures, ramenee a l'echelle du produit.** Elle posait
   `0.85rem`, c'est-a-dire 13,6 px mesures sur le reglage du navigateur, au milieu de cartouches
   ecrites de 8,5 a 11,5 px : elle sortait du lot, et c'est ce qu'Antoine a vu le 2026-08-20.

   La taille est celle de `.cartouche__detail`, le texte a cote duquel elle s'affiche : 10,5 px.
   L'interlignage est 1,4, celui que cette feuille emploie le plus (dix regles contre trois en
   1,35) — releve en revue, ou la premiere redaction annoncait a tort reprendre les deux valeurs
   de `.cartouche__detail`.

   **La forme courte `font:` impose aussi la graisse 500**, la ou la regle heritait de celle de
   son parent. C'est voulu : le corps de page pose deja 500, donc rien ne change a l'ecran, et une
   regle qui declare sa police entiere ne peut plus deriver si son parent change.

   **D'autres regles de cette feuille posent encore une taille en `rem`** (`.classeur__titre`,
   `.rapprochement__consigne-*`, `.classeur__section`…). Elles ne sont pas
   touchees ici : ce lot traite l'ecart signale, pas la feuille entiere. La regle du produit,
   elle, est l'echelle en pixels de la maquette — 203 declarations la suivent. */
.etat-du-projet__dechargement {
  margin: 12px 0 0;
  color: var(--color-text);
  font: 500 var(--taille-etiquette)/1.4 var(--font-body);
}

/* Une pastille : le point de tonalite, puis le libelle court. 7 px pour le point, mesure dans la
   maquette executable le 2026-08-18. */
.pastille {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 9px;
  border: 1px solid var(--color-divider);
  font: 600 var(--taille-etiquette)/1 var(--font-body);
}

/* Le signe de l'etat, dans le texte de la pastille : « ? » quand le serveur n'a pas repondu,
   tiret cadratin quand il n'y a rien, rien du tout quand c'est charge. Un peu plus gras que le
   libelle, pour se voir sans crier. */
.pastille__marque {
  font-weight: 800;
  margin-left: 1px;
}

.pastille__point {
  width: 7px;
  height: 7px;
  flex: none;
  display: block;
}

/* « Combler ce qui manque », dans la pastille du FGF ou de la carto quand elle manque (Antoine,
   2026-09-26). Souligné en pointillé : un lien, sans changer la couleur de l'état. */
.pastille__lien {
  color: inherit;
  text-decoration: underline dotted;
  text-underline-offset: 2px;
}

/* Les trois tonalites, celles des cartouches : un etat n'a pas deux couleurs selon la forme sous
   laquelle on le regarde. */
.pastille--present {
  background: var(--ok-bg);
  color: var(--ok-ink);
}

.pastille--present .pastille__point {
  background: var(--ef-leaf);
}

.pastille--absent {
  background: var(--void-bg);
  color: var(--void-ink);
}

.pastille--absent .pastille__point {
  background: var(--color-neutral-500);
}

/* L'etat inconnu ne se lit pas comme un avertissement : ni jaune ni rouge, la teinte neutre ; seul
   le « ! » de la maquette le distingue de l'absent (revue du chantier 3, Antoine 2026-10-02). */
.pastille--inconnu {
  background: var(--void-bg);
  color: var(--void-ink);
}

.pastille--inconnu .pastille__point {
  background: var(--etat-neutre);
}

/* « Lecture seule » en haut de l'ecran. Le meme jaune que la mention de la bibliotheque : un jaune veut dire « attention » partout dans le produit.

   Pas de point : ce n'est pas l'etat d'une moitie du projet, c'est un avertissement sur le
   dossier. Le curseur d'aide dit qu'il y a une phrase au survol. */
.pastille--lecture-seule,
.pastille--avertissement {
  background: var(--warn-bg);
  color: var(--warn-ink);
  cursor: help;
}

/* Ce qu'un lecteur d'ecran annonce et que l'oeil ne voit pas. **Pas `display: none`** : ce qui
   est masque ainsi n'est annonce par personne, et l'interet de cette classe est exactement
   l'inverse. La recette est la recette standard — un carre d'un pixel, decoupe, hors flux.

   Employee par les pastilles d'etat, ou l'oeil lit un signe (« ? ») et l'oreille doit entendre la
   phrase (« Etat du FGF inconnu »). */
.pour-lecture-d-ecran {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------- M3 — le bandeau de sauvegarde */

/* Dans la barre de titre depuis le 2026-10-03, a droite des pastilles. Deux etats seulement sont construits aujourd'hui : voir `bandeau_de_sauvegarde.py` pour
   pourquoi « en cours » et « echouee » n'y sont pas. Le meme `[hidden]` que `.bandeau-d-attente`
   le retire du flux tant qu'il n'y a rien a affirmer.

   Le pas vertical est celui de la maquette : 4 px de marge interne, soit 29 px de haut
   avec l'action. A 8 px le bandeau en faisait 37 et poussait tout l'ecran vers le bas. */
/* Dans la barre du haut depuis le 2026-10-03 : le point jaune et « Enregistrer », la phrase
   au survol du bouton. */
.bandeau-de-sauvegarde {
  display: flex;
  flex: none;
  align-items: center;
  gap: 6px;
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
}

.bandeau-de-sauvegarde[hidden] {
  display: none;
}

.bandeau-de-sauvegarde__pastille {
  width: 9px;
  height: 9px;
  flex: none;
  border-radius: 50%;
}

.bandeau-de-sauvegarde__detail {
  min-width: 0;
  flex: 1;
}

.bandeau-de-sauvegarde__echeance {
  flex: none;
  font-weight: 600;
  white-space: nowrap;
}

/* Le chemin de retour vers un travail long. **Une ligne au meme pas que le bandeau voisin**, et
   la pastille qui bat pour dire que quelque chose tourne — c'est le seul endroit du produit ou
   une animation porte une information. */
.retour-au-travail {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 20px;
  border-bottom: 1px solid var(--color-divider);
  background: var(--color-surface);
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
}

.retour-au-travail__puce {
  width: 9px;
  height: 9px;
  flex: none;
  border-radius: 50%;
  background: var(--ef-sun, currentColor);
}

/* **Le battement porte une information, et une seule : le serveur travaille.** Sur un travail
   deja fini, la pastille reste allumee sans bouger. */
.retour-au-travail__puce--bat {
  animation: retour-au-travail-battement 1.6s ease-in-out infinite;
}

/* **Le mouvement se coupe quand le systeme le demande.** Une pastille qui bat sans arret est
   exactement ce que ce reglage existe pour eteindre. */
@media (prefers-reduced-motion: reduce) {
  .retour-au-travail__puce--bat {
    animation: none;
  }
}

@keyframes retour-au-travail-battement {
  0%, 100% { opacity: 1; }
  50% { opacity: .35; }
}

.retour-au-travail__lien {
  color: inherit;
}

/* Le bandeau d'un calcul (maquette du 2026-09-23) : vert clair a la reussite, rouge des refus a
   l'arret. Pendant le calcul, il garde le fond neutre et la pastille qui bat. */
.retour-au-travail--termine {
  background: var(--ok-bg);
  color: var(--ok-ink);
}

.retour-au-travail--erreur {
  background: var(--message-refus-bg);
  color: var(--message-refus-ink);
}

.retour-au-travail__action {
  margin-left: auto;
}

/* La croix qui referme un travail fini (Antoine, 2026-09-26), collee au bord droit. */
.retour-au-travail__fermeture {
  display: flex;
  margin: 0 0 0 auto;
}

.retour-au-travail__action + .retour-au-travail__fermeture {
  margin-left: 0;
}



/* « Nouveau projet » sur la carte ouverte sans projet (2026-09-26) : une barre de mode comme les
   autres, sur une ligne. Le nom se saisit a la hauteur des commandes qui l'entourent. */
.nouveau-projet__nom.input {
  width: 220px;
  padding: 4px 8px;
  font-size: var(--taille-etiquette);
}

.nouveau-projet__parcelles {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* Les zones de la zone d'etude, nommables une a une dans le mode qui les concerne. */
.zones-nommees {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  padding: 8px 12px;
  background: var(--color-neutral-100);
  border-bottom: 1px solid var(--color-neutral-400);
  font: 500 var(--taille-texte)/1.4 var(--font-body);
}

.zones-nommees__titre {
  font-weight: 700;
  flex: 1 1 100%;
}

.zones-nommees__zone {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.zones-nommees__surface {
  color: var(--color-neutral-700);
  font-variant-numeric: tabular-nums;
}

/* « A sauvegarder » : le jaune ne reste que sur le point (Antoine, 2026-10-03) ; le fond jaune
   pleine largeur est parti avec le bandeau. */

.bandeau-de-sauvegarde--a_sauvegarder .bandeau-de-sauvegarde__pastille {
  background: var(--ef-sun);
}

/* « Sauvegardee » : rien n'est montre (gabarit `hidden`), tout est enregistre. */

.bandeau-de-sauvegarde--sauvegardee .bandeau-de-sauvegarde__pastille {
  background: var(--ef-leaf);
}

/* ------------------------------------------------------- M4 — etat vide */
/* Doctrine de l'interface, regle 11 (2026-10-01) : une ligne qui nomme ce qui manque, une phrase,
   le bouton qui le debloque, dans le cadre commun (regle 10). */
/* Deux tailles d'un même motif (chantier 3) : dans le cadre quand rien n'est chargé, sans cadre
   à la place de la première ligne d'une liste. Illisible, le cadre prend le filet et le repère « ! »
   de la teinte à surveiller : celle du refus reste aux refus (Antoine, 2026-10-02). */
.etat-vide {
  border: 1px solid var(--color-divider);
  border-radius: var(--rayon-cadre);
  background: var(--crm-blanc);
  max-width: 1040px;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
}
/* Une ligne d'écran vide qu'un script montre à la demande (recherche sans résultat). */
.etat-vide[hidden] {
  display: none;
}
.etat-vide--liste {
  border: 0;
  border-bottom: 1px solid var(--color-divider);
  border-radius: 0;
  background: none;
  max-width: none;
  padding: 12px 2px;
  gap: 8px;
}
.etat-vide--illisible {
  border-left: 4px solid var(--etat-a-surveiller);
}
.etat-vide__tete {
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
.etat-vide__ligne {
  margin: 0;
  font: 700 var(--taille-bloc)/1.3 var(--font-heading);
}
.etat-vide--liste .etat-vide__ligne {
  font: 600 var(--taille-texte)/1.4 var(--font-body);
}
.etat-vide__repere {
  flex: none;
  width: 22px;
  height: 22px;
  border: 1px solid var(--etat-a-surveiller);
  border-radius: var(--rayon-bouton);
  background: var(--message-attention-bg);
  color: var(--message-attention-ink);
  font: 800 var(--taille-texte)/20px var(--font-body);
  text-align: center;
}
.etat-vide__cause {
  margin: 2px 0 0;
  color: var(--color-text-muted);
  font-size: var(--taille-texte);
}
.etat-vide__actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
/* La valeur absente (règle 11) : le tiret long en encre grise, souligné de points quand une
   raison se lit au survol. */
.valeur-absente {
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}
.valeur-absente[title] {
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  cursor: help;
}
/* -------------------------------------------------- M15 — avertissements */

/* Trois niveaux, pas un de plus. L'avertissement vit **dans le flux**, la ou l'action se
   declenche : ni toast, ni modale (README du design, M15). */
/* **Un bandeau sur toute la largeur, comme la maquette.** Il etait borne a 92 caracteres : au
   dessus de panneaux qui prennent toute la largeur, il donnait exactement l'impression de cadres
   incoherents qu'Antoine a relevee le 2026-08-19. La borne de lecture reste, mais sur le texte
   plutot que sur le cadre. */
.avertissement {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 12px;
  border: 1px solid var(--color-divider);
  font: 500 var(--taille-etiquette)/1.45 var(--font-body);
}

.avertissement__pastille {
  width: 8px;
  height: 8px;
  flex: none;
  display: block;
  margin-top: 5px;
}

.avertissement__textes {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  /* La borne de lecture, deplacee du cadre vers le texte : une ligne trop longue se lit mal,
     mais un bandeau plus etroit que ce qu'il surplombe se voit encore plus mal. */
  max-width: 110ch;
}

.avertissement__sortie {
  font-weight: 700;
}

.avertissement--information {
  background: var(--void-bg);
  color: var(--void-ink);
}

.avertissement--information .avertissement__pastille {
  background: var(--color-neutral-500);
}

/* **Les niveaux de l'avertissement sont ceux des messages** (chantier 2, 2026-10-02) : « a
   confirmer » prend l'attention, plus le jaune qui dit « pas encore enregistre » (revue 01 §4) ;
   le refus prend le rose de l'echec, le seul dessin d'un echec dans tout le produit (01 §3). */
.avertissement--a-confirmer {
  background: var(--message-attention-bg);
  color: var(--message-attention-ink);
}

.avertissement--a-confirmer .avertissement__pastille {
  background: var(--etat-a-surveiller);
}

.avertissement--refus {
  background: var(--message-refus-bg);
  color: var(--message-refus-ink);
  border-color: var(--etat-bloque);
}

.avertissement--refus .avertissement__pastille {
  background: var(--etat-bloque);
}

/* ---------------------------------------------------------------- boutons */

/* **L'interligne d'un bouton vaut son corps**, mesure sur la maquette le 2026-09-03 : nous en
   posions 1,2, ce qui rendait chaque bouton deux pixels trop haut. Le corps est celui des
   etiquettes depuis la doctrine du 2026-10-01. */
/* Doctrine, regles 3 et 8 : un bouton sans role est un bouton secondaire, et tous les boutons
   ont la meme forme. */
.btn {
  padding: 7px 12px;
  font: 600 var(--taille-etiquette)/1 var(--font-body);
  border: 1px solid var(--color-divider);
  border-radius: var(--rayon-bouton);
  background: var(--color-surface);
  color: var(--color-text);
  cursor: pointer;
  text-decoration: none;
  display: inline-block;
}

.btn:hover {
  background: var(--color-neutral-200);
  color: var(--color-text);
}

/* **Le texte d'un bouton plein est #F3F2F2, pas #FFFFFF** — le blanc casse qui sert aussi de fond
   de page. Mesure au navigateur le 2026-09-03, sur tous les boutons verts de la maquette. */
.btn-primary {
  background: var(--bouton-principal);
  border-color: var(--bouton-principal);
  color: var(--bouton-principal-encre);
  font-weight: 700;
}

.btn-primary:hover {
  background: var(--bouton-principal-survol);
  border-color: var(--bouton-principal-contour-survol);
  color: var(--bouton-principal-encre);
}

/* Graisse 600 et non 700 : mesure au navigateur le 2026-09-03. Un bouton secondaire pese moins
   que le bouton principal de son ecran, et c'est la graisse qui le dit.

   **Son encre reste noire, et c'est voulu** : l'audit du 2026-09-03 la voulait verte, mais la
   maquette ne pose sur `.btn-secondary` que sa bordure — l'encre y reste celle de `.btn`. L'audit
   a lu le bouton fantome. Releve en revue. */
.btn-secondary {
  background: var(--color-surface);
  border-color: var(--color-divider);
  color: var(--color-text);
  font-weight: 600;
}

/* **Un bouton fantome est un lien vert sans cadre.** La maquette lui donne l'accent et un contour
   transparent — il garde donc sa place sans dessiner de boite. C'est ce qui fait la difference,
   sur la bibliotheque, entre quatre boutons identiques et « Ouvrir » suivi de deux liens.

   Le contour reste declare pour que la boite ne bouge pas ; `.sur-fond-vert .btn-ghost` et
   `.rail__signalement` le reposent, tous deux plus loin dans la feuille. */
.btn-ghost {
  background: transparent;
  border-color: transparent;
  color: var(--bouton-discret);
  font-weight: 600;
}

/* **Et son etat survole, sans quoi le lien vert redevenait noir sur plaque grise.** `.btn:hover`
   repose l'encre du texte courant, et il pesait plus lourd que `.btn-ghost` : la regle ci-dessus ne
   tenait qu'au repos. Meme mode de panne que celui decrit plus haut pour le bouton plein en theme
   sombre. La maquette ne repose jamais l'encre au survol et se contente d'une teinte d'accent. */
.btn-ghost:hover {
  background: color-mix(in srgb, var(--bouton-discret) 10%, transparent);
  color: var(--bouton-discret);
}

/* Doctrine, regle 8 : un seul rouge, pour retirer ou refuser. `.btn-refus` en est l'alias,
   garde pour les confirmations qui le portent deja. */
.btn-danger,
.btn-refus {
  background: var(--refus-bg);
  border-color: var(--refus-bord);
  color: var(--refus-ink);
}

.btn-danger:hover,
.btn-refus:hover {
  background: var(--refus-bord);
  border-color: var(--refus-bord);
  color: var(--refus-ink);
}

/* Un bouton dans une ligne de tableau ou de liste : 24 px de haut au lieu de 28. */
.btn--compact {
  padding: 5px 10px;
}

/* Un bouton qui porte une icone devant son libelle. */
.btn--avec-icone {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* Un bouton qui ne porte qu'un signe (« + », « ⋯ ») : carre de 28 px. */
.btn--icone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  box-sizing: border-box;
}

/* Un bouton qui ouvre un menu `<details>` : sans le triangle du navigateur. */
summary.btn {
  list-style: none;
}

summary.btn::-webkit-details-marker {
  display: none;
}

/* Un bouton qui reste enfonce tant que son mode dure (placer une photo, par exemple). */
.btn[aria-pressed="true"] {
  background: var(--color-accent-100);
  border-color: var(--color-accent);
  color: var(--color-accent);
}

/* La croix de fermeture, seule pour tout le produit : cible de 32 px, icone tracee de 16, encre
   de son fond, nom au survol par `title`. */
.croix-de-fermeture {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 32px;
  height: 32px;
  padding: 0;
  box-sizing: border-box;
  border: 1px solid transparent;
  border-radius: var(--rayon-bouton);
  background: transparent;
  color: inherit;
  cursor: pointer;
}

.croix-de-fermeture:hover {
  background: color-mix(in srgb, currentColor 12%, transparent);
}

.croix-de-fermeture:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}

.croix-de-fermeture__icone {
  width: 16px;
  height: 16px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

/* --------------------------------------------------- le choix d'un fichier

   **Le controle natif du navigateur ne se montre plus.** Il arrivait nu sur trois ecrans, avec sa
   forme et sa langue a lui — « Choose File / No file chosen », en anglais, trois fois sur le meme
   ecran ; la maquette dessine a la place un bouton borde pleine largeur. Releve le 2026-09-03.

   **Le champ est masque a l'oeil, pas retire** : il reste focalisable et il reste ce que le
   formulaire envoie. `display: none` le sortirait de l'ordre de tabulation, et le clavier n'aurait
   plus aucun moyen de choisir un fichier. */
.depot-de-fichier {
  cursor: pointer;
}

.depot-de-fichier__champ {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* `.btn .btn-secondary` porte l'apparence ; il ne reste ici que la largeur pleine et le centrage,
   que la maquette donne a ce bouton-la et a aucun autre. */
.depot-de-fichier__bouton {
  display: block;
  width: 100%;
  box-sizing: border-box;
  text-align: center;
}

/* Le champ etant masque, c'est le bouton qui doit montrer le focus — sinon la tabulation traverse
   l'ecran sans que rien ne bouge. */
.depot-de-fichier__champ:focus-visible + .depot-de-fichier__bouton {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}

/* Le nom du fichier choisi. **Le controle natif l'ecrivait ; en le masquant on le devait.** Sans
   lui, choisir un fichier ne change rien a l'ecran. */
.depot-de-fichier__choisi {
  display: block;
  font: 500 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-text-muted);
  /* **Un nom de fichier est toujours long.** Sans coupure, il poussait le bouton hors de sa carte
     — le defaut est deja survenu ici, et on ecrit ce nom nous-memes depuis le 2026-09-03. */
  overflow-wrap: anywhere;
}

/* Un bouton carre de 32 px qui ne porte qu'un dessin — la bascule de theme de la barre de titre.
   Les dimensions sont celles de la maquette : 32 de cote, un dessin de 15.

   `box-sizing: border-box` : sans lui, la bordure d'un pixel s'ajoute aux 32 et le bouton mesure
   34. Le meme oubli avait ete mesure le 2026-08-18 sur le bouton du pied du rail, ou il donnait
   26 px au lieu de 24 — un `<button>` recoit `border-box` du navigateur, un `<a>` non, et la
   regle est ecrite ici pour valoir dans les deux cas. */
.btn--carre {
  width: 32px;
  height: 32px;
  flex: none;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

.btn__icone {
  width: 15px;
  height: 15px;
  display: block;
}

/* Le formulaire de la bascule n'est qu'un porteur : il ne doit pas ajouter de hauteur ni de
   marge a la rangee d'actions. */
.barre-de-titre__bascule {
  margin: 0;
  display: flex;
}

/* Un bouton qui prend toute la largeur de son formulaire. Employe par la maquette sur « Se
   connecter », qui est la seule action de sa page. */
/* **Son texte est aligne a gauche**, comme la maquette le pose : un bouton pleine largeur dont
   le texte est centre laisse deux grands vides de part et d'autre, et ne se lit plus dans la
   colonne du formulaire. Releve le 2026-09-03. */
.btn-block {
  display: block;
  width: 100%;
  padding: 11px 12px;
  font: 700 var(--taille-texte)/1 var(--font-body);
  text-align: left;
}

/* **Sur fond vert fonce, l'etat desactive change d'habillage.** La regle globale de la maquette
   grise tout ce qui est indisponible ; appliquee telle quelle sur un bloc vert, elle donne un
   gris clair sur vert fonce, illisible — releve en regardant l'ecran le 2026-08-15
   (`docs/BUGS.md`, symptome 2). La maquette montre au meme endroit un bouton blanc plein et un
   bouton en contour clair : ce qui suit garde le **sens** de la regle globale — on voit que
   l'action ne se fait pas — en le disant avec les couleurs du fond sur lequel elle se pose.

   `!important` comme la regle globale, et pour la meme raison : elle doit gagner contre les
   variantes de bouton, et celle-ci doit gagner contre elle. */
.sur-fond-vert .btn[disabled],
.sur-fond-vert .btn:disabled {
  background: rgba(255, 255, 255, .12) !important;
  /* .70 et non .62 : a .62 le libelle tombe a 4,26 de contraste, sous le seuil de 4,5. Une
     commande desactivee n'y est pas soumise — mais « Calculer les donnees » est justement le
     libelle qu'on a interet a pouvoir lire pour comprendre ce qui manque. .70 donne 4,95 sans
     rien changer a l'aspect de plaque sombre. */
  color: rgba(255, 255, 255, .70) !important;
  border-color: rgba(255, 255, 255, .3) !important;
  cursor: not-allowed !important;
}

/* Le meme fond vert rend illisible un bouton **actif** en contour : `btn-ghost` peint son texte
   en `--color-text`, qui est presque noir. C'est le cas de « Se deconnecter » dans le pied du
   rail — le seul moyen de sortir de l'application, et il se lisait a peine. Trouve en meme temps
   que le precedent, en regardant l'ecran.

   **Le lisere est passe de .35 a .45 le 2026-08-17.** Mesure : a .35 il ne se detachait du vert
   du rail qu'a 2,75 pour 1, sous le 3 pour 1 exige d'un contour qui porte a lui seul la forme
   d'une cible — cas du bouton de sortie, qui n'a pas de fond. La verification navigateur mesure
   desormais ce contraste-la ; la remarque « aucun test ne mesure un contraste », qui figurait
   ici, n'est plus vraie. */
.sur-fond-vert .btn-ghost {
  border-color: rgba(255, 255, 255, .45);
  color: #ffffff;
}

.sur-fond-vert .btn-ghost:hover {
  background: rgba(255, 255, 255, .14);
  color: #ffffff;
}

/* Le bouton de sortie du pied du rail — **declare ici, apres `.sur-fond-vert .btn-ghost`, et
   c'est la seule raison de sa place dans ce fichier.**

   Il vivait avec le reste du rail, quatre cents lignes plus haut. A specificite egale, c'est le
   dernier declare qui gagne : `.btn` et `.btn-ghost` ecrasaient donc presque tout ce bloc. Mesure
   dans le navigateur avant correction : le bouton faisait 26 x 24 px au lieu de 24 x 24, son
   icone affleurait la bordure de droite, et le jaune de survol de la maquette n'apparaissait
   jamais. Releve en contre-revue.

   **Deplacer le bloc n'a suffi qu'a moitie, et la revue du 2026-08-17 l'a mesure.** L'ordre de
   declaration ne departage que des selecteurs de meme poids : `.sur-fond-vert .btn-ghost:hover`
   porte deux classes et un etat, il l'emporte sur `.rail__signalement:hover` ou qu'on l'ecrive. Le
   survol restait donc blanc translucide. Le survol se declare desormais avec le meme poids, et
   apres — c'est la seule facon de gagner sans `!important`.

   Les mesures viennent de la maquette, au pixel : 24 x 24, contour clair, fond transparent.
   `color: #fff` n'est pas decoratif — l'icone est tracee en `currentColor`, et c'est cette
   couleur que le controle de contraste du rail mesure.

   **Ce bouton portait la sortie jusqu'au 2026-08-18 ; il porte le signalement depuis.** Sa forme
   n'a pas bouge — c'est la meme case de 24 px au meme endroit, avec le meme contour et le meme
   survol jaune : seuls le dessin et la destination changent. Les regles ci-dessous sont donc
   celles d'avant, renommees. */
.rail__signalement {
  width: 24px;
  height: 24px;
  /* **Sans cette ligne le bouton mesure 26 px, et c'est la mesure navigateur qui l'a dit.** Le
     navigateur pose `box-sizing: border-box` d'office sur un `<button>`, pas sur un `<a>` : en
     devenant un lien, le bouton s'est mis a ajouter son contour de 1 px de chaque cote aux 24
     demandes. La cible cliquable grossissait, et surtout elle cessait d'etre celle de la
     maquette. */
  box-sizing: border-box;
  flex: none;
  padding: 0;
  background: transparent;
  /* Epaisseur seulement : la **couleur** du lisere vient de `.sur-fond-vert .btn-ghost`, qui
     porte deux classes et l'emporterait de toute facon sur celle-ci. La redire ici la ferait
     diverger en silence a la premiere correction. */
  border: 1px solid;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* **Le rail vert est dans le selecteur, et il doit y rester.** Sans lui, cette regle pese moins
   que le survol generique des boutons fantomes et redevient inerte : c'est exactement la panne
   que la revue a mesuree. La verification navigateur mesure ce fond-la. */
.sur-fond-vert .rail__signalement:hover {
  background: var(--ef-sun);
  border-color: var(--ef-sun);
  color: var(--color-accent-800);
}

/* Regle globale : tout etat « Indisponible » passe par `disabled`, et se rend gris avec le
   curseur interdit. `!important` repris de la maquette — c'est la seule regle qui doit gagner
   contre toutes les variantes de bouton. */
/* **Un bouton eteint reste un bouton.** Son filet reprenait la couleur de son fond : pose sur le
   fond de page, qui en est tres proche, il disparaissait entierement — « Ouvrir l'outil »,
   « Ouvrir », « Voir dans le FGF » se lisaient comme du texte ordinaire, et rien ne disait qu'il
   y avait la une commande. Le defaut touchait toutes les commandes eteintes du produit, c'est-a-
   dire presque toutes celles de la phase actuelle. Vu a l'ecran le 2026-08-19. */
/* Doctrine, regle 9 : un bouton eteint se voit eteint. Le filet en pointillé et le fond
   transparent le separent d'un bouton secondaire, que son gris imitait. */
.btn[disabled],
.btn:disabled,
.btn[aria-disabled="true"] {
  background: transparent !important;
  color: var(--void-ink) !important;
  border-color: var(--color-neutral-500) !important;
  border-style: dashed !important;
  cursor: not-allowed !important;
  box-shadow: none !important;
  opacity: 1 !important;
}

/* --------------------------------------------------------------- messages */

/* Les messages de `messages.py` : ce qui **vient de se passer**, flottant au bas de l'ecran depuis
   le 2026-09-21. Distincts des avertissements de M15, qui disent ce qui **va** se passer et vivent
   a cote de l'action — voir la docstring de `src/web/avertissements.py`. */
/* **Les messages flottent en bas depuis le 2026-09-21** (Antoine) : « les messages d'erreurs ne
   s'affichent pas en bas de l'ecran, en flottant, comme c'etait prevu ». Ils etaient dans le flot,
   en tete de l'ecran, et une phrase de refus un peu longue descendait toute la mise en page — sur
   le classeur, la table sautait de deux lignes au moment ou l'on saisissait.

   **En bas a droite, et pas au centre** : le rail occupe la gauche, et sa largeur change quand on
   le replie. La droite est toujours de la zone de contenu, a toute largeur de fenetre.

   **Le conteneur ne prend pas le clic**, la liste si : vide, il est rendu quand meme — c'est ce
   qui donne a `hx-swap-oob` une cible —, et un bloc fixe invisible qui avalerait les clics du bas
   de l'ecran serait pire que le defaut qu'on corrige. */
/* **Au-dessus de la cartographie, et c'est une mesure qui l'a fixe.** A `z-index: 40`, le message
   etait peint SOUS les calques de Leaflet — le conteneur de la carte est `position: relative` sans
   `z-index`, donc il ne fait pas de contexte d'empilement, et ses calques (200 a 1000) sortent
   dans celui de la page. Mesure au navigateur le 2026-09-21 sur les deux feuilles reelles :
   `elementFromPoint` rendait la tuile sur les 144 premiers pixels du message. 1100 passe au-dessus
   des 1000 de Leaflet, et au-dessus du menu du clic droit, qui est au meme niveau : les deux ne se
   rencontrent qu'au coin bas droit, et un message qui dit ce qui vient d'echouer vaut mieux la
   qu'un menu qu'un clic ailleurs referme. */
#messages {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 1100;
  width: min(60ch, calc(100vw - 48px));
  pointer-events: none;
}

/* **La pile defile chez elle, et non dans son conteneur** : celui-ci ne prend pas le clic, donc
   il n'aurait pas pris la molette non plus. Au-dela de sa hauteur, les messages les plus anciens
   se remontent. */
.messages {
  list-style: none;
  margin: 0;
  padding: 0;
  font: 500 var(--taille-etiquette)/1.45 var(--font-body);
  display: grid;
  gap: 6px;
  max-height: min(40vh, 320px);
  overflow-y: auto;
  pointer-events: auto;
}

/* **Chaque message porte son niveau** (Antoine, 2026-09-15 : « les messages polluent l'ecran »).
   Le cadre jaune d'avertissement habillait tout, une reussite comme un refus : il fallait lire la
   phrase pour savoir lequel des deux on regardait.

   **Quatre niveaux, chacun son fond, sa marque de gauche et son icone** (chantier 2, 2026-10-02) :
   reussite, information, attention, echec. La marque prend la variable d'etat du niveau, et
   l'icone le dit sans la couleur. Plus de jaune : aucun message n'est sans niveau. */
/* **Un cadre et une ombre depuis qu'ils flottent** : posee sur la table ou sur la carte, une
   phrase sans relief se confondait avec ce qu'elle recouvre. */
/* **La phrase, puis la croix qui l'ecarte**, sur une ligne. La croix garde sa largeur quoi qu'il
   arrive : une phrase longue la reduirait a rien, et c'est la seule facon de faire partir un refus
   avant de recharger la page. */
.messages__ligne {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 9px 12px;
  border: 1px solid var(--color-divider);
  border-left: 4px solid var(--message-marque);
  border-radius: var(--rayon-bouton);
  box-shadow: 0 4px 14px rgba(32, 30, 29, .22);
  background: var(--message-bg);
  color: var(--message-ink);
}

/* **L'icone du niveau, peinte de sa marque a travers un masque** : un seul dessin par niveau,
   pose ici, que le gabarit comme le script qui pose un refus recoivent sans rien ecrire. Les
   traces sont ceux de la maquette du chantier 2. L'espace de noms du dessin s'ecrit `%2F%2F` : le
   controle des polices refuse toute adresse en `//` dans la feuille, et le dessin ne charge rien. */
.messages__ligne::before {
  content: "";
  flex: none;
  width: 16px;
  height: 16px;
  margin-top: 1px;
  background: var(--message-marque);
  -webkit-mask: var(--message-icone) center / contain no-repeat;
  mask: var(--message-icone) center / contain no-repeat;
}

.messages__texte {
  flex: 1;
}

/* **Elle prend la couleur de son message** (`currentColor` par `color: inherit`) : les trois
   niveaux ont trois fonds, et une croix d'une teinte fixe serait illisible sur l'un des trois.
   Attenuee au repos pour que la phrase reste ce qu'on lit d'abord, pleine des qu'on la vise. */
.messages__ecarter {
  flex: none;
  margin: -2px -4px 0 0;
  padding: 0 4px;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: var(--taille-ecran);
  line-height: 1.2;
  opacity: .7;
  cursor: pointer;
}

.messages__ecarter:hover,
.messages__ecarter:focus-visible {
  opacity: 1;
}

/* **Pose dans la page, pas flottant** : une page d'echec (`_echec_d_une_page.html`) porte le
   meme dessin qu'un message, sans l'ombre qui le detache d'un ecran qu'il recouvre. */
.messages__ligne--fixe {
  max-width: 70ch;
  margin: 0 0 12px;
  box-shadow: none;
}

.echec-d-une-page__retour {
  margin: 0;
}

/* Reussite : le geste a abouti. */
.messages__ligne--f {
  --message-bg: var(--ok-bg);
  --message-ink: var(--ok-ink);
  --message-marque: var(--etat-acquis);
  --message-icone: url("data:image/svg+xml,%3Csvg xmlns='http:%2F%2Fwww.w3.org%2F2000%2Fsvg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5l3.2 3L13 4.5'/%3E%3C/svg%3E");
}

/* Information : ce qu'il faut savoir, sans rien a corriger. */
.messages__ligne--i {
  --message-bg: var(--message-information-bg);
  --message-ink: var(--message-information-ink);
  --message-marque: var(--etat-neutre);
  --message-icone: url("data:image/svg+xml,%3Csvg xmlns='http:%2F%2Fwww.w3.org%2F2000%2Fsvg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='8' cy='8' r='6'/%3E%3Cpath d='M8 7.5v3.5M8 5h0'/%3E%3C/svg%3E");
}

/* Attention : un resultat partiel, ou un ecran ouvert ailleurs que demande. */
.messages__ligne--a {
  --message-bg: var(--message-attention-bg);
  --message-ink: var(--message-attention-ink);
  --message-marque: var(--etat-a-surveiller);
  --message-icone: url("data:image/svg+xml,%3Csvg xmlns='http:%2F%2Fwww.w3.org%2F2000%2Fsvg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 2.5l6 11H2z'/%3E%3Cpath d='M8 7v3M8 12h0'/%3E%3C/svg%3E");
}

/* Echec : le geste n'a pas eu lieu, et la phrase dit par ou sortir. */
.messages__ligne--r {
  --message-bg: var(--message-refus-bg);
  --message-ink: var(--message-refus-ink);
  --message-marque: var(--etat-bloque);
  --message-icone: url("data:image/svg+xml,%3Csvg xmlns='http:%2F%2Fwww.w3.org%2F2000%2Fsvg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='8' cy='8' r='6'/%3E%3Cpath d='M5.8 5.8l4.4 4.4M10.2 5.8l-4.4 4.4'/%3E%3C/svg%3E");
}

/* ------------------------------------------------------- accueil, connexion */

/* La ligne de date de la maquette : un tiret jaune de 26 px sur 4, puis la date en capitales
   espacees. Valeurs relevees dans la maquette — 11 px entre les deux, 9 px de texte, 0,2 em
   d'espacement. */
/* **Nom distinct de `.accueil__date`**, qui designe la date d'une ligne de reprise, plus bas.
   Les deux regles avaient la meme specificite et aucune propriete en commun : elles
   s'additionnaient au lieu de s'ecraser, et la ligne de date heritait du `white-space: nowrap`
   des lignes de projet — sur une fenetre de telephone, elle debordait. Releve en revue. */
.accueil__ligne-de-date {
  margin: 0;
  display: flex;
  align-items: center;
  gap: 11px;
}

.accueil__tiret {
  width: 26px;
  height: 4px;
  flex: none;
  display: block;
  background: var(--ef-sun);
}

.accueil__jour {
  font: 700 var(--taille-etiquette)/1 var(--font-body);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* Le titre suit la maquette : il grandit avec la fenetre jusqu'a 48 px, au lieu des 46 px fixes
   qu'il portait. `clamp` evite qu'il deborde sur une fenetre etroite. */
.accueil__bienvenue {
  margin: 0;
  font: 800 clamp(var(--taille-vitrine), 3.8vw, 48px)/1.08 var(--font-heading);
  letter-spacing: -.03em;
}

/* **Le filet est porte par la phrase**, comme dans la maquette : c'est un trait plein au-dessus
   d'elle, et non une bordure de bloc. Sa largeur suit donc celle du texte. */
.accueil__phrase {
  margin: 0;
  font: 500 var(--taille-ecran)/1.6 var(--font-body);
  color: var(--color-neutral-700);
  max-width: 52ch;
  border-top: 2px solid var(--color-text);
  padding-top: 16px;
}

/* M18, seconde moitie — les lignes de reprise de projet, ajoutees le 2026-08-17.

   L'ecran se tient en deux blocs empiles : l'accroche, qui prend la place restante, et la bande
   de reprise, qui prend la sienne. `minmax(0, 1fr)` et non `1fr` : sans le minimum a zero, une
   piste de grille refuse de descendre sous la taille de son contenu, et l'accroche pousserait la
   bande de reprise hors du cadre sur une fenetre courte. */
.accueil {
  min-height: 100%;
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto;
}

/* Les valeurs de la maquette : 56 px de haut et 48 px de cote, 20 px entre les blocs, et une
   hauteur minimale de 340 px pour que le titre garde sa place sur une fenetre courte. */
.accueil__accroche {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 20px;
  padding: 56px 48px;
  min-height: 340px;
}

/* Le bouton ne s'etire pas sur toute la largeur de la colonne : il fait sa taille, a gauche. */
.accueil__accroche .btn {
  align-self: flex-start;
}

.accueil__reprise {
  display: flex;
  flex-direction: column;
  border-top: 2px solid var(--color-text);
  background: var(--color-surface);
}

.accueil__surtitre {
  padding: 13px 20px 11px;
  font: 700 var(--taille-etiquette)/1 var(--font-body);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.accueil__echec {
  margin: 0;
  padding: 0 20px 14px;
  font: 500 var(--taille-texte)/1.5 var(--font-body);
  color: var(--color-neutral-700);
}

/* `display: contents` sur le formulaire : sans lui, il formerait une boite de plus dans la
   colonne, et la ligne cesserait de s'etendre sur toute la largeur de la bande. Meme necessite
   que pour le bouton de sortie du rail, et meme raison — un formulaire par ligne est impose par
   le fait qu'ouvrir modifie l'etat, pas par la mise en page. */
.accueil__ligne-formulaire {
  display: contents;
}

.accueil__ligne {
  width: 100%;
  padding: 12px 20px;
  border: 0;
  border-top: 1px solid var(--color-divider);
  background: transparent;
  color: var(--color-text);
  display: flex;
  align-items: center;
  gap: 14px;
  text-align: left;
  cursor: pointer;
  min-width: 0;
}

.accueil__ligne:hover:not(:disabled) {
  background: var(--color-accent-100);
}

/* Une ligne desactivee est celle du projet **deja en memoire** : la rouvrir le rechargerait pour
   rien. Le curseur par defaut et l'opacite disent que le geste n'est pas disponible ; la marque
   « En memoire », a cote, dit pourquoi. */
.accueil__ligne:disabled {
  cursor: default;
  opacity: .75;
}

/* `min-width: 0` et la coupure : un nom de projet long doit s'abreger, pas pousser la date hors
   de la bande. Un element de flexbox refuse par defaut de descendre sous la taille de son
   contenu, et `overflow: hidden` seul n'y suffit donc pas. */
.accueil__nom-de-projet {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 700 var(--taille-texte)/1.3 var(--font-body);
}

.accueil__marque {
  flex: none;
  padding: 3px 6px;
  background: var(--ef-sun);
  color: var(--color-text);
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  letter-spacing: .12em;
  text-transform: uppercase;
}

/* « Lecture seule » sur une ligne de reprise. **Un contour, et non la pastille pleine** : la
   marque « EN MEMOIRE » juste a cote est deja jaune plein, et deux marques jaunes cote a cote ne
   se distingueraient qu'a la lecture. Elles ne disent pourtant pas la meme chose — l'une est un
   etat, l'autre un avertissement. Le fond pale et le trait ferment la confusion. */
.accueil__marque--lecture-seule {
  background: var(--warn-bg);
  color: var(--warn-ink);
  border: 1px solid currentColor;
  cursor: help;
}

.accueil__date {
  flex: none;
  white-space: nowrap;
  font: 500 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-text-muted);
}

.accueil__vers-la-bibliotheque {
  padding: 12px 20px;
  border-top: 2px solid var(--color-text);
  background: var(--color-bg);
  color: var(--color-text);
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  text-decoration: none;
}

.accueil__vers-la-bibliotheque:hover {
  background: var(--color-accent-100);
}

/* M18 — la connexion en deux moitiés. Jusqu'au 2026-08-15, c'etait le formulaire seul sur fond
   gris : la premiere chose que voit quiconque ouvre EF360, et la seule page dont l'apparence ne
   devait rien a la maquette (`docs/BUGS.md`, symptome 1).

   Les proportions sont celles du dessin — `1fr | 1.1fr`, le formulaire un peu plus large que le
   panneau. Le `minmax(0, …)` n'est pas decoratif : sans lui, une piste de grille refuse de
   descendre sous la taille de son contenu, et le motif en `object-fit: cover` pousserait la
   colonne au-dela de la fenetre. */
.connexion {
  height: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
}

/* La moitie verte. **Deux blocs depuis le 2026-08-23**, la marque et l'accroche : Antoine a fait
   retirer la mention du bas. `space-between` collait alors l'accroche en bas du panneau au lieu
   de la laisser au milieu — un effet de bord que rien ne mesurait, releve en revue. `center`
   remet l'accroche au milieu et garde la marque au-dessus d'elle.

   Le blanc pose ici vaut 11,5:1 sur le vert fonce du theme clair. En theme sombre, l'accent
   devient le vert clair et ce meme blanc tombe a **2,09:1** — mesure du 2026-08-18, inscrite aux
   bugs ouverts. La regle qui suit le corrige, comme celle de `.btn-primary` plus haut. */
.connexion__panneau {
  background: var(--color-accent);
  color: #ffffff;
  padding: 44px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 24px;
  border-right: 2px solid var(--color-text);
  position: relative;
  overflow: hidden;
}

/* **L'encre du panneau de connexion en theme sombre.** Le cookie de theme survit a la
   deconnexion : quelqu'un qui travaille en sombre retrouve cette page en sombre, et c'est la
   premiere qu'il voit. Meme encre que le bouton principal, et pour la meme raison — 8,15:1
   contre 2,09:1. */
[data-theme="sombre"] .connexion__panneau {
  color: #00211d;
}

.connexion__motif {
  opacity: .26;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  pointer-events: none;
}

/* Les trois blocs passent au-dessus du motif, qui est en position absolue. */
.connexion__logo {
  width: 56px;
  height: 56px;
  object-fit: contain;
  background: #ffffff;
  padding: 4px;
  align-self: flex-start;
  position: relative;
  z-index: 2;
}

.connexion__accroche {
  display: flex;
  flex-direction: column;
  gap: 14px;
  position: relative;
  z-index: 2;
}

/* `clamp` repris du dessin : l'accroche suit la largeur de la fenetre sans jamais devenir
   illisible ni ecraser le panneau. */
.connexion__phrase {
  font: 800 clamp(var(--taille-vitrine), 3.4vw, 44px)/1.02 var(--font-heading);
  letter-spacing: -.02em;
}

.connexion__signature {
  font: 600 var(--taille-etiquette)/1 var(--font-body);
  letter-spacing: .18em;
  text-transform: uppercase;
  opacity: .85;
}


/* La moitie du formulaire : centre verticalement, comme le dessin. */
.connexion__cote {
  display: flex;
  align-items: center;
  padding: 44px;
  overflow: auto;
  position: relative;
}

/* Le numero de version, en bas a droite. Demande par Antoine le 2026-08-23, « en gris fonce ».
   `--color-neutral-700`, le gris le plus fonce de la gamme neutre et le seul qui passe le seuil
   de 4,5:1 du produit.

   **Les chiffres d'abord ecrits ici etaient faux** : ils mesuraient contre `--color-surface`, or
   cette moitie de page ne declare aucun fond et herite de `--color-bg`. Releve en revue. Les
   vrais sont 5,83:1 en theme clair et 9,78:1 en sombre — et ils ne sont plus seulement ecrits :
   la suite navigateur les mesure sur la page servie, comme la feuille l'exige partout ailleurs. */
.connexion__version {
  position: absolute;
  right: 16px;
  bottom: 12px;
  color: var(--color-neutral-700);
  font: 500 var(--taille-etiquette)/1.2 var(--font-body);
  letter-spacing: .04em;
}

.connexion__formulaire {
  width: 100%;
  max-width: 380px;
}

/* L'espacement de la maquette : -.015em, soit -0,33 px pour 22 px de corps. Ce titre n'en a
   jamais porte ; il est ajoute ici. La barre de titre en porte un, mais un autre (-.01em). */
.connexion__titre {
  margin: 0 0 16px;
  font: 800 var(--taille-titre)/1.1 var(--font-heading);
  letter-spacing: -.015em;
}

/* `champ` et l'erreur portent une largeur maximale en `ch`, pensee pour un ecran large. Dans
   cette colonne-ci, c'est le formulaire qui borne — sinon les champs seraient plus etroits que le
   bouton, qui prend toute la largeur. */
.connexion__formulaire .champ,
.connexion__formulaire .formulaire__erreur {
  max-width: none;
}

.connexion__aide {
  display: block;
  margin-top: 14px;
  font: 500 var(--taille-etiquette)/1.5 var(--font-body);
  color: var(--color-neutral-700);
}

/* Sous 900 px, les deux moities s'empilent et le panneau se reduit a un bandeau : garder la
   grille couperait le formulaire en deux sur un ecran etroit. La hauteur passe en `auto` pour
   que la page defile au lieu d'ecraser les champs. */
@media (max-width: 900px) {
  .connexion {
    grid-template-columns: 1fr;
    height: auto;
  }

  .connexion__panneau {
    padding: 24px;
    gap: 16px;
    border-right: 0;
    border-bottom: 2px solid var(--color-text);
  }

  .connexion__cote {
    padding: 24px;
  }
}

/* L'erreur d'un formulaire — distincte de l'echelle M15, qui qualifie une action dans
   l'application et non une saisie. Voir l'en-tete de `connexion.html`. **Elle porte le dessin
   commun de l'echec** (chantier 2, revue 01 §3) : un seul rouge pour dire « ca n'a pas marche ». */
.formulaire__erreur {
  margin: 0 0 16px;
  padding: 9px 12px;
  background: var(--message-refus-bg);
  color: var(--message-refus-ink);
  border: 1px solid var(--color-divider);
  border-left: 4px solid var(--etat-bloque);
  border-radius: var(--rayon-bouton);
  font: 600 var(--taille-etiquette)/1.45 var(--font-body);
  max-width: 42ch;
}

/* --------------------------------------------------------- champs et tables */

.champ {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
  margin-bottom: 12px;
  max-width: 42ch;
}

.champ__libelle {
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  letter-spacing: .12em;
  text-transform: uppercase;
}

/* **L'aplat gris de la maquette, pas le fond de page.** Nos champs reprenaient la couleur de la
   page : ils ne se detachaient plus de ce qui les entoure, et sur « General » les deux champs de
   l'identite disparaissaient dans leur section. Releve par Antoine le 2026-08-19, image contre
   image. */
.input {
  width: 100%;
  padding: 9px 10px;
  font: 500 var(--taille-texte)/1.2 var(--font-body);
  border: 1px solid var(--color-divider);
  background: var(--color-surface);
  color: var(--color-text);
  box-sizing: border-box;
}

/* **Sans elle, un champ texte désactivé peut ignorer `font-family` malgré la cascade.** Le
   `font-family` calculé disait bien Archivo — mesuré dans un navigateur —, mais le rendu du
   contrôle natif du système passait outre pour son texte, visible seulement à l'oeil : la bonne
   police à côté de la mauvaise, sur le même écran. Signalé par Antoine le 2026-09-01.

   **`input.input, textarea.input`, et non `.input` seule.** La classe habille aussi deux menus
   déroulants (`select.input` : le fond de carte, la couche choisie) ; leur retirer l'apparence
   native effacerait leur flèche sans rien pour la remplacer, sur deux écrans que cette remarque
   ne visait pas. Relevé en revue le 2026-09-01. */
input.input,
textarea.input {
  appearance: none;
  -webkit-appearance: none;
}

.input:focus {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}

/* **Les champs de date sans classe reprennent l'habillage du produit** (Antoine, 2026-09-22).
   Quatre d'entre eux ne portaient aucune regle et rendaient le controle natif du systeme : fond
   blanc, coins arrondis, police du systeme. Ce sont les deux dates de l'ecran des echanges et les
   deux bornes du rapport d'avancement.

   **`:not([class])`, et c'est la revue du 2026-09-22 qui l'impose.** Un selecteur d'attribut pese
   une classe **plus** un type : `input[type="date"]` seul gagnait donc sur
   `.classeur__creation-champ` et sur `.entites__champ`, et changeait l'aspect de deux champs que
   cette demande ne visait pas. Mesure avant/apres dans un navigateur : le champ du formulaire de
   creation d'une ligne passait de 11,5 px a 13 px et changeait de fond.

   **La police et la taille sont celles du formulaire qui porte le champ**, pas celles de `.input` :
   sur l'ecran des echanges, la date voisine avec un compte rendu a 11 px, et un champ plus gros que
   son voisin immediat se remarque autant qu'un champ mal habille. La graisse redescend a 400 comme
   le fait deja le compte rendu, l'etiquette qui les porte etant en 600.

   **Pas d'`appearance: none`** : sur un champ de date, elle efface le bouton du calendrier, qui est
   le seul moyen de choisir une date a la souris. */
input[type="date"]:not([class]) {
  padding: 6px 8px;
  font: inherit;
  font-weight: 400;
  border: 1px solid var(--color-divider);
  background: var(--color-surface);
  color: var(--color-text);
  box-sizing: border-box;
}

input[type="date"]:not([class]):focus {
  outline: 2px solid var(--color-accent);
  outline-offset: -2px;
}

/* La table declare sa police en entier : sa graisse ne vient donc pas du corps de page, et elle
   suit la meme correction que lui. La maquette laisse ses cellules a 400. */
.table {
  border-collapse: collapse;
  width: 100%;
  font: 400 var(--taille-texte)/1.55 var(--font-body);
}

/* **Une entete de colonne pese moins que la donnee qu'elle nomme.** Elle etait en encre pleine et
   d'un demi-point plus grosse que dans la maquette : le nom de la colonne tirait l'oeil avant son
   contenu. Mesure au navigateur des deux cotes le 2026-09-02 : maquette 9,5 px gris #7D7979, ici
   10 px encre pleine #201E1D.

   **Le gris est celui que la maquette donne a ses tables de consultation.** Le classeur y fait
   exception et garde l'encre pleine : voir `.classeur-table .table th`, plus bas. */
.table th {
  padding: 5px 10px;
  text-align: left;
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  border-bottom: 2px solid var(--color-text);
  background: var(--color-surface);
  position: sticky;
  top: 0;
}

.table td {
  padding: 2px 10px;
  border-bottom: 1px solid var(--color-divider);
}

/* **Une cellule de donnee tient sur une ligne, et la table deborde en largeur.** C'est la
   construction de la maquette, mesuree au navigateur le 2026-09-03 : `nowrap` partout, et le
   cadre qui defile horizontalement. Sans elle, une douzaine de colonnes serrees dans 1 440 px
   font des lignes de 36 a 98 px la ou la maquette en tient 23 — on voyait sept lignes contre
   douze. Les deux cadres defilent deja (`.classeur-table`, `.donnees-table`). La maquette du
   2026-09-26 borne la cellule a 260 px.

   **Les deux tables de donnees seulement.** L'administration et la bibliotheque logent des
   commandes dans certaines cellules ; les mettre sur une ligne les etalerait hors du cadre. Les
   colonnes de ces deux tables qui doivent tenir sur une ligne le declarent deja chacune.

   **Et une cellule trop large se coupe, avec un point de suspension** — c'est la maquette, qui
   borne sa cellule a 340 px et tronque dedans. Antoine a tranche le 2026-09-03 en faveur de la
   troncature ; la fiche de `docs/A_TRANCHER.md` recommandait l'inverse.

   **`max-width` n'est pas la largeur obtenue, et ce n'est pas un defaut.** Sous la disposition de
   table automatique il declare la largeur *souhaitee* d'une colonne, et le navigateur repartit
   ensuite la place restante. Mesure au navigateur, douze colonnes sur 1 440 px : la colonne longue
   tombe de 1 418 a 427 px, la table de 2 240 a 1 404, et le cadre cesse de defiler. **Sans
   `max-width`, `text-overflow` ne fait rien** : la colonne prend la largeur de son texte, et il n'y
   a plus rien qui depasse a couper.

   **La valeur entiere reste lisible au survol de la souris** : les deux gabarits la posent en
   `title` sur la cellule. Cacher une donnee sans aucun moyen de la lire serait le plus couteux des
   deux defauts, et c'est ce que la fiche redoutait.

   **La limite, relevee en revue et assumee :** `title` ne s'ouvre ni au clavier ni au doigt. Sur
   un ecran tactile, et pour qui navigue sans souris, la fin d'une valeur longue reste hors de
   portee. C'est un defaut ouvert (`docs/BUGS.md`), pas un oubli : le rendre atteignable demande un
   mecanisme que la maquette ne dessine pas. */
.donnees-table .table td {
  padding: 0 12px;
  line-height: 27px;
  white-space: nowrap;
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* **La table du classeur borne ses colonnes et revient a la ligne** (Antoine, 2026-09-06) : « une
   largeur de colonne fixe, de l'ordre de celle de PERSPECTIVES_SIGNATURE, et un retour a la ligne
   pour les valeurs longues ». Elle coupait les valeurs a 340 px sur une seule ligne, et le survol
   etait le seul moyen d'en lire le reste.

   **176 px, et voici d'ou vient le nombre** : mesure au navigateur le 2026-09-06, le libelle
   `PERSPECTIVES_SIGNATURE` fait 160 px a la fonte de cette table. On ajoute les 16 px de marge
   interieure de la cellule.

   `overflow-wrap: anywhere` et non `break-word` : une reference cadastrale ou un identifiant sans
   espace ne se coupe pas autrement, et c'est precisement ce que ces colonnes portent. */
/* **La table du classeur garde ses colonnes et defile sur le cote** (Antoine, 2026-09-08 : « je ne
   suis toujours pas satisfait, beaucoup de choses ne ressortent pas »).

   **C'est ici qu'etait la cause principale, et ce n'etait pas la marge interieure.** La table
   etait large de 100 %, donc comprimee pour tenir dans l'ecran : vingt-huit colonnes se
   partageaient 1 440 px, et chaque valeur se cassait sur trois lignes. En disposition fixe, avec
   une largeur qui suit son contenu, chaque colonne garde la sienne et le cadre defile — ce qu'il
   sait deja faire.

   `min-width: 100%` pour qu'un onglet de quatre colonnes remplisse quand meme le cadre.

   **Chaque colonne prend la largeur de son contenu** (doctrine, regle 12 ; Antoine, 2026-10-04),
   en disposition automatique : au moins son titre, au plus 260 px pour un texte, un nombre ou une
   date jamais coupes. Le navigateur ne mesure que la page affichee, cent lignes au plus, jamais
   l'onglet entier. **Une largeur tiree l'emporte** : le script releve alors la largeur de chaque
   colonne, la pose sur le groupe de colonnes et fige la table (`classeur-table__figee`). */
.classeur-table .table {
  table-layout: auto;
  width: max-content;
  min-width: 100%;
}

.classeur-table .table.classeur-table__figee {
  table-layout: fixed;
}

/* Un texte s'arrete a 260 px et finit par « … » ; il se lit en entier au survol, ou en entier dans
   la table avec « Textes longs en entier », qui le replie dans la meme largeur. */
.classeur-case:not(.classeur-case--nombre) .classeur-case__texte,
.classeur-table .table .classeur__entete {
  max-width: 260px;
}

.classeur-table .table td {
  white-space: normal;
  overflow-wrap: anywhere;
  vertical-align: top;
  /* Une rangee sur une ligne (maquette 3.2, 2026-10-03). */
  padding: 5px 10px;
}

/* **Un trait vertical a chaque bord de colonne** (Antoine, 2026-09-21) : « afin de pouvoir plus
   facilement etirer la colonne ». Sur l'ecran du FGF, la poignee de tirage se prend sur ce bord
   et ne se voit pas ; sans le trait, il fallait promener le curseur pour le trouver.

   **Le classeur seul**, et pas les cinq autres tables du produit : lui seul aligne assez de
   colonnes pour qu'on perde la sienne en la lisant. La table du tiroir de la carte rend le meme
   bloc et recoit donc les traits ; elle n'a pas de poignee (`installerLaTableSansGestes`), et
   les traits y servent seulement a lire.

   **La colonne du « + » ne se separe de rien, et c'est la regle qui compte.** La ligne d'en-tete
   porte une cellule de plus que les lignes de donnees — celle du « + » —, et aucune case ne la
   prolonge dans le corps. Un trait pose a ce bord-la existerait dans l'en-tete sans descendre
   d'une seule ligne. **Changer de cote n'y change rien** : `border-right` avec exception sur
   `:last-child` et `border-left` sur `:not(:first-child)` dessinent exactement les memes traits,
   puisque l'asymetrie vient de la case absente, pas du cote choisi. Le seul remede est de viser
   la colonne du « + » par son nom. Releve en revue le 2026-09-21, deux fois.

   **Le meme gris que le trait horizontal**, et pas plus fonce : la grille doit se deviner, pas
   quadriller la lecture. */
.classeur-table .table th:not(:first-child),
.classeur-table .table td:not(:first-child) {
  border-left: 1px solid var(--color-divider);
}

.classeur-table .table th.classeur__ajout-de-colonne {
  border-left: 0;
}

/* **Court par defaut, complet sur demande** (Antoine, 2026-09-06 ; une ligne depuis la maquette
   3.2 du 2026-10-03) : court tient sur une ligne, complet montre tout. Le pli tient sur le texte
   et non sur la cellule — `max-height` est ignore sur une cellule de tableau.

   **Sans une ligne de script** : la case a cocher vit dans la barre, que l'echange htmx de la
   table ne remplace pas, et `:has()` porte le reglage jusqu'ici. Le choix survit donc a chaque
   pagination sans voyager dans l'adresse — une adresse partagee montrerait l'affichage de celui
   qui l'a copiee, ce que le choix des colonnes a deja evite. */
.classeur-case__texte {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  line-clamp: 1;
  overflow: hidden;
}

.classeur:has(.classeur-barre__affichage:checked) .classeur-case__texte {
  display: block;
  overflow: visible;
}

/* Le meme texte se replie dans ses 260 px quand on demande les textes longs en entier. */
.classeur:has(.classeur-barre__affichage:checked) .classeur-case--nombre .classeur-case__texte {
  white-space: normal;
}

/* ------------------------------------------------- indicateur d'attente htmx */

/* Les trois regles de l indicateur d attente d htmx, recopiees telles quelles depuis
   `_n()` de htmx.min.js.

   htmx les injecte normalement lui-meme dans une balise <style> en ligne au demarrage.
   `script-src 'self'` et `style-src 'self'` du proxy (docker/Caddyfile) bloquent cette
   injection : la console affiche une violation a **chaque** chargement de page, et la regle
   `opacity:0` n est pas appliquee — le premier `hx-indicator` pose sur un ecran serait donc
   visible en permanence en production, et parfaitement normal en local. Le meta
   `htmx-config` de base.html coupe l injection ; ces trois lignes la remplacent.

   Le lien avec le fichier vendu est garde par un test
   (`test_les_regles_de_l_indicateur_n_ont_pas_change_dans_le_fichier_vendu`) : un relevement
   qui change ces regles echoue en nommant ce fichier. Sans lui, la copie divergerait en
   silence. Empreintes et procedure : src/web/static/vendor/README.md.

   Une difference avec l injection d htmx, sans consequence aujourd hui : il inserait sa balise
   en fin de <head>, donc APRES toutes les feuilles liees. Ces regles vivent maintenant dans la
   premiere feuille. Le jour ou leaflet.css ou la maquette seront liees apres, une regle de meme
   specificite gagnerait la ou htmx gagnait. */
.htmx-indicator {
  opacity: 0;
}

.htmx-request .htmx-indicator {
  opacity: 1;
  transition: opacity 200ms ease-in;
}

.htmx-request.htmx-indicator {
  opacity: 1;
  transition: opacity 200ms ease-in;
}

/* --------------------------------------------------- lot « peripherie » : aide et mon compte

   Les deux ecrans entres le 2026-08-16. Le style suit le systeme de la maquette — angles vifs,
   filets de 2 px, tout aligne a gauche, aucun arrondi — et n invente aucun jeton : toutes les
   couleurs viennent des variables declarees en tete de ce fichier.

   `ef-chip` est ecrite ici et non dans un fichier a part parce que la maquette l emploie sur les
   deux ecrans et en emploiera d autres : c est une piece du socle, pas de l ecran d aide. */

.ef-chip {
  display: inline-block;
  padding: 3px 8px;
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  letter-spacing: .06em;
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  color: var(--color-text);
}

/* Les deux moities : le FGF en neutre, la cartographie en vert plein a encre claire. Le vert pale
   du « reussi » ne peint plus une categorie (regle 6, revue 01 §4). Le filet reprend le fond pour
   que l'etiquette pleine n'ait pas un liseré plus clair qu'elle. */
.ef-chip--classeur {
  background: var(--void-bg);
  border-color: var(--void-bg);
  color: var(--color-text);
}

.ef-chip--carto {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: #ffffff;
}

/* En theme sombre l'accent devient un vert clair : une encre claire posee dessus disparait. */
[data-theme="sombre"] .ef-chip--carto {
  color: #00211d;
}

/* Les trois etats prennent les trois couleurs du produit, celles des pastilles de la coque. */
.ef-chip--présent {
  background: var(--ok-bg);
  border-color: var(--ok-bg);
  color: var(--ok-ink);
}

.ef-chip--absent {
  background: var(--void-bg);
  border-color: var(--void-bg);
  color: var(--void-ink);
}

.ef-chip--inconnu {
  background: var(--warn-bg);
  border-color: var(--warn-bg);
  color: var(--warn-ink);
}

/* ------------------------------------------------------------------ comment ca marche */

.aide {
  display: flex;
  flex-direction: column;
  gap: 22px;
  max-width: 1180px;
}

/* **24 px en graisse 800**, mesure au navigateur sur la maquette le 2026-09-03 : nous en
   posions 22 en 700, et le titre de cet ecran ne pesait pas plus qu'un intitule de section. */
.aide__titre {
  font: 800 var(--taille-titre)/1.05 var(--font-heading);
  letter-spacing: -.02em;
  margin: 0 0 8px;
}

.aide__phrase {
  font: 500 var(--taille-texte)/1.5 var(--font-body);
  color: var(--color-neutral-700);
  margin: 0;
  max-width: 78ch;
}

/* **Un filet epais sous chaque titre de section**, comme la maquette. Sans lui les sections se
   suivaient sans separation visible, et c'est ce qui donnait a l'ecran son air de liste plate.
   `padding-bottom` et non `margin` : le filet doit toucher le titre, pas flotter sous lui. */
.aide__sous-titre {
  font: 700 var(--taille-bloc)/1.2 var(--font-body);
  color: var(--color-text);
  margin: 0 0 12px;
}

/* Deux colonnes sur un ecran large, une seule quand la place manque. `auto-fit` plutot qu un
   point de rupture en pixels : c est la largeur disponible qui decide, pas une taille d appareil
   supposee — et le rail occupe deja 236 px de la fenetre. */
/* **Les deux moities sont une seule boite, et elles sont colorees.** Releve le 2026-08-19 en
   mettant l'ecran a cote de la maquette : elle pose les deux moities dans un cadre unique,
   separees par un filet, et donne a chaque en-tete sa couleur — vert tres pale pour le classeur,
   vert fonce a encre claire pour la cartographie. Nous avions deux boites grises, ecartees, de
   largeurs differentes. C'est l'incoherence de largeur relevee par Antoine : deux boites
   independantes ne peuvent pas s'aligner, un cadre a deux colonnes si.

   `1fr 1fr` et non `auto-fit` : la maquette donne deux moities de meme largeur, quoi qu'elles
   contiennent. `auto-fit` les faisait dependre de la longueur de leur texte. */
.aide__moities {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}

@media (max-width: 900px) {
  .aide__moities {
    grid-template-columns: minmax(0, 1fr);
  }
}

.aide__moitie {
  border-radius: var(--rayon-cadre);
  background: var(--crm-blanc);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Le filet qui separe les deux moities, porte par la premiere : une bordure sur chacune en
   dessinerait deux, epaisses de deux pixels au milieu. */
.aide__moitie:first-child {
  border-right: 0;
}

@media (max-width: 900px) {
  .aide__moitie:first-child {
    border-right: 0;
    border-bottom: 1px solid var(--color-text);
  }
}

/* L'en-tete colore de chaque moitie. **Les deux couleurs disent laquelle est tenue a la main et
   laquelle est calculee** — c'est le sens que la maquette leur donne, pas une decoration. */
.aide__moitie--classeur .aide__entete {
  background: none;
}

.aide__moitie--carto .aide__entete {
  background: none;
}


.aide__entete {
  padding: 14px 16px 6px;
}

/* **8,5 px et non 9,5**, mesure au navigateur sur la maquette le 2026-09-03. Ces libelles en
   capitales n'annoncent pas, ils etiquettent : d'un point trop gros, ils pesaient autant que ce
   qu'ils surmontent. L'espacement reste a .16em, qui est celui de la maquette. */

/* 19 px en graisse 800, meme mesure. Les deux moities sont les deux objets de l'ecran. */
.aide__nom-moitie {
  font: 800 var(--taille-titre)/1.1 var(--font-heading);
  margin: 0 0 4px;
}

.aide__resume {
  font: 500 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-neutral-700);
  margin: 0;
}

.aide__faits {
  margin: 0;
}

/* Intitule a gauche, valeur a droite — la disposition de la maquette. Empiles, les quatre faits
   doublaient la hauteur de la boite pour la meme matiere. */
.aide__fait {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr);
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--color-divider);
}

.aide__fait:last-child {
  border-bottom: 0;
}

/* Meme mesure : 8,5 px, espacement .12em, interligne 1,3. */
.aide__intitule {
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-text-muted);
  margin: 0;
}

.aide__valeur {
  font: 500 var(--taille-etiquette)/1.45 var(--font-body);
  margin: 0;
}

.aide__technique {
  padding: 4px 0 0;
  font: 500 var(--taille-etiquette)/1.5 var(--font-body);
  color: var(--color-neutral-700);
}

/* **Ni cadre ni fond, et cote a cote** : la maquette pose ces deux sections a meme la page. Les
   enfermer dans deux panneaux gris pleine largeur doublait la hauteur de l'ecran. Releve par
   Antoine, image contre image, le 2026-08-19. */
.aide__colonnes {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 32px;
  align-items: start;
}

@media (max-width: 900px) {
  .aide__colonnes {
    grid-template-columns: minmax(0, 1fr);
  }
}

.aide__correspondance,
.aide__etats {
  font: 500 var(--taille-etiquette)/1.5 var(--font-body);
  color: var(--color-neutral-700);
}

.aide__technique p,
.aide__correspondance p,
.aide__etats p {
  margin: 0 0 10px;
  max-width: 92ch;
}

/* Deux passages de meme largeur, comme les deux moities. `auto-fit` les faisait dependre de la
   longueur de leur texte : le premier etait plus large que le second sans raison, et c'est
   l'incoherence de largeur relevee par Antoine. */
/* La section qui porte le titre **et** le cadre : le titre au-dessus, avec son filet, le cadre
   dessous. Sans elle, le titre serait une cellule de la grille des passages. */
.aide__section-passages {
  display: block;
}

.aide__passages {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (max-width: 900px) {
  .aide__passages {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Le titre de section vit **au-dessus du cadre**, pas dedans : la maquette le pose sur la page,
   avec son filet, et le cadre commence sous lui. Il est donc sorti de la grille par le gabarit ;
   cette regle ne subsiste que pour le cas ou il y retomberait. */
.aide__passages > .aide__sous-titre {
  grid-column: 1 / -1;
}

/* **Un cadre unique a deux colonnes, comme les deux moities du haut** — pas deux boites ecartees.
   La maquette enferme les deux passages dans un seul cadre, separes par un filet interieur : c'est
   ce qui les donne a lire comme les deux faces d'une meme chose. Le filet ne se pose que sur la
   seconde colonne, sinon il doublerait le bord exterieur. */
.aide__passages > .aide__passage {
  border: 0;
  background: var(--crm-blanc);
  padding: 18px;
}

.aide__passages {
  border-radius: var(--rayon-cadre);
  overflow: hidden;
}

.aide__passage + .aide__passage {
  border-left: 1px solid var(--color-divider);
}

/* En une seule colonne, le filet passe du cote gauche au cote haut : autrement il disparait. */
@media (max-width: 900px) {
  .aide__passage + .aide__passage {
    border-left: 0;
    border-top: 1px solid var(--color-divider);
  }
}

.aide__sens {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 0 0 8px;
}

.aide__fleche {
  font: 700 var(--taille-texte)/1 var(--font-body);
  color: var(--color-text-muted);
}

.aide__description {
  font: 500 var(--taille-etiquette)/1.45 var(--font-body);
  color: var(--color-neutral-700);
  margin: 0 0 12px;
}

/* **Une boite pleine, pas un filet.** La maquette marque cette remarque par un aplat creme, un
   petit carre jaune en guise de puce et un texte gras : c'est ce qui la detache du paragraphe
   au-dessus. Notre filet de 3 px se confondait avec le texte courant. */
.aide__note {
  display: flex;
  gap: 10px;
  background: var(--warn-bg);
  color: var(--warn-ink);
  font-weight: 700;
  padding: 12px 14px;
  border-left: 0;
}

.aide__note::before {
  content: "";
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  margin-top: 4px;
  background: var(--ef-sun);
}

/* Le detail rare, replie sous un titre (maquette 3.9, 2026-10-03). */
.aide__repli {
  padding: 12px 18px;
  border-radius: var(--rayon-cadre);
  background: var(--crm-blanc);
}

.aide__repli > summary {
  cursor: pointer;
  font: 600 var(--taille-texte)/1.3 var(--font-body);
}

.aide__repli[open] > summary {
  margin-bottom: 12px;
}

.aide__pastilles {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

/* ------------------------------------------------------------------------- mon compte */

/* Deux colonnes, comme la maquette : la carte d'identite (693 px mesures) a gauche, une colonne
   souple de trois encarts empiles a droite. `align-items: start` empeche la colonne de droite
   de s'etirer a la hauteur de la carte quand elle est plus courte.

   **La premiere colonne est `minmax(0, 693px)` et non `693px`**, et c'est ce qui evite un
   debordement. Le rail prend 236 px et la zone 20 px de marge de chaque cote : une largeur fixe
   de 693 plus la colonne de droite reclamait 991 px, si bien qu'entre 900 et 1 260 px de fenetre
   la colonne de droite sortait de l'ecran — releve en revue, reproduit au navigateur a 1 100 px.
   Avec `minmax`, la carte se retrecit au lieu de pousser sa voisine dehors. */
.compte {
  display: grid;
  grid-template-columns: minmax(0, 693px) minmax(280px, 1fr);
  gap: 18px;
  align-items: start;
  max-width: 1180px;
}

@media (max-width: 900px) {
  .compte {
    grid-template-columns: minmax(0, 1fr);
  }
}

.compte__carte {
  border-radius: var(--rayon-cadre);
  background: var(--crm-blanc);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.compte__colonne-droite {
  display: flex;
  flex-direction: column;
  gap: 18px;
  min-width: 0;
}

/* Les liens du compte dans le cadre commun (maquette 3.8, 2026-10-03). */
.compte__liens {
  display: flex;
  flex-direction: column;
  padding: 4px 18px;
  border-radius: var(--rayon-cadre);
  background: var(--crm-blanc);
}

.compte__lien {
  display: flex;
  justify-content: space-between;
  padding: 12px 0;
  border-bottom: 1px solid var(--color-divider);
  color: var(--color-text);
  font-weight: 600;
  text-decoration: none;
}

.compte__lien:last-child {
  border-bottom: 0;
}

.compte__lien:hover {
  color: var(--color-accent);
}

.compte__personne {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 16px;
  margin: 0;
  border-bottom: 1px solid var(--color-divider);
}

/* Le carre des initiales. **Mesure dans la maquette le 2026-08-19**, pas deduit : 26x26, fond
   #82C46C — la feuille verte, pas l'accent —, encre #00211D, 10 px en graisse 800, aucun rayon.
   Il etait jusque-la de 34 px, en accent vert fonce avec de l'encre blanche : trop gros, trop
   sombre, et illisible en theme sombre (1,86:1, releve en revue). Ces deux jetons-la ne bougent
   pas avec le theme, et c'est voulu : le carre est le meme des deux cotes, comme dans la
   maquette. */
.compte__initiales {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ef-leaf);
  color: var(--color-accent-800);
  font: 800 var(--taille-etiquette)/1 var(--font-body);
  letter-spacing: .04em;
}

.compte__noms {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.compte__nom {
  font: 800 var(--taille-bloc)/1.15 var(--font-heading);
}

.compte__sous-titre {
  font: 500 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-text-muted);
}

/* Les trois faits sur une seule ligne, arbitre par Antoine le 2026-08-19. La grille etait a deux
   colonnes et quatre cases, dont deux ne se rempliraient jamais : elles occupaient la moitie de
   la place avec un « inconnu » et un paragraphe chacune, et les hauteurs de cases ne tombaient
   plus juste. Filet a droite, sauf sur la derniere colonne. */
.compte__faits {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-bottom: 1px solid var(--color-divider);
}

.compte__fait {
  padding: 12px 14px;
  border-right: 1px solid var(--color-divider);
  min-width: 0;
  overflow: hidden;
}

.compte__fait:last-child {
  border-right: 0;
}

/* Sous 640 px, trois colonnes donnent des cases ou un intitule ne tient pas sur une ligne : elles
   se rangent l'une sous l'autre, et c'est le filet du bas qui les separe. */
@media (max-width: 640px) {
  .compte__faits {
    grid-template-columns: minmax(0, 1fr);
  }

  .compte__fait {
    border-right: 0;
    border-bottom: 1px solid var(--color-divider);
  }

  .compte__fait:last-child {
    border-bottom: 0;
  }
}

.compte__intitule {
  font: 600 var(--taille-etiquette)/1 var(--font-body);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: 4px;
}

.compte__valeur {
  font: 600 var(--taille-texte)/1.25 var(--font-body);
  margin: 0;
}

/* La raison d'un fait inconnu, en texte visible sous sa valeur : une infobulle ne se lit ni au
   clavier ni sur un ecran tactile. Discrete, elle explique sans concurrencer la valeur. */
.compte__raison {
  margin: 4px 0 0;
  color: var(--color-text-muted);
  font: 500 var(--taille-etiquette)/1.35 var(--font-body);
}

/* Un fait dont la valeur n a pas pu etre lue se distingue de l oeil : sans cela « inconnu »
   ressemble a une valeur ordinaire, et la regle des trois etats ne se voit plus a l ecran.
   L italique et la couleur portent la difference — jamais la couleur seule. */
.compte__fait--inconnu .compte__valeur {
  font-style: italic;
  font-weight: 500;
  color: var(--color-text-muted);
  cursor: help;
}

.compte__mot-de-passe {
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.compte__sous-titre-section {
  font: 700 var(--taille-bloc)/1.2 var(--font-body);
  margin: 0 0 14px;
}

/* Les deux boutons — enregistrer le mot de passe, se deconnecter — sur une rangee, comme la
   maquette. `flex-wrap` parce que « Se deconnecter » est un libelle long : sur une fenetre
   etroite il passe dessous plutot que de deborder. */
.compte__actions {
  margin: 4px 0 0;
  display: flex;
  gap: 9px;
  flex-wrap: wrap;
}

/* **Pas de filet a gauche de l'introduction.** La maquette n'en met aucun : le titre et sa
   phrase commencent au meme bord que les cadres du dessous. Le filet jaune ajoutait un accent
   que rien ne demandait et decalait le titre de douze pixels par rapport a tout le reste.
   Releve le 2026-08-19 en comparant les deux ecrans. */
.aide__intro {
  margin-bottom: 4px;
}

.compte__formulaire {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* **La taille du texte des panneaux, mesuree dans la maquette le 2026-08-19** : 12 px en graisse
   500, encre #605D5D. Le notre heritait de la taille du corps de page — pres de 15 px en encre
   presque noire —, si bien que les trois panneaux occupaient trois fois leur place et
   concurrencaient la carte d'identite au lieu de l'accompagner. C'est l'ecart de disposition
   qu'Antoine a vu en premier. */
.compte__explication {
  margin: 0;
  font: 500 var(--taille-etiquette)/1.55 var(--font-body);
  color: var(--color-neutral-700);
}

/* ------------------------------------------------------------- M16 bibliotheque */

/* **La maquette validee le 2026-09-26** (`docs/refonte_ui/bibliotheque.html`) : une liste serree,
   une ligne par projet sur une seule hauteur de texte. Le projet en memoire est epingle au-dessus
   de la zone qui defile ; l'en-tete des colonnes y reste fixe ; l'occupation tient dans une barre
   fine en bas. `.application` interdit le defilement du document : c'est la liste qui defile. */
.bibliotheque {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  background: var(--crm-blanc);
  border-radius: 14px;
  overflow: hidden;
  font: 400 var(--taille-texte)/1.5 var(--font-body);
}

.bibliotheque__entete {
  flex: none;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 24px 10px;
}

.bibliotheque__bascule {
  display: flex;
  padding: 3px;
  border-radius: 999px;
  background: var(--color-neutral-100);
}

.bibliotheque__portee {
  padding: 2px 12px;
  border-radius: 999px;
  font: 600 var(--taille-etiquette)/1.5 var(--font-body);
  color: var(--color-neutral-700);
  text-decoration: none;
}

.bibliotheque__portee--active {
  background: var(--crm-blanc);
  color: var(--color-accent);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .08);
}

.bibliotheque__nombre {
  margin-left: 4px;
  font-style: normal;
  font-weight: 500;
  color: var(--color-text-muted);
}

.bibliotheque__recherche {
  position: relative;
  width: 300px;
  margin: 0 0 0 auto;
}

.bibliotheque__champ {
  box-sizing: border-box;
  width: 100%;
  padding: 6px 30px 6px 14px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-100);
  color: var(--color-text);
  font: 400 var(--taille-texte)/1.3 var(--font-body);
}

.bibliotheque__champ:focus {
  outline: 2px solid var(--color-accent-200);
}

/* La croix du navigateur double celle de la maquette : une seule sortie. */
.bibliotheque__champ::-webkit-search-cancel-button {
  display: none;
}

.bibliotheque__effacer {
  position: absolute;
  top: 50%;
  right: 9px;
  transform: translateY(-50%);
  padding: 0 3px;
  font-size: var(--taille-ecran);
  color: var(--color-text-muted);
  text-decoration: none;
}

/* **Une ligne de projet : une seule hauteur de texte, colonnes alignees.** L'en-tete des colonnes
   (`.bibliotheque__tetes`, plus bas) reprend la meme grille, sans quoi les intitules ne
   tomberaient pas au-dessus des valeurs. */
.bibliotheque__ligne {
  display: grid;
  grid-template-columns: minmax(190px, 1fr) 92px 140px 28px;
  gap: 0 12px;
  align-items: center;
  position: relative;
  min-height: 31px;
  padding: 3px 10px;
  border-bottom: 1px solid var(--color-neutral-200);
  font-size: var(--taille-texte);
}

.bibliotheque__ligne:hover {
  background: var(--color-neutral-100);
}

.bibliotheque__ligne > * {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.bibliotheque__ligne > .bibliotheque__gestes,
.bibliotheque__ligne > .bibliotheque__sur-place {
  overflow: visible;
}

.bibliotheque__nom {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

/* **Les gestes suivent le titre, colles a lui** (Antoine, 2026-09-30) : « Ouvrir ▾ » dans la
   liste, « Reserver », « Enregistrer » et « Fermer » sur le projet ouvert. Un bouton ne se coupe
   jamais ; l'etat du projet ouvert cede sa place d'abord, puis le titre et sa pilule ensemble.

   La cellule du nom ne rogne plus : le menu de la reserve s'ouvre sous son bouton, qu'il prend
   pour repere, et deborde donc de la cellule. **Rien d'autre ne doit en deborder** : tout ce
   qu'elle porte hors des boutons se coupe, et la colonne garde la largeur des boutons
   (`minmax(190px, 1fr)`), sans quoi une pilule ou « Fermer » recouvrait la colonne voisine
   (revue du 2026-09-30). */
.bibliotheque__ligne > .bibliotheque__nom {
  overflow: visible;
}

.bibliotheque__nom > .bibliotheque__double,
.bibliotheque__nom > .btn {
  flex-shrink: 0;
}

.bibliotheque__nom > .bibliotheque__double {
  position: relative;
}

.bibliotheque__nom .bibliotheque__menu {
  top: calc(100% + 3px);
  right: auto;
  left: 0;
}

.bibliotheque__nom > .bibliotheque__etat {
  flex-shrink: 1000;
  min-width: 0;
}

.bibliotheque__nom > .bibliotheque__pilule {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.bibliotheque__intitule {
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 600;
}

.bibliotheque__gris {
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

/* Le contenu s'explique au survol : le curseur ne promet pas un lien. */
.bibliotheque__contenu {
  cursor: default;
}

/* **Une date s'aligne a droite, son intitule aussi** (doctrine, regle 12) : la colonne « Modifie »
   le dit par sa nature (`ecran_de_la_bibliotheque.colonnes`). */
.bibliotheque__date,
.bibliotheque__tri--a-droite {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.bibliotheque__pilule {
  flex: none;
  padding: 0 8px;
  border-radius: 999px;
  background: var(--color-neutral-200);
  color: var(--color-neutral-800);
  font: 600 var(--taille-etiquette)/17px var(--font-body);
  cursor: default;
}

/* **Le seul signal jaune de l'ecran** : un FGF charge dont le travail n'est pas enregistre. */
.bibliotheque__pilule--jaune {
  background: var(--warn-bg);
  color: var(--warn-ink);
}

.bibliotheque__pilule--jaune::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 5px;
  border-radius: 50%;
  background: var(--ef-sun);
  vertical-align: 1px;
}

/* Le projet en memoire, epingle hors de la zone qui defile. */
.bibliotheque__epingle {
  flex: none;
  padding: 0 14px 6px;
}

.bibliotheque__ligne--memoire,
.bibliotheque__ligne--memoire:hover {
  padding: 5px 10px;
  border-bottom: 0;
  border-radius: 10px;
  background: var(--color-accent-100);
}

.bibliotheque__ligne--memoire .bibliotheque__intitule {
  font-weight: 700;
}

.bibliotheque__etat {
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

/* La zone qui defile, sous un en-tete fixe. */
.bibliotheque__defile {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: 0 14px 8px;
}

.bibliotheque__tetes {
  display: grid;
  grid-template-columns: minmax(190px, 1fr) 92px 140px 28px;
  gap: 0 12px;
  align-items: center;
  position: sticky;
  top: 0;
  z-index: 2;
  padding: 5px 10px;
  border-bottom: 1px solid var(--color-neutral-200);
  background: var(--crm-blanc);
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.bibliotheque__tri {
  color: inherit;
  text-decoration: none;
}

.bibliotheque__tri:hover {
  color: var(--color-text);
}

.bibliotheque__tri--actif {
  color: var(--color-accent);
  font-weight: 600;
}

/* **Le client et l'equipe, deux colonnes apres le nom** (`docs/refonte_ui/clients_equipe_echanges
   .html`, section 3), pour un compte d'Energie Fonciere.

   **Le client partage avec le nom ce que les colonnes fixes laissent** : 160 px des 1 440 px de
   la maquette, et moins sur un ecran plus etroit, jusqu'a son seul rond. Fixe, il ne laissait
   plus rien au nom sous 1 300 px. 642 px = les cinq colonnes fixes (380), les six gouttieres
   (72) et les 190 px que le nom garde pour ses boutons, plus le statut et la technologie (180
   et deux gouttieres, 2026-10-01) ; la derniere colonne ne porte plus que
   « ⋯ » depuis que les gestes suivent le titre (2026-09-30), et le proprietaire a quitte la
   ligne pour ce menu (2026-10-01). La taille a quitte la ligne le 2026-10-04 (64 px et une
   gouttiere) : 770 px. La date en toutes lettres prend 44 px de plus le 2026-10-04 : 814 px. */
.bibliotheque--avec-l-equipe .bibliotheque__ligne,
.bibliotheque--avec-l-equipe .bibliotheque__tetes {
  grid-template-columns:
    minmax(190px, 1fr) 104px 76px clamp(18px, calc((100% - 814px) * 0.4), 160px)
    100px 92px 140px 28px;
}

/* Un intitule trop long pour sa colonne se coupe, comme les valeurs, au lieu de deborder sur la
   suivante. */
.bibliotheque--avec-l-equipe .bibliotheque__tetes > * {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.bibliotheque__client {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.bibliotheque__client-nom {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Le rond du client, plus petit que sur le General : la teinte vient de `crm-teinte-N`. */
/* **Le rond reste rond, et trois caracteres s'ecrivent plus petit** (Antoine, 2026-10-04, qui
   n'a pas voulu du rond allonge). 20 px et non 18 : en 18, trois lettres ne tenaient qu'en 7 px. */
.bibliotheque__rond {
  width: 20px;
  height: 20px;
  padding: 0;
  box-sizing: border-box;
  border-radius: var(--rayon-pilule);
  display: inline-grid;
  place-items: center;
  flex: none;
  background: var(--crm-fond);
  color: var(--crm-encre);
  font: 700 var(--taille-etiquette) var(--font-body);
  font-style: normal;
}

/* Les pastilles vertes du General, serrees l'une sur l'autre. **Trois pixels de recouvrement
   et non six** : a six, la bordure blanche mangeait la seconde initiale de la pastille d'avant. */
.bibliotheque__equipe {
  display: flex;
  align-items: center;
}

/* Prefixees par la case : `.general__pastille`, plus bas dans la feuille, l'emporterait sinon. */
.bibliotheque__equipe .bibliotheque__pastille {
  box-sizing: border-box;
  width: 22px;
  height: 22px;
  margin-left: -3px;
  border: 2px solid var(--crm-blanc);
  /* Les initiales d'un collaborateur, un peu plus petites (Antoine, 2026-10-04 ; derogation a la
     regle 2). */
  font-size: 11px;
  cursor: default;
}

.bibliotheque__equipe .bibliotheque__pastille:first-child {
  margin-left: 0;
}

/* Sa propre pastille, en vert plein. */
.bibliotheque__equipe .bibliotheque__pastille--moi {
  background: var(--color-accent);
  color: var(--crm-blanc);
}

.bibliotheque__reste {
  margin-left: 4px;
  font: 600 var(--taille-etiquette) var(--font-body);
  color: var(--color-text-muted);
  cursor: default;
}

/* Les deux gestes d'une ligne, a la hauteur du texte. */
.bibliotheque__gestes {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 4px;
}

/* « Ouvrir ▾ » et « Enregistrer ▾ » : deux boutons communs accoles, la fleche portant le menu. */
.bibliotheque__double {
  display: inline-flex;
  align-items: stretch;
  margin: 0;
}

.bibliotheque__avant-fleche {
  padding-right: 8px;
  border-radius: var(--rayon-bouton) 0 0 var(--rayon-bouton);
}

.bibliotheque__fleche {
  padding-left: 5px;
  padding-right: 7px;
  border-left: 0;
  border-radius: 0 var(--rayon-bouton) var(--rayon-bouton) 0;
}

/* **Le menu d'un intitule** (Antoine, 2026-10-05) : sous l'intitule, cale sur son bord, celui de
   droite pour une colonne alignee a droite. L'intitule se coupe lui-meme, et non sa boite, qui
   couperait le menu. */
.bibliotheque__colonne {
  position: relative;
  min-width: 0;
}

.bibliotheque--avec-l-equipe .bibliotheque__tetes > .bibliotheque__colonne {
  overflow: visible;
}

.bibliotheque__colonne > summary {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  cursor: pointer;
}

.bibliotheque__colonne--a-droite > summary {
  text-align: right;
}

.bibliotheque__tri--filtre {
  color: var(--color-accent);
}

.bibliotheque__entonnoir {
  width: 12px;
  height: 12px;
  vertical-align: -1px;
}

.bibliotheque__menu.bibliotheque__menu-de-colonne {
  top: calc(100% + 4px);
  right: auto;
  left: 0;
  min-width: 180px;
}

.bibliotheque__colonne--a-droite > .bibliotheque__menu-de-colonne {
  right: 0;
  left: auto;
}

.bibliotheque__filtre-de-colonne {
  display: grid;
  gap: 2px;
  padding: 4px;
}

.bibliotheque__case-du-filtre {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 7px;
  color: var(--color-text);
  font-size: var(--taille-texte);
  white-space: nowrap;
  cursor: pointer;
}

.bibliotheque__filtre-de-colonne > .btn {
  justify-self: start;
  margin-top: 4px;
}

.btn-primary.bibliotheque__fleche {
  border-left: 1px solid color-mix(in srgb, var(--color-bg) 30%, transparent);
}

.bibliotheque__deroulant > summary {
  list-style: none;
}

.bibliotheque__deroulant > summary::-webkit-details-marker {
  display: none;
}

/* « ⋯ » : un bouton discret carre de 28 px, la cible que la ligne lui doit. */
.bibliotheque__plus {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  box-sizing: border-box;
}

.bibliotheque__deroulant[open] > .bibliotheque__plus {
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
}

/* Le proprietaire du projet, en tete du menu « ⋯ » : un fait, pas un geste. */
.bibliotheque__proprietaire-du-menu {
  padding: 6px 10px 4px;
  color: var(--color-text-muted);
  font-size: var(--taille-texte);
  white-space: nowrap;
}

/* Le menu se place sous la ligne, a droite : la ligne est positionnee, le menu la prend pour
   repere. */
.bibliotheque__menu {
  position: absolute;
  top: calc(100% - 2px);
  right: 10px;
  z-index: 3;
  display: grid;
  gap: 1px;
  min-width: 200px;
  padding: 6px;
  border-radius: 14px;
  background: var(--crm-blanc);
  box-shadow: 0 4px 16px rgba(0, 0, 0, .14);
  font-size: var(--taille-texte);
}

.bibliotheque__choix {
  display: flex;
  justify-content: space-between;
  gap: 18px;
  padding: 5px 11px;
  border: 0;
  border-radius: 9px;
  background: transparent;
  color: var(--color-text);
  font: 400 var(--taille-texte)/1.5 var(--font-body);
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.bibliotheque__choix:hover {
  background: var(--color-neutral-100);
}

.bibliotheque__choix--defaut,
.bibliotheque__choix--en-cours {
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-weight: 600;
}

.bibliotheque__choix[disabled],
.bibliotheque__choix[disabled]:hover {
  background: transparent;
  color: var(--color-text-muted);
  cursor: not-allowed;
}

.bibliotheque__mention {
  font-style: normal;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.bibliotheque__separateur {
  margin: 4px 6px;
  border: 0;
  border-top: 1px solid var(--color-neutral-200);
}

/* Ce qui s'ouvre sur la ligne : restaurer, enregistrer sous un nom. */
/* « La copie part sans ses photos. », sous le champ du nom (2026-09-27). */
.bibliotheque__sans-photos {
  flex-basis: 100%;
  color: var(--color-neutral-700);
}

.bibliotheque__sur-place {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0;
  padding: 5px 0 3px;
}

.bibliotheque__puce {
  padding: 0 10px;
  border: 1px solid var(--color-neutral-300);
  border-radius: 999px;
  background: var(--crm-blanc);
  color: var(--color-neutral-800);
  font-size: var(--taille-etiquette);
  line-height: 19px;
  text-decoration: none;
}

.bibliotheque__puce--choisie {
  border-color: var(--color-accent-200);
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-weight: 600;
}

.bibliotheque__nom-neuf {
  width: 280px;
  padding: 2px 12px;
  border: 0;
  border-radius: 999px;
  background: var(--crm-blanc);
  box-shadow: 0 0 0 1px var(--color-neutral-300);
  color: var(--color-text);
  font: 400 var(--taille-etiquette)/1.5 var(--font-body);
}

.bibliotheque__nom-neuf:focus {
  outline: 2px solid var(--color-accent-200);
}

.bibliotheque__etiquette {
  margin-right: 2px;
  font-size: var(--taille-etiquette);
  color: var(--color-neutral-700);
}

.bibliotheque__pousse {
  flex: 1;
}

.bibliotheque__ligne--a-supprimer,
.bibliotheque__ligne--a-supprimer:hover {
  background: var(--message-refus-bg);
}

/* Pendant la confirmation, l'avertissement, « Garder » et « Supprimer définitivement » prennent
   la place des colonnes : seul le nom du projet reste, pour dire ce qui va partir. */
.bibliotheque__ligne--a-supprimer > .bibliotheque__gestes {
  grid-column: 2 / -1;
}

/* **L'avertissement ne se coupe pas** : les colonnes fixes n'y suffisent pas, la ligne passe donc
   à deux pistes, le nom et ce qui l'efface. */
.bibliotheque__ligne.bibliotheque__ligne--a-supprimer {
  grid-template-columns: minmax(0, 1fr) auto;
}

.bibliotheque__avertissement {
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--message-refus-ink);
  font-size: var(--taille-etiquette);
  font-weight: 600;
}

.bibliotheque__echec {
  margin: 0;
  padding: 14px 10px;
  color: var(--refus-bg);
  font-size: var(--taille-texte);
  font-weight: 600;
}

.bibliotheque__cause {
  color: var(--color-neutral-800);
  font-weight: 400;
}

/* Le pied : ce que la liste montre, et le disque pour un administrateur. */
/* Le lien vers les projets supprimés, sous le pied : un geste rare, qui ne doit pas s'y mêler. */
.bibliotheque__supprimes {
  flex: none;
  margin: 0;
  padding: 6px 26px;
}

.bibliotheque__pied {
  flex: none;
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 9px 26px;
  border-top: 1px solid var(--color-neutral-200);
  background: var(--color-neutral-100);
  font-size: var(--taille-etiquette);
  color: var(--color-neutral-700);
}

.bibliotheque__pied b {
  color: var(--color-text);
  font-weight: 600;
}

.bibliotheque__disque {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}

/* **Un `<progress>` et non deux `<span>` imbriques** : `style-src 'self'` interdit l'attribut
   `style`, et l'element natif porte sa valeur dans un attribut. */
.bibliotheque__jauge {
  width: 140px;
  height: 6px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-300);
  overflow: hidden;
  appearance: none;
}

.bibliotheque__jauge::-webkit-progress-bar {
  background: var(--color-neutral-300);
}

.bibliotheque__jauge::-webkit-progress-value {
  border-radius: 999px;
  background: var(--color-accent-500);
}

.bibliotheque__jauge::-moz-progress-bar {
  border-radius: 999px;
  background: var(--color-accent-500);
}

/* La zone de dépôt de l'écran d'import : le cadre en pointillés, sa phrase, et le choix de
   fichier ordinaire à l'intérieur. Le glissement demanderait du script ; le cadre non. */
.depot {
  border: 2px dashed var(--color-divider);
  background: var(--color-bg);
  padding: 20px;
  gap: 6px;
}

.depot__invite {
  font-size: var(--taille-texte);
  font-weight: 600;
  line-height: 1.3;
}

.depot__note {
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
  font-weight: 500;
  line-height: 1.4;
}

/* ------------------------------------------------- page de confirmation destructrice */

.confirmation {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 680px;
}

.confirmation__faits {
  margin: 0;
  border: 2px solid var(--color-text);
}

.confirmation__fait {
  display: flex;
  gap: 12px;
  padding: 9px 14px;
  border-bottom: 1px solid var(--color-divider);
}

.confirmation__fait:last-child {
  border-bottom: 0;
}

.confirmation__intitule {
  margin: 0;
  width: 168px;
  flex: none;
  font: 700 var(--taille-etiquette)/1.4 var(--font-body);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* **Le même intitulé, posé sur un label plutôt que sur un `dt`.** La largeur fixe de 168 px sert
   à aligner les faits en deux colonnes ; au-dessus d'un champ, elle couperait le libellé. */
.confirmation__intitule--champ {
  display: block;
  width: auto;
}

.confirmation__valeur {
  margin: 0;
  font: 600 var(--taille-texte)/1.4 var(--font-body);
}

.confirmation__formulaire {
  margin: 0;
}

/* **Le champ de la seule confirmation qui en porte un** : corriger un identifiant demande de dire
   par quoi. Même dessin que les champs de la vue par entité, pour que les deux endroits où l'on
   corrige une identité se ressemblent. */
.confirmation__champ {
  width: 100%;
  max-width: 360px;
  margin: 6px 0 14px;
  padding: 6px 8px;
  border: 1px solid var(--color-neutral-300);
  border-radius: 4px;
  background: var(--color-surface);
  color: var(--color-neutral-900);
  font: 400 var(--taille-texte)/1.4 var(--font-body);
}

/* **L'ordre de toute confirmation** (chantier 2, 2026-10-02) : la sortie sans dommage a gauche, en
   secondaire, le geste a droite. */
.confirmation__actions {
  margin: 0;
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
}

.confirmation__actions > .btn-secondary:first-child {
  margin-right: auto;
}

/* ------------------------------------------------- le suivi d'un travail long */

/* **Un seul dessin pour suivre un travail long** (chantier 2, 2026-10-02, revue 06 §1) : le
   panneau d'un outil, « Calculer ou mettre a jour » et le suivi des operations partagent ce
   cadre. Le titre nomme le travail, la pastille dit son etat, le pied range les gestes : le
   discret a gauche, l'action qui suit a droite. */
.suivi {
  border: 1px solid var(--color-divider);
  border-radius: var(--rayon-cadre);
  background: var(--color-surface);
  padding: 14px;
}

.suivi__tete {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 12px;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.suivi__titre {
  margin: 0;
  font: 700 var(--taille-bloc)/1.3 var(--font-heading);
}

.suivi__duree {
  margin: 0 0 6px;
  font-size: var(--taille-texte);
  color: var(--color-text-muted);
}

.suivi__pied {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-end;
  margin: 12px 0 0;
}

.suivi__pied > .btn-ghost:first-child,
.suivi__pied > form:first-child:has(.btn-ghost) {
  margin-right: auto;
}

/* **La garde de « Compris »** (revue 06 §6) : la question, la sortie sans dommage, puis le geste
   qui efface, sur une ligne qui passe a la suivante quand la place manque. */
.suivi__garde {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.suivi__garde[hidden] {
  display: none;
}

.suivi__question {
  margin: 0;
}

/* **La pastille prend la variable de son etat** : en cours, reussi, echoue. Le point de couleur
   la dit, son mot la dit sans la couleur. */
.pastille-etat {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--pastille-etat) 14%, transparent);
  color: var(--color-text);
  font: 600 var(--taille-etiquette)/1 var(--font-body);
}

.pastille-etat::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 999px;
  background: var(--pastille-etat);
}

.pastille-etat--en-cours {
  --pastille-etat: var(--etat-en-cours);
}

.pastille-etat--reussi {
  --pastille-etat: var(--etat-acquis);
}

.pastille-etat--echoue {
  --pastille-etat: var(--etat-bloque);
}

.pastille-etat--inconnu {
  --pastille-etat: var(--etat-neutre);
}

/* La liste des sauvegardes proposées à la restauration (2026-08-24).

   **Une liste de choix et non un menu déroulant** : on doit voir d'un coup ce qui est disponible,
   c'est la question qu'on se pose en arrivant sur cette page. Les mesures suivent celles des
   faits juste au-dessus, pour que les deux blocs se lisent comme un seul. */
.confirmation__choix {
  margin: 0;
  padding: 9px 14px;
  border: 2px solid var(--color-text);
  border-top: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.confirmation__option {
  display: flex;
  gap: 10px;
  align-items: center;
  font: 600 var(--taille-texte)/1.4 var(--font-body);
  cursor: pointer;
}

/* Ce que la page dit quand elle n'a rien à proposer, et quand elle n'a pas pu lire. Les deux se
   ressemblent à l'écran et ne veulent pas dire la même chose : la seconde prend la teinte du
   refus, la première reste neutre — il n'y a pas d'anomalie à n'avoir aucune sauvegarde. */
.confirmation__vide {
  margin: 0 0 14px;
  font: 500 var(--taille-texte)/1.5 var(--font-body);
  color: var(--color-neutral-700);
}

.confirmation__cause {
  margin: 0 0 14px;
  font: 600 var(--taille-texte)/1.5 var(--font-body);
  color: var(--refus-ink);
}

/* Ce qu'une confirmation explique avant son bouton, en pleine lisibilité : ce qu'un
   enregistrement coupé a laissé, ce qu'un recalcul ne rafraîchira pas. */
.confirmation__phrase {
  margin: 0 0 14px;
  font: 500 var(--taille-texte)/1.6 var(--font-body);
  color: var(--color-neutral-800);
}

/* ------------------------------------------------- la barre « Défaire »

   Chantier 1 de la passe d'interface (2026-10-02) : un retrait agit aussitôt, puis la barre dit
   ce qui est parti et propose « Défaire » le temps de son décompte. **Dans le flux, sous la zone
   touchée** : elle pousse ce qui suit et ne couvre jamais une valeur (Antoine). L'encre et le
   fond s'inversent, pour qu'elle se lise comme un état passager et non comme un bloc de l'écran.
   Le filet vert du bas décompte la durée que `ef360.js` pose (`--duree-du-defaire`). */
.defaire {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 8px 0;
  padding: 9px 12px;
  border-radius: var(--rayon-bouton);
  background: var(--color-text);
  color: var(--color-bg);
  font: 600 var(--taille-texte)/1.35 var(--font-body);
  overflow: hidden;
}

.defaire::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 3px;
  background: var(--ef-leaf);
  transform-origin: left;
  animation: defaire-decompte var(--duree-du-defaire, 8s) linear forwards;
}

@keyframes defaire-decompte {
  to {
    transform: scaleX(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .defaire::after {
    animation: none;
  }
}

.defaire__texte {
  min-width: 0;
  overflow-wrap: anywhere;
}

.defaire__geste {
  display: contents;
}

.defaire__bouton {
  flex: none;
  margin-left: auto;
  min-height: 32px;
  padding: 0 12px;
  border: 1px solid color-mix(in srgb, var(--color-bg) 45%, transparent);
  border-radius: var(--rayon-bouton);
  background: transparent;
  color: var(--color-bg);
  font: 700 var(--taille-etiquette)/1 var(--font-body);
  cursor: pointer;
}

.defaire__bouton:hover,
.defaire__bouton:focus-visible {
  background: color-mix(in srgb, var(--color-bg) 18%, transparent);
}

/* ------------------------------------------------- écran « Enregistrer le projet »

   Deux gestes séparés sur une même page. La séparation est **visuelle autant que technique** :
   chacun vit dans son cadre, avec son titre et sa phrase d'explication, pour qu'on ne confonde
   pas « mettre à jour là d'où le projet vient » et « en faire une copie chez soi ». Les faits
   affichés en haut reprennent les classes de la page de confirmation : c'est la même liste de
   couples intitulé/valeur, et la redéfinir donnerait deux mises en forme du même objet. */

.enregistrement {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 680px;
}

.enregistrement__vide {
  margin: 0;
  font: 500 var(--taille-etiquette)/1.5 var(--font-body);
  color: var(--color-neutral-700);
}

/* **Le meme squelette de panneau que le reste du produit** : un bandeau de titre separe du
   corps par un filet, et non un titre pose dans la boite. Ces deux ecrans etaient les derniers a
   avoir leur propre grammaire, et c'est exactement l'incoherence de cadres qu'Antoine a relevee
   le 2026-08-19. */
.enregistrement__geste {
  border: 2px solid var(--color-text);
  display: flex;
  flex-direction: column;
}

.enregistrement__titre {
  margin: 0;
  padding: 11px 14px;
  border-bottom: 2px solid var(--color-text);
  font: 700 var(--taille-texte)/1.2 var(--font-heading);
  letter-spacing: .01em;
}

/* Le corps du panneau prend son ecart lateral, et ses elements respirent entre eux. Ecrit en
   marges plutot qu'en `gap` : le bandeau de titre est un enfant direct, et un `gap` l'ecarterait
   du filet qu'il porte. */
.enregistrement__geste > *:not(.enregistrement__titre) {
  margin-left: 14px;
  margin-right: 14px;
}

.enregistrement__geste > .enregistrement__titre + * {
  margin-top: 12px;
}

.enregistrement__geste > *:not(.enregistrement__titre) + *:not(.enregistrement__titre) {
  margin-top: 12px;
}

.enregistrement__geste > *:last-child {
  margin-bottom: 14px;
}

.enregistrement__explication {
  margin: 0;
  font: 500 var(--taille-etiquette)/1.5 var(--font-body);
  color: var(--color-neutral-700);
}

.enregistrement__formulaire {
  margin: 0;
}

/* ------------------------------------------------------------- M17 administration

   Cinq sections, chacune dans un onglet. **Le filet de 2 px et les angles droits de ces regles
   sont precises plus bas** par le style des ecrans refaits (maquette du 2026-09-29) : les
   classes partagees gardent ici leur forme d'origine.

   Les trois gravites d'alerte reprennent les jetons deja poses (ok / warn / refus) plutot que
   d'en inventer : trois familles de couleurs de plus sur la meme page seraient trois conventions
   a tenir accordees a la main. */

/* --- La rangee des quatre chiffres du haut ------------------------------------------------
   La maquette pose un seul cadre decoupe en quatre par des filets verticaux, pas quatre cartes
   flottantes. Une grille de quatre colonnes egales, un filet a gauche de chaque colonne sauf la
   premiere : c'est exactement ce dessin, et la rangee reste d'un bloc si un chiffre manque. */
.administration__chiffres {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border: 2px solid var(--color-text);
  background: var(--color-neutral-100);
}

.administration__chiffre {
  padding: 13px 16px;
  border-left: 2px solid var(--color-text);
}

.administration__chiffre:first-child {
  border-left: 0;
}

.administration__chiffre-surtitre {
  display: block;
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-text-muted);
}

.administration__chiffre-valeur {
  display: block;
  margin-top: 6px;
  font: var(--font-heading-weight) var(--taille-vitrine)/1.2 var(--font-heading);
  color: var(--color-text);
}

/* La seconde moitie du chiffre, ecrite dessous en petit : « 90 % occupes » sous « 26,3 / 250 Go ».
   Elle ne prend jamais la place du chiffre lui-meme, qui doit se lire de loin. */
.administration__chiffre-precision {
  display: block;
  margin-top: 3px;
  font: 500 var(--taille-etiquette)/1.35 var(--font-body);
  color: var(--color-text-muted);
}

/* Un chiffre qu'on n'a pas su lire ne doit pas avoir l'allure d'un chiffre : il perd la graisse
   du titre et prend le gris de l'absence. Sans quoi « ? » se lirait comme une valeur. */
.administration__chiffre-valeur--inconnu {
  font: 600 var(--taille-vitrine)/1.2 var(--font-heading);
  color: var(--color-text-muted);
}

/* --- Les listes de fiches -----------------------------------------------------------------
   Le motif que la maquette emploie pour les projets confies et pour les signalements : une
   fiche par ligne, un filet de couleur a gauche, ce qu'on cherche en titre et le reste en note
   dessous, l'action a droite. Un tableau a six colonnes dont quatre tiennent une seule valeur
   donne la meme hauteur, mais etale sur toute la largeur — et ce qu'on cherche s'y lit au meme
   poids que la date.

   **Ecrit ici et non sous `.administration`** : deux ecrans l'emploient deja, et un troisieme
   suivra. Une classe prefixee par un ecran serait recopiee au premier reemploi. */
.liste-de-fiches {
  margin: 0;
  padding: 0;
  list-style: none;
  border: 2px solid var(--color-text);
}

.fiche {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 14px 9px 0;
  border-bottom: 1px solid var(--color-divider);
}

.fiche:last-child {
  border-bottom: 0;
}

/* Le filet de gauche, qui donne son rythme a la liste. Il est decoratif : ce qu'il dit est
   ecrit dans la fiche, jamais porte par la seule couleur. */
.fiche__filet {
  flex: 0 0 auto;
  align-self: stretch;
  width: 4px;
  background: var(--color-accent-300);
}

.fiche__corps {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  flex: 1 1 auto;
}

.fiche__titre {
  font: 700 var(--taille-texte)/1.35 var(--font-body);
  color: var(--color-text);
}

.fiche__note {
  font: 500 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-text-muted);
}

/* Un signalement referme : le filet s'eteint, et la fiche le redit en toutes lettres. */
.fiche__filet--eteint {
  background: var(--color-neutral-400);
}

.fiche__etat {
  align-self: flex-start;
  padding: 1px 6px;
  background: var(--color-neutral-200);
  color: var(--color-neutral-700);
  font: 700 var(--taille-etiquette)/1.5 var(--font-body);
  letter-spacing: .04em;
  text-transform: uppercase;
}

.administration__precision {
  font: 500 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-text-muted);
}

/* Les deux boutons du filtre, pousses a droite de l'en-tete comme la maquette les pose. */
.administration__filtres {
  display: flex;
  gap: 6px;
  margin-left: auto;
}

/* Le filtre choisi porte `.btn-primary`, le reste `.btn-secondary` : **les classes de bouton
   elles-memes, et non une couleur reposee ici**. Reposer l'accent a la main reintroduirait le
   defaut que `.btn-primary` documente — en theme sombre l'accent devient un vert clair sur
   lequel le blanc ne se lit plus. Ne reste ici que ce qu'un lien doit perdre pour ressembler a
   un bouton. */
.administration__filtre {
  text-decoration: none;
}

.fiche__geste {
  margin: 0;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
}

/* --- Le bandeau des demandes en attente ---------------------------------------------------
   Aucun courriel n'est envoye : ce bandeau est le seul endroit ou une demande en attente se
   signale, quel que soit l'onglet ouvert. Une demande attend un geste : elle prend l'etat « a
   surveiller », plus le jaune de la marque (revue 06 §11). */
.administration__bandeau {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 10px 14px;
  border: 2px solid var(--etat-a-surveiller);
  background: var(--message-attention-bg);
}

.administration__bandeau-puce {
  width: 9px;
  height: 9px;
  flex: 0 0 auto;
  background: var(--etat-a-surveiller);
}

.administration__bandeau-texte {
  font: 700 var(--taille-texte)/1.35 var(--font-body);
  color: var(--message-attention-ink);
}

.administration__bandeau-note {
  font: 500 var(--taille-etiquette)/1.35 var(--font-body);
  color: var(--color-neutral-700);
}

.administration__bandeau .btn {
  margin-left: auto;
}

/* --- Les cinq onglets ---------------------------------------------------------------------
   Ce sont des liens, pas des boutons : l'onglet ouvert vit dans l'adresse, donc il se partage,
   il se met en signet et le bouton « precedent » du navigateur y revient. Meme motif que les
   onglets de l'exploration du classeur. */
.administration__onglets {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  flex-wrap: wrap;
  border-bottom: 2px solid var(--color-neutral-300);
}

.administration__onglet {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 13px;
  margin-bottom: -2px;
  border-bottom: 3px solid transparent;
  font: 600 var(--taille-texte)/1.3 var(--font-body);
  color: var(--color-text-muted);
  text-decoration: none;
}

.administration__onglet:hover {
  color: var(--color-text);
}

.administration__onglet--actif {
  color: var(--color-text);
  font-weight: 700;
  border-bottom-color: var(--color-accent);
}

/* Le compte de l'onglet : une pastille, pas un nombre entre parentheses. Elle reste lisible en
   theme sombre parce qu'elle reprend les jetons neutres, qui s'inversent avec le theme. */
.administration__onglet-compte {
  padding: 1px 6px;
  background: var(--color-neutral-200);
  color: var(--color-neutral-700);
  font: 700 var(--taille-etiquette)/1.5 var(--font-body);
}

/* La marque ne dit pas « onglet ouvert », elle dit « quelqu'un attend une reponse » : l'etat a
   surveiller. Deux demandes en attente appellent un geste ; quatorze acces exterieurs sont un
   etat. */
.administration__onglet-compte--a-traiter {
  background: var(--message-attention-bg);
  color: var(--message-attention-ink);
}

.administration__section {
  border: 2px solid var(--color-text);
}

.administration__entete {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 11px 14px;
  border-bottom: 2px solid var(--color-text);
}

/* **Le titre de section, a la taille de la maquette.** Elle l'ecrit en petites capitales
   espacees — 9,5 px, graisse 700, 0,16 em d'interlettrage —, la meme forme que les titres de
   section des autres ecrans. Le notre etait un titre de 13 px sans interlettrage : deux ecrans
   voisins n'annoncaient pas leurs sections de la meme facon. Mesure le 2026-08-19. */
.administration__titre {
  margin: 0;
  font: 700 var(--taille-bloc)/1.2 var(--font-body);
}

/* Le compteur des demandes : c'est le seul signal qu'une demande attend, aucun courriel n'est
   envoye. Il porte donc l'etat « a surveiller ». */
.administration__compteur {
  margin-left: auto;
  padding: 2px 8px;
  background: var(--message-attention-bg);
  color: var(--message-attention-ink);
  font: 700 var(--taille-etiquette)/1.4 var(--font-body);
  letter-spacing: .06em;
  text-transform: uppercase;
}

.administration__table {
  margin: 0;
}

/* Ce qu'une section n'a pas pu lire, et ce qu'elle n'a rien a montrer : deux tons distincts.
   Une cause d'echec en gris clair se confondrait avec « vide », qui est une reponse valable ;
   elle prend donc le dessin de l'echec (revue 06 §11). */
.administration__cause {
  margin: 0;
  padding: 10px 14px;
  background: var(--message-refus-bg);
  color: var(--message-refus-ink);
  font: 500 var(--taille-etiquette)/1.4 var(--font-body);
}

.administration__vide {
  margin: 0;
  padding: 10px 14px;
  color: var(--void-ink);
  font: 500 var(--taille-etiquette)/1.45 var(--font-body);
}

.administration__raison {
  margin: 8px 0 0;
  color: var(--color-text-muted);
  font: 500 var(--taille-etiquette)/1.4 var(--font-body);
}

/* « Creer un compte » : un pliage natif dont la poignee a l'apparence d'un bouton. La maquette
   dessine un bouton qui ouvre une boite de dialogue ; l'ouvrir demanderait du script, que la
   politique de securite interdit. Meme motif que le depliable « Code couleur » du classeur. */
/* La maquette pose « Creer un compte » a droite de l'en-tete de section, pas sous elle. Le
   formulaire s'ouvre dessous, aligne sur le bouton — l'en-tete passe alors a la ligne. */
.administration__creation {
  margin-left: auto;
}

/* Les couleurs viennent de `.btn-primary`, portee par le meme element : en theme sombre l'accent
   devient un vert clair sur lequel le blanc ne se lit plus, et `.btn-primary` porte deja
   l'inversion. Ne rien reposer ici, sinon le defaut revient. */
.administration__creation-titre {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  list-style: none;
}

.administration__creation-titre::-webkit-details-marker {
  display: none;
}

/* La marque d'etat est dessinee par du texte, pas par une image : « + » ferme, « − » ouvert. */
.administration__creation-titre::before {
  content: "+";
  font-weight: 700;
}

.administration__creation[open] .administration__creation-titre::before {
  content: "\2212";
}

.administration__creation .administration__formulaire {
  margin-top: 10px;
}

/* La note d'usage sous le formulaire de creation. **Sa propre classe** : `administration__raison`
   dit une raison d'absence, ce que celle-ci n'est pas — et la partager desarmait le controle qui
   verifie que la phrase de presence precede le tableau. Releve en revue. */
.administration__note-de-creation {
  margin: 10px 0 0;
  color: var(--color-text-muted);
  font: 500 var(--taille-etiquette)/1.4 var(--font-body);
}

/* Une note de bas de section. **Elle porte l'ecart lateral du cadre** : sans lui son texte
   touchait le filet de la section, seul element de la page a le faire. */
.administration__regle {
  margin: 0;
  padding: 10px 14px;
  max-width: 90ch;
  font: 500 var(--taille-etiquette)/1.5 var(--font-body);
  color: var(--color-neutral-700);
}

.administration__pannes {
  border: 2px solid var(--etat-bloque);
  background: var(--message-refus-bg);
  color: var(--message-refus-ink);
  padding: 10px 14px;
}

.administration__pannes-titre {
  display: block;
  font: 700 var(--taille-bloc)/1.2 var(--font-body);
}

.administration__pannes-liste {
  margin: 6px 0 0;
  padding-left: 18px;
  font: 500 var(--taille-etiquette)/1.45 var(--font-body);
}

.administration__panne {
  margin: 0;
}

/* Chaque alerte est un encart a elle seule, pose entre le bandeau et les onglets. Elle etait
   une ligne d'une liste tant que les cinq sections etaient empilees ; depuis les onglets, elle
   doit se tenir seule et porte donc son propre cadre. */
.administration__alerte {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  align-items: baseline;
  padding: 10px 14px;
  border: 2px solid transparent;
  border-left-width: 5px;
}

.administration__alerte-intitule {
  font: 700 var(--taille-etiquette)/1.35 var(--font-body);
}

.administration__alerte-detail {
  font: 500 var(--taille-etiquette)/1.35 var(--font-body);
}

.administration__alerte--information {
  background: var(--ok-bg);
  color: var(--ok-ink);
  border-color: var(--ok-ink);
}

.administration__alerte--attention {
  background: var(--message-attention-bg);
  color: var(--message-attention-ink);
  border-color: var(--etat-a-surveiller);
}

.administration__alerte--urgence {
  background: var(--refus-bg);
  color: var(--refus-ink);
  border-color: var(--refus-bord);
}

/* Fermer un compte : le seul geste de cet écran qui efface une identité.

   **Plié par défaut, et le pliage est natif** — un `<details>`, qui ne demande aucun script et
   traverse donc la politique de sécurité. C'est le même motif que le dépliable « Code couleur »
   du classeur, aux couleurs près : celui-ci porte l'habillage du refus, pour qu'on ne le confonde
   pas avec « Désactiver », qui se défait d'un clic. */
.administration__fermeture {
  margin-top: 10px;
  border: 1px solid var(--refus-bord);
  border-radius: 4px;
  background: var(--refus-bg);
  color: var(--refus-ink);
}

.administration__fermeture-titre {
  padding: 7px 12px;
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--refus-ink);
  cursor: pointer;
  list-style: none;
}

.administration__fermeture-titre::-webkit-details-marker {
  display: none;
}

.administration__fermeture-titre::before {
  content: "\25b8";
  display: inline-block;
  margin-right: 8px;
  transition: transform .12s ease;
}

.administration__fermeture[open] .administration__fermeture-titre::before {
  transform: rotate(90deg);
}

/* La précision sous « Ses projets vont à » : le menu ne propose que des administrateurs depuis
   le 2026-08-26, et sans cette ligne l'absence d'un collègue attendu passe pour un défaut. Ton
   neutre, pas le rouge du refus : ce n'est pas une panne, c'est la règle.

   **Ce bloc est séparé, et il a coûté cher de l'apprendre.** Une première rédaction l'a glissé
   entre la virgule et le sélecteur suivant de la liste ci-dessous : l'avertissement « C'est
   définitif » a changé de règle en silence, perdant sa couleur d'alerte et son retrait. Deux
   relecteurs l'ont trouvé le 2026-08-26 ; aucun contrôle ne le voyait. */
.administration__precision-du-repreneur {
  margin: 2px 0 6px;
  color: var(--color-text-muted);
  font: 500 var(--taille-etiquette)/1.4 var(--font-body);
}

.administration__fermeture-explication {
  margin: 0;
  padding: 0 12px 10px;
  font: 500 var(--taille-etiquette)/1.45 var(--font-body);
  color: var(--refus-ink);
  max-width: 78ch;
}

.administration__fermeture .administration__geste {
  padding: 0 12px 12px;
}

/* Les gestes d'écriture de l'administration.
   Chaque formulaire est en ligne et ne porte qu'un bouton : les mettre en colonne étirerait
   chaque rangée du tableau sur la hauteur de quatre gestes, et la liste des comptes deviendrait
   illisible dès la dixième personne. */
.administration__gestes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.administration__geste {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
}

/* Confier un projet ne part d'aucune ligne : son formulaire vit sous le tableau, et respire. */
.administration__formulaire {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--color-divider);
}

/* **Les trois textes du formulaire, habilles pour de vrai.** Ils ne declaraient qu'une taille :
   la graisse et l'interlignage retombaient donc sur ceux du navigateur — 400 et « normal » — la
   seule police du produit qui ne vienne pas de la feuille. Releve le 2026-08-19 par la sonde de
   polices de `scripts/comparer_a_la_maquette.py`, ajoutee ce jour-la pour cette question :
   « Archivo | 14.4px | 400 | normal » devant « Confier a », introuvable dans la maquette. */
.administration__etiquette {
  font: 500 var(--taille-etiquette)/1.2 var(--font-body);
  white-space: nowrap;
}

/* Une case a cocher de la liste des droits : la case, son intitule, et d'ou vient le droit. */
.administration__droit {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: 500 var(--taille-etiquette)/1.2 var(--font-body);
  white-space: nowrap;
  cursor: pointer;
}

/* Une case eteinte n'est pas cliquable : le curseur ne doit pas promettre le contraire. */
.administration__droit:has(input:disabled) {
  cursor: default;
}

/* « par son role » : le droit vient d'ailleurs que de la table, la case est donc cochee et
   eteinte. Discret, c'est un renseignement pose a cote d'un intitule. */
.administration__droit-source {
  font: 500 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-text-muted);
  font-style: italic;
}

.administration__choix,
.administration__saisie {
  border: 1px solid var(--color-divider);
  padding: 4px 8px;
  /* `font: inherit` heritait de la meme absence : le menu deroulant prenait lui aussi la police
     du navigateur. Declaree, comme celle de tout autre champ de saisie du produit. */
  font: 500 var(--taille-etiquette)/1.2 var(--font-body);
  background: var(--color-surface);
  color: var(--color-text);
}

.administration__saisie {
  min-width: 12ch;
}

/* --- La table des clients (maquette clients_equipe_echanges.html, partie 2, 2026-09-26) ---
   La forme des comptes : titre en petites capitales, bouton principal dans l'en-tete, une ligne
   par client. Le rond reprend les huit teintes du CRM (`.crm-teinte-N`). */
.administration__bouton-d-entete {
  margin-left: auto;
}

/* Le formulaire d'ajout, deplie sous l'en-tete : deux colonnes, l'intitule et sa saisie. */
.administration__client-nouveau {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 6px 10px;
  align-items: center;
  max-width: 520px;
  margin: 0;
  padding: 12px 14px;
  border-bottom: 2px solid var(--color-text);
  background: var(--crm-blanc);
}

.administration__client-etiquette {
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.administration__client-saisie {
  box-sizing: border-box;
  min-width: 0;
  padding: 5px 8px;
  border: 1px solid var(--color-divider);
  background: var(--crm-blanc);
  color: var(--color-text);
  font: 400 var(--taille-etiquette)/1.2 var(--font-body);
}

.administration__client-saisie--sigle {
  width: 52px;
  text-align: center;
  text-transform: uppercase;
  font-weight: 700;
}

.administration__client-sigle,
.administration__nom-du-client {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.administration__rond {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 24px;
  height: 24px;
  padding: 0;
  box-sizing: border-box;
  border-radius: var(--rayon-pilule);
  background: var(--crm-fond, var(--color-neutral-200));
  color: var(--crm-encre, var(--color-neutral-700));
  font: 700 var(--taille-etiquette)/1 var(--font-body);
}

.administration__rond[hidden] {
  display: none;
}

/* **Trois caracteres s'ecrivent plus petit** : le sigle d'un client en porte jusqu'a trois depuis
   le 2026-09-27 (#781). Mesure dans Archivo gras : en 9 px, un sigle courant fait 18 a 21 px et
   tient dans un rond de 24 ; en 8 px, 16 a 18 px dans un rond de 20 (derogation a la regle 2). */
.general__rond.rond-a-trois,
.administration__rond.rond-a-trois {
  font-size: 9px;
  letter-spacing: -0.02em;
}

.bibliotheque__rond.rond-a-trois {
  font-size: 8px;
  letter-spacing: -0.02em;
}

.administration__table--clients td {
  padding: 4px 10px;
  vertical-align: middle;
}

/* La question de la suppression confirmee sur la ligne : l'encre du refus, sans phrase de plus. */
.administration__question {
  font-weight: 600;
  color: var(--refus-bord);
}

/* Un bouton eteint ne montre pas toujours son infobulle, son porteur si. */
.administration__porteur-de-raison {
  display: inline-flex;
}

/* --- L'administration dans le style des ecrans refaits (maquette validee le 2026-09-29) --------
   `docs/refonte_ui/administration_et_signalement.html`. Les pieces sont celles de la
   Bibliotheque refaite : carte blanche arrondie, bascule en pilule, rangees a filet fin,
   pastilles, boutons en pilule. **Portees par `.administration`** : les regles plus haut
   restent celles des classes partagees, et celles-ci les precisent pour cet ecran seul.

   **Les gestes d'une ligne vivent dans son panneau**, un `<details>` par ligne dont le contenu
   se pose a droite de l'ecran. Tant qu'un panneau est ouvert, la carte recule d'autant : les
   colonnes restent lisibles au lieu d'etre couvertes. */
.administration {
  max-width: none;
  display: block;
  min-height: 0;
  overflow-y: auto;
  padding: 0 0 18px;
  background: var(--crm-blanc);
  border-radius: 14px;
  font: 400 var(--taille-texte)/1.5 var(--font-body);
}

.administration:has(.administration__ligne[open]:not([hidden])) {
  margin-right: 416px;
}

.administration__tete {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 14px;
  padding: 14px 24px 10px;
}

.administration .administration__onglets {
  display: flex;
  gap: 0;
  margin: 0;
  padding: 3px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-100);
}

.administration .administration__onglet,
.administration .administration__filtre {
  padding: 2px 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--color-neutral-700);
  font: 600 var(--taille-etiquette)/1.5 var(--font-body);
  letter-spacing: normal;
  text-transform: none;
  text-decoration: none;
  white-space: nowrap;
}

.administration .administration__onglet--actif,
.administration .administration__filtre--actif {
  background: var(--crm-blanc);
  color: var(--color-accent);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .08);
}

.administration .administration__onglet-compte {
  margin-left: 4px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-text-muted);
  font: 500 var(--taille-etiquette)/1.5 var(--font-body);
}

/* Quelqu'un attend une reponse : un point « a surveiller », le nombre en encre d'attention. */
.administration .administration__onglet-compte--a-traiter {
  background: none;
  color: var(--message-attention-ink);
  font-weight: 700;
}

.administration .administration__onglet-compte--a-traiter::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 4px;
  border-radius: 50%;
  background: var(--etat-a-surveiller);
  vertical-align: 1px;
}

/* Les chiffres a filets fins, comme ceux de l'Avancement foncier. */
.administration .administration__chiffres {
  margin: 0 24px 8px;
  border: 0;
  background: none;
}

.administration .administration__chiffre {
  padding: 4px 16px;
  border: 0;
  border-left: 1px solid var(--color-neutral-200);
}

.administration .administration__chiffre:first-child {
  padding-left: 0;
  border-left: 0;
}

.administration .administration__chiffre-surtitre {
  color: var(--color-neutral-700);
  font: 400 var(--taille-texte)/1.5 var(--font-body);
  letter-spacing: normal;
  text-transform: none;
}

.administration .administration__chiffre-valeur {
  font: 800 var(--taille-titre)/1.2 var(--font-heading);
  white-space: nowrap;
}

.administration .administration__chiffre-precision {
  font: 400 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-text-muted);
}

/* Le bandeau des demandes et les alertes : une pilule a point, puis la phrase. */
.administration .administration__bandeau,
.administration .administration__alerte,
.administration .administration__pannes {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  margin: 2px 24px 8px;
  padding: 0;
  border: 0;
  background: none;
  font: 400 var(--taille-texte)/1.5 var(--font-body);
}

.administration .administration__bandeau-texte,
.administration .administration__alerte-intitule,
.administration .administration__pannes-titre {
  padding: 0 9px;
  border-radius: 999px;
  background: var(--message-attention-bg);
  color: var(--message-attention-ink);
  font: 600 var(--taille-etiquette)/20px var(--font-body);
  letter-spacing: normal;
  text-transform: none;
}

.administration .administration__bandeau-texte::before,
.administration .administration__alerte-intitule::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 5px;
  border-radius: 50%;
  background: var(--etat-a-surveiller);
  vertical-align: 1px;
}

/* Ce qui n'a pas pu etre lu est une panne : le dessin de l'echec, pas celui de l'attente. */
.administration .administration__pannes-titre {
  background: var(--message-refus-bg);
  color: var(--message-refus-ink);
}

.administration .administration__alerte--urgence .administration__alerte-intitule {
  background: var(--message-refus-bg);
  color: var(--message-refus-ink);
}

.administration .administration__alerte--urgence .administration__alerte-intitule::before {
  background: var(--etat-bloque);
}

.administration .administration__bandeau-note,
.administration .administration__alerte-detail,
.administration .administration__panne {
  color: var(--color-neutral-700);
  font: 400 var(--taille-texte)/1.5 var(--font-body);
}

.administration .administration__pannes-liste {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Les sections : plus de cadre, le titre est porte par la bascule du haut et se lit a l'oreille. */
.administration .administration__section {
  margin: 0;
  padding: 0 14px;
  border: 0;
}

.administration .administration__entete {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
  padding: 6px 10px 10px;
  border: 0;
  background: none;
}

.administration .administration__titre {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.administration__recherche {
  width: 300px;
  padding: 6px 14px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-100);
  color: var(--color-text);
  font: 400 var(--taille-texte)/1.5 var(--font-body);
}

.administration__recherche:focus {
  outline: 2px solid var(--color-accent-200, var(--color-accent));
}

.administration .administration__filtres {
  display: flex;
  margin: 0;
  padding: 3px;
  gap: 0;
  border-radius: 999px;
  background: var(--color-neutral-100);
}

.administration .administration__creation,
.administration .administration__bouton-d-entete {
  margin-left: auto;
}

.administration .administration__creation + .administration__creation {
  margin-left: 0;
}

.administration .administration__creation[open] {
  flex-basis: 100%;
  order: 10;
  padding: 12px 16px;
  border: 0;
  border-radius: 14px;
  background: var(--color-accent-100);
}

.administration .administration__creation-titre::before {
  content: none;
}

.administration .administration__note-de-creation,
.administration .administration__regle,
.administration .administration__raison,
.administration .administration__precision,
.administration .administration__cause,
.administration .administration__vide {
  margin: 6px 10px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-neutral-700);
  font: 400 var(--taille-texte)/1.5 var(--font-body);
  letter-spacing: normal;
  text-transform: none;
}

.administration .administration__cause {
  color: var(--message-refus-ink);
  font-weight: 600;
}

.administration .administration__creation-titre {
  padding: 4px 14px;
  font-size: var(--taille-texte);
}

.administration .administration__choix,
.administration .administration__saisie,
.administration .administration__client-saisie {
  padding: 4px 12px;
  border: 0;
  border-radius: 999px;
  background: var(--crm-blanc);
  box-shadow: 0 0 0 1px var(--color-neutral-300);
  color: var(--color-text);
  font: 400 var(--taille-texte)/1.5 var(--font-body);
}

.administration .administration__etiquette,
.administration .administration__droit {
  color: var(--color-neutral-700);
  font: 400 var(--taille-texte)/1.5 var(--font-body);
  letter-spacing: normal;
  text-transform: none;
}

.administration .administration__droit-source,
.administration .administration__precision-du-repreneur {
  color: var(--color-text-muted);
  font: 400 var(--taille-etiquette)/1.5 var(--font-body);
}

/* Les tables qui restent (clients, demandes, retenue) : filets fins, en-tetes sans capitales. */
.administration .table {
  border: 0;
  border-collapse: collapse;
  font: 400 var(--taille-texte)/1.5 var(--font-body);
}

.administration .table th {
  padding: 5px 10px;
  border: 0;
  border-bottom: 1px solid var(--color-neutral-200);
  background: none;
  color: var(--color-text-muted);
  font: 400 var(--taille-etiquette)/1.5 var(--font-body);
  letter-spacing: normal;
  text-align: left;
  text-transform: none;
}

.administration .table td {
  padding: 5px 10px;
  border: 0;
  border-bottom: 1px solid var(--color-neutral-200);
}

.administration .table tbody tr:hover {
  background: var(--color-neutral-100);
}

/* --- Les listes a panneau : comptes, acces exterieurs, signalements ---------------------- */
.administration__liste {
  font-size: var(--taille-texte);
}

.administration__liste--comptes .administration__tetes,
.administration__liste--comptes .administration__resume {
  grid-template-columns: minmax(0, 1.3fr) 36px minmax(0, 1.5fr) 120px 90px 110px 60px;
}

.administration__liste--acces .administration__tetes,
.administration__liste--acces .administration__resume {
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1.2fr) minmax(0, 1fr) 120px minmax(0, 1.2fr);
}

.administration__liste--signalements .administration__tetes,
.administration__liste--signalements .administration__resume {
  grid-template-columns: minmax(0, 2.6fr) minmax(0, 1.2fr) 130px 150px 20px;
}

.administration__tetes {
  display: grid;
  gap: 0 12px;
  align-items: center;
  padding: 5px 10px;
  border-bottom: 1px solid var(--color-neutral-200);
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
}

.administration__resume {
  display: grid;
  gap: 0 12px;
  align-items: center;
  min-height: 34px;
  padding: 3px 10px;
  border-bottom: 1px solid var(--color-neutral-200);
  cursor: pointer;
  list-style: none;
}

.administration__resume::-webkit-details-marker {
  display: none;
}

.administration__resume > * {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.administration__resume:hover {
  background: var(--color-neutral-100);
}

.administration__ligne[open] > .administration__resume {
  background: var(--color-accent-100);
}

.administration__nom {
  font-weight: 600;
}

.administration__gris {
  color: var(--color-text-muted);
}

.administration__a-droite {
  text-align: right;
}

.administration__pilule {
  display: inline-block;
  padding: 0 9px;
  border-radius: 999px;
  background: var(--color-neutral-200);
  color: var(--color-neutral-800);
  font: 600 var(--taille-etiquette)/19px var(--font-body);
  white-space: nowrap;
}

.administration__pilule--ok {
  background: var(--ok-bg);
  color: var(--ok-ink);
}

.administration__pilule--cours {
  background: var(--processus-bleu-fond);
  color: var(--processus-bleu);
}

.administration__pilule--accent {
  background: var(--color-accent-100);
  color: var(--color-accent);
}

/* Le panneau de la ligne ouverte, a droite de l'ecran (outils.html). */
.administration__panneau {
  position: fixed;
  z-index: 20;
  top: calc(var(--hauteur-de-la-barre) + 12px);
  right: 16px;
  bottom: 16px;
  width: 400px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: 18px;
  background: var(--color-accent-100);
  box-shadow: 0 6px 24px rgba(0, 0, 0, .12);
  cursor: default;
}

.administration__panneau-tete {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 16px 18px 10px;
}

.administration__panneau-titre {
  margin: 0;
  font: 800 var(--taille-bloc)/1.3 var(--font-heading);
  overflow-wrap: anywhere;
}

.administration__panneau-note {
  margin: 2px 0 0;
  color: var(--color-neutral-700);
  font-size: var(--taille-etiquette);
}

.administration__fermer {
  margin-left: auto;
}

.administration__panneau-corps {
  flex: 1;
  display: grid;
  align-content: start;
  gap: 14px;
  overflow: auto;
  padding: 0 18px 16px;
}

.administration__bloc {
  padding: 12px 14px;
  border-radius: 14px;
  background: var(--crm-blanc);
}

.administration__bloc-titre {
  margin: 0 0 8px;
  color: var(--color-accent);
  font: 700 var(--taille-texte)/1.4 var(--font-body);
}

/* L'irreversible, isole en rouge (regle 14 de la refonte). */
.administration__bloc--danger {
  box-shadow: inset 0 0 0 1px var(--message-refus-bg);
}

.administration__bloc--danger .administration__bloc-titre,
.administration__bloc--danger .administration__fermeture-titre {
  color: var(--message-refus-ink);
}

.administration__panneau .administration__geste,
.administration__panneau .administration__formulaire {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0 0 8px;
}

.administration__panneau .administration__fermeture {
  margin: 4px 0 0;
  padding: 0;
  border: 0;
  background: none;
}

.administration__aide {
  margin: 4px 0 8px;
  color: var(--color-neutral-700);
  font-size: var(--taille-etiquette);
}

.administration__actions {
  display: flex;
  justify-content: flex-end;
  margin: 8px 0 0;
}

.administration__zone {
  box-sizing: border-box;
  width: 100%;
  min-height: 70px;
  margin-top: 10px;
  padding: 8px 12px;
  border: 0;
  border-radius: 12px;
  background: var(--crm-blanc);
  box-shadow: 0 0 0 1px var(--color-neutral-300);
  color: var(--color-text);
  font: 400 var(--taille-texte)/1.5 var(--font-body);
  resize: vertical;
}

.administration__traitement {
  margin: 0;
}

/* L'etat d'un signalement en bascule : quatre boutons radio habilles en pilules. */
.administration__bascule {
  display: inline-flex;
  flex-wrap: wrap;
  margin: 0;
  padding: 3px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-100);
}

.administration__bascule-choix input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.administration__bascule-choix span {
  display: inline-block;
  padding: 2px 11px;
  border-radius: 999px;
  color: var(--color-neutral-700);
  font: 600 var(--taille-etiquette)/1.5 var(--font-body);
  cursor: pointer;
}

.administration__bascule-choix input:checked + span {
  background: var(--crm-blanc);
  color: var(--color-accent);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .08);
}

.administration__bascule-choix input:focus-visible + span {
  outline: 2px solid var(--color-accent);
}

.administration__capture img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 10px;
  background: var(--color-neutral-200);
}

.administration__fiches {
  margin: 0;
}

.administration__fiche {
  display: grid;
  grid-template-columns: 130px minmax(0, 1fr);
  gap: 10px;
  padding: 6px 0;
  border-top: 1px solid var(--color-neutral-200);
}

.administration__fiche:first-child {
  border-top: 0;
}

.administration__fiche dt {
  color: var(--color-neutral-700);
}

.administration__fiche dd {
  margin: 0;
  font-weight: 600;
  overflow-wrap: anywhere;
  white-space: pre-line;
}

/* Une fenetre etroite : le panneau couvre la liste au lieu de la faire reculer. */
@media (max-width: 1100px) {
  .administration:has(.administration__ligne[open]:not([hidden])) {
    margin-right: 0;
  }

  .administration__panneau {
    left: 16px;
    width: auto;
  }
}

/* --- Les trois écrans de lecture d'un projet -------------------------------------------- */

/* Le cartouche long de M2. Même source que la chip compacte de la barre de titre, forme
   différente : ici on a la place d'écrire le texte d'explication, là-haut non. Les quatre
   tonalités sont celles des chips, reprises par les mêmes jetons. */
/* Le classeur est un écran de pleine hauteur : la coque n'y pose plus de marge, donc chaque bloc
   pose la sienne, et aucun ne s'étire pour combler le vide. L'Avancement et le Rapprochement,
   refaits le 2026-09-26, ne partagent plus cette règle. */
.classeur__section {
  border: 1px solid var(--color-divider);
  border-radius: var(--rayon-cadre);
  background: var(--crm-blanc);
  overflow: hidden;
  flex: none;
  margin: 0 20px 16px;
  /* **La table colle aux bords de sa boite** (Antoine, 2026-09-05) : le cadre de la section lui
     sert de bordure, et cent lignes gagnent la place que le retrait prenait. Ce qui entoure la
     table reprend ce retrait pour son propre compte, juste dessous. */
  padding: 0;
}

/* **La seule section qui grandit, et c'est celle de la table.** Les autres blocs de l'ecran
   gardent `flex: none` : ils font leur hauteur et rien de plus. Celui-ci prend ce qui reste, sans
   quoi le cadre de la table ne peut pas defiler et l'en-tete ne tient pas en haut.

   Vise par son identifiant plutot que par une classe de plus : il n'y en a qu'un sur la page, et
   une classe supplementaire se serait posee sur un bloc puis oubliee sur le suivant. */
#classeur-table {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

/* Les commandes gardent de quoi ne pas coller au bord ; la table, elle, va jusqu'au bout. */
.classeur__section > p,
.classeur__section > .classeur__pagination {
  padding-left: 8px;
  padding-right: 8px;
}

/* Les deux `__entete` qui figuraient ici sont parties avec la regle des rangees souples, dont
   elles etaient co-selectrices : tombees dans celle-ci, elles auraient recu une taille de titre.
   Aucun gabarit ne les pose aujourd'hui. Releve en revue le 2026-09-08. */
.classeur__titre {
  font-size: var(--taille-bloc);
  margin: 0;
}

/* Les bandeaux que rien ne peut afficher, écrits en toutes lettres avec leur raison. */

/* Sans marge : revenir de la carte sur une parcelle absente de l'onglet monte ce bloc, et il se
   mesure là (`tests/navigateur/test_aller_retour_classeur_carte.py`). */
.classeur__attente {
  margin: 0;
  background: var(--warn-bg);
  color: var(--warn-ink);
  padding: 10px;
  font-size: var(--taille-ecran);
}

/* --- « Avancement foncier » : le projet, puis ses zones (maquette validee le 2026-09-26) -------

   `docs/refonte_ui/avancement_foncier.html`. Une carte blanche aux coins arrondis, comme la
   bibliotheque ; ni cadre ni capitale. Le tableau des zones defile sous son en-tete fixe. */
.avancement {
  display: flex;
  flex-direction: column;
  gap: 18px;
  height: 100%;
  min-height: 0;
  padding: 18px 26px 22px;
  box-sizing: border-box;
  overflow: auto;
  background: var(--crm-blanc);
  border-radius: 14px;
  font: 400 var(--taille-texte)/1.5 var(--font-body);
}

.avancement__sans-fgf {
  flex: 1;
  display: grid;
  place-items: center;
  min-height: 420px;
}

.avancement__tete {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

/* Le seuil : la reglette (maquette validee le 2026-09-26, docs/refonte_ui/priorite_avancement.html).
   Les niveaux accoles, arrondis aux deux bouts seulement ; chacun dans sa couleur de la rampe de
   la priorite, pleine s'il est compris, pale sinon ; le retenu se detache par un anneau. La rangee
   du seuil peut passer a la ligne, la reglette jamais. */
.avancement__seuil {
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
}

.avancement__seuil-titre {
  cursor: default;
}

.avancement__niveaux {
  display: flex;
  gap: 0;
}

/* Chaque niveau part dans son propre formulaire : `display: contents` laisse le bouton se poser
   dans la rangee sans que le formulaire ajoute une boite. */
.avancement__choix {
  display: contents;
}

/* Sans rampe (moteur muet, pas de carto, pas de script) : la reglette sans couleur. */
.avancement__niveau {
  /* Remplacee niveau par niveau par avancement.js ; ce defaut ne sert qu'a la declarer. */
  --niveau-teinte: var(--color-accent-200);
  position: relative;
  flex: none;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: var(--color-neutral-200);
  font: 700 var(--taille-etiquette)/1 var(--font-body);
  color: var(--color-text-muted);
  cursor: pointer;
}

.avancement__niveau--compris {
  background: var(--color-accent-200);
  color: var(--color-accent);
}

/* Avec la rampe : `--niveau-teinte` est pose par avancement.js depuis `data-teinte`. L'encre du
   chiffre se choisit au contraste, cote serveur. */
.avancement__niveaux--rampe .avancement__niveau {
  background: color-mix(in srgb, var(--niveau-teinte) 16%, var(--crm-blanc));
}

.avancement__niveaux--rampe .avancement__niveau--compris {
  background: var(--niveau-teinte);
  color: var(--color-accent-800);
}

.avancement__niveaux--rampe .avancement__niveau--compris.avancement__niveau--encre-claire {
  color: #fff;
}

/* Chaque niveau vit dans son formulaire : les bouts se lisent donc sur les formulaires. */
.avancement__choix:first-child .avancement__niveau {
  border-radius: 999px 0 0 999px;
}

.avancement__choix:last-child .avancement__niveau {
  border-radius: 0 999px 999px 0;
}

.avancement__choix:only-child .avancement__niveau {
  border-radius: 999px;
}

.avancement__choix .avancement__niveau.avancement__niveau--retenu {
  z-index: 1;
  border-radius: 6px;
  box-shadow: 0 0 0 2px var(--crm-blanc), 0 0 0 3.5px var(--color-text);
}

.avancement__perimetre {
  margin-left: 6px;
  white-space: nowrap;
}

/* Le seul signal jaune de l'ecran : un FGF sans seuil utilisable. */
.avancement__signal {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 1px 9px;
  border-radius: 999px;
  background: var(--warn-bg);
  color: var(--warn-ink);
  font-size: var(--taille-etiquette);
  font-weight: 600;
  white-space: nowrap;
  cursor: default;
}

.avancement__signal::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ef-sun);
}

/* Vue du projet : quatre chiffres separes de filets fins. */
.avancement__projet {
  display: flex;
  flex-direction: column;
  gap: 22px;
}

.avancement__chiffres {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid var(--color-neutral-200);
  border-bottom: 1px solid var(--color-neutral-200);
}

.avancement__chiffre {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: 14px 18px 14px 0;
}

.avancement__chiffre + .avancement__chiffre {
  padding-left: 18px;
  border-left: 1px solid var(--color-neutral-200);
}

.avancement__intitule {
  width: max-content;
  max-width: 100%;
  color: var(--color-text-muted);
  font-size: var(--taille-texte);
  cursor: default;
}

.avancement__valeur {
  font: 800 var(--taille-vitrine)/1.15 var(--font-heading);
  letter-spacing: -.01em;
}

.avancement__valeur--absente {
  color: var(--color-text-muted);
  cursor: default;
}

.avancement__fraction {
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
}

.avancement__repartition {
  min-width: 0;
}

.avancement__repartitions {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.avancement__repartition-titre {
  display: inline-block;
  margin: 0;
  font: 700 var(--taille-ecran)/1.4 var(--font-heading);
  cursor: default;
}

/* Une barre arrondie ; le dessin qu'elle porte place chaque etat a sa part. */
.avancement__barre {
  display: block;
  height: 14px;
  margin-top: 8px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--color-neutral-100);
}

.avancement__dessin {
  display: block;
  width: 100%;
  height: 100%;
}

.avancement__dessin rect {
  fill: var(--teinte);
}

.avancement__legende {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 22px;
  margin: 9px 0 0;
  padding: 0;
  list-style: none;
}

.avancement__etat {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: var(--taille-texte);
  white-space: nowrap;
}

.avancement__etat small {
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
}

.avancement__etat--nul {
  color: var(--color-text-muted);
}

.avancement__etat--nul .avancement__point {
  opacity: .45;
}

.avancement__point {
  flex: none;
  display: inline-block;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--teinte);
}

/* Vue par zone. */
.avancement__zones {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.avancement__outils {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.avancement__recherche {
  width: 170px;
  padding: 7px 14px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-100);
  color: var(--color-text);
  font: 400 var(--taille-texte)/1.3 var(--font-body);
}

.avancement__recherche:focus {
  outline: 2px solid var(--color-accent-200);
}

.avancement__filtres {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
}

.avancement__filtre {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font: 500 var(--taille-etiquette)/1.5 var(--font-body);
  color: var(--color-neutral-700);
  white-space: nowrap;
  cursor: pointer;
}

.avancement__filtre small {
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
}

.avancement__filtre[aria-pressed="true"] {
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-weight: 600;
}

.avancement__filtre .avancement__point {
  width: 8px;
  height: 8px;
}

.avancement__table {
  flex: 1;
  min-height: 0;
  margin-top: 12px;
  overflow: auto;
  border-top: 1px solid var(--color-neutral-200);
}

/* Une zone par ligne, sans retour : la table ne loge aucune commande, et elle defile a l'horizontale
   dans son cadre quand la fenetre est etroite. */
.avancement__table table {
  width: 100%;
  border-collapse: collapse;
  white-space: nowrap;
}

.avancement__table th {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 9px 10px;
  border-bottom: 1px solid var(--color-neutral-200);
  background: var(--crm-blanc);
  text-align: left;
  font: 600 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-text-muted);
  white-space: nowrap;
}

.avancement__table th button {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: pointer;
}

.avancement__table th button[aria-sort] {
  color: var(--color-accent);
}

.avancement__table th button[aria-sort="descending"]::after {
  content: " ↓";
}

.avancement__table th button[aria-sort="ascending"]::after {
  content: " ↑";
}

.avancement__colonne-absente {
  color: var(--color-neutral-400);
  cursor: default;
}

.avancement__table td {
  padding: 8px 10px;
  border-bottom: 1px solid var(--color-neutral-200);
  font-size: var(--taille-texte);
  font-variant-numeric: tabular-nums;
}

.avancement__table th.avancement__nombre,
.avancement__table td.avancement__nombre {
  text-align: right;
}

.avancement__table tbody tr {
  cursor: pointer;
}

.avancement__table tbody tr:hover {
  background: var(--color-accent-100);
}

.avancement__nom a {
  font-weight: 700;
  color: inherit;
  text-decoration: none;
}

.avancement__etat-de-zone {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--color-neutral-800);
}

.avancement__etat-de-zone .avancement__point {
  width: 8px;
  height: 8px;
}

.avancement__mini {
  display: block;
  width: 170px;
  height: 8px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--color-neutral-100);
}

.avancement__faible {
  color: var(--color-text-muted);
}

.avancement__fleche {
  width: 28px;
  color: var(--color-neutral-400);
  font-size: var(--taille-ecran);
}

.avancement__table tbody tr:hover .avancement__fleche {
  color: var(--color-accent);
}

.avancement__pied {
  display: flex;
  gap: 18px;
  padding-top: 8px;
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
}

.avancement__echec {
  margin: 0;
  color: var(--color-neutral-700);
}

/* --- Les teintes des etats ----------------------------------------------------------------------

   **Une classe par etat, declaree ici et nulle part ailleurs**, aux couleurs du referentiel du
   moteur (`src/web/teintes_des_etats.py`). Elle pose la teinte dans `--teinte`, que la barre, la
   pastille ou le point lisent. `tests/unit/test_teintes_des_etats.py` confronte chaque couleur au
   referentiel du pin installe. */
.teinte--inconnue {
  --teinte: var(--color-neutral-300);
}
.teinte--zone-non-commencee { --teinte: #CFCFCF; }
.teinte--zone-en-cours { --teinte: #82C46C; }
.teinte--zone-securisee { --teinte: #00413B; }
.teinte--zone-suspendue { --teinte: #FFCC00; }
.teinte--zone-abandonnee { --teinte: #C0392B; }
.teinte--surface-non-commencee { --teinte: #CFCFCF; }
.teinte--surface-en-cours { --teinte: #82C46C; }
.teinte--surface-securisee { --teinte: #00413B; }
.teinte--surface-compliquee { --teinte: #E8850C; }
.teinte--surface-non-signable { --teinte: #C0392B; }
.teinte--perspective-non-connu { --teinte: #ECECEC; }
.teinte--perspective-defavorable { --teinte: #C0392B; }
.teinte--perspective-reticent { --teinte: #EF8A43; }
.teinte--perspective-neutre { --teinte: #FBD25E; }
.teinte--perspective-plutot-favorable { --teinte: #86C561; }
.teinte--perspective-favorable { --teinte: #2E9E52; }
.teinte--signature-non-connu { --teinte: #ECECEC; }
.teinte--signature-identifie { --teinte: #E7F3DE; }
.teinte--signature-contacte { --teinte: #B1D99F; }
.teinte--signature-rencontre { --teinte: #82C46C; }
.teinte--signature-en-signature { --teinte: #417951; }
.teinte--signature-signe { --teinte: #00413B; }
.teinte--signature-complique { --teinte: #E8850C; }
.teinte--signature-refuse { --teinte: #C0392B; }
.teinte--signature-signe-autre-projet { --teinte: #98006D; }
.teinte--signature-abandonne { --teinte: #874D45; }

/* Doctrine, regle 7 : le vert fonce du referentiel, celui de ce qui est acquis, se fondait dans
   le fond du theme sombre (releve du 2026-10-01). Le theme sombre lui donne le vert de son
   accent ; le referentiel, et donc le theme clair, ne changent pas. */
[data-theme="sombre"] .teinte--signature-signe,
[data-theme="sombre"] .teinte--surface-securisee,
[data-theme="sombre"] .teinte--zone-securisee {
  --teinte: var(--color-accent-600);
}

/* **Le classeur seul.** Il remplit la hauteur : la barre d'outils et la rangée de chiffres
   restent en place, et c'est la zone des onglets et de la table qui défile. Sans
   `min-height: 0`, un enfant qui déborde pousse la colonne au lieu de défiler dedans. */
.classeur {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

/* --- Les deux écrans d'entrée : le calcul et le catalogue d'outils --------------------------- */

/* La raison écrite sous un bouton gris du classeur. Elle double l'infobulle du bouton, à dessein :
   une infobulle ne se lit ni au clavier ni sur un écran tactile. */
.classeur__raison {
  margin: 8px 0 0;
  font-size: var(--taille-texte);
  color: var(--color-text-muted);
}

.classeur__pagination {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 12px;
}

/* Ajouter une ligne : le pliage est porté par le navigateur, sans une ligne de script. */
.classeur__creation {
  margin: 0 0 10px;
}

.classeur__creation-formulaire {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px;
  margin-top: 8px;
  padding: 10px 14px;
  border: 2px solid var(--color-text);
  background: var(--color-surface);
}

.classeur__creation-champ {
  padding: 5px 8px;
  border: 1px solid var(--color-divider);
  background: var(--color-bg);
  color: var(--color-text);
  font-size: var(--taille-etiquette);
}

/* **La phrase qui dit où la ligne se posera.** Elle ne paraît que sur le geste venu du menu du
   clic droit ; le geste du haut de table pose en fin et n'a rien à annoncer. */
.classeur__creation-position {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
}

.classeur__creation-eteinte {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 10px;
  font-size: var(--taille-etiquette);
  opacity: 0.7;
}

/* **Celle du bas se fige au bas de l'ecran** (Antoine, 2026-09-05) : elle vivait sous cent lignes,
   donc hors de vue, et changer de page demandait de descendre tout le tableau. Elle porte son
   propre fond et un filet, sans quoi les lignes defileraient a travers. */
/* **Resserree le 2026-09-21** (Antoine, avec le retrait du bouton « Nouvelle ligne » qu'elle
   portait) : dix pixels au-dessus et au-dessous devenaient une bande, alors qu'elle ne porte plus
   que le compte et les deux fleches de page. Six suffisent, et c'est autant rendu a la table. */
.classeur__pagination--bas {
  position: sticky;
  bottom: 0;
  margin-top: 0;
  padding-top: 6px;
  padding-bottom: 6px;
  background: var(--color-surface);
  border-top: 1px solid var(--color-divider);
}

/* Le compteur d'un onglet quand le moteur l'a rendu — distinct du signe d'absence, qui garde
   le fond d'avertissement de `.classeur__compteur-absent`. */
/* **Un voile sombre, et non une teinte a lui** (Antoine, 2026-09-08) : « meme couleur, plus
   foncee, comme si un aplat gris semi-transparent etait pose dessus ». Un noir a 18 % se compose
   sur le fond de l'onglet, neutre ou vert pour l'onglet ouvert, sans qu'aucune valeur ne soit
   ecrite par onglet. La couleur du texte est celle de l'onglet. */
.classeur__compteur {
  display: inline-block;
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
  font-variant-numeric: tabular-nums;
}

/* La table de l'onglet actif.

   **Le cadre de la table prend la hauteur qui reste, et c'est lui qui defile.** Il ne defilait
   qu'en largeur ; le defilement vertical se faisait au niveau de la page, et deux choses en
   souffraient, toutes deux signalees par Antoine le 2026-09-06.

   **Les noms de colonnes ne tenaient pas en haut.** Ils se declarent pourtant collants
   (`.table th`, `position: sticky`), mais un `overflow-x` fait du cadre le contexte de
   defilement des DEUX axes : l'en-tete collait donc au haut d'une boite qui, elle, s'en allait
   avec la page. Bornee en hauteur, la boite defile pour de bon et l'en-tete tient.

   **La barre de defilement horizontale n'etait atteignable qu'au bas du tableau**, apres avoir
   fait defiler des milliers de lignes. Elle se pose desormais au bas du cadre visible.

   `min-height: 0` est ce qui autorise un enfant de colonne flexible a etre plus court que son
   contenu ; sans lui le cadre grandit indefiniment et rien ne defile. */
/* **La table occupe tout son conteneur** (Antoine, 2026-09-08 : « je vois du padding qui pourrait
   disparaitre »). Les 14 px de marge tout autour prenaient 28 px de largeur a la donnee, sur un
   ecran ou l'on cherche justement a en montrer plus. */
.classeur-table {
  flex: 1;
  min-height: 0;
  overflow: auto;
  margin: 0;
}

/* **Les en-tetes du classeur sont en encre pleine, et lui seul.** La correction du 2026-09-02 a
   grise les cinq tables du produit ; mesure au navigateur le 2026-09-03 : la maquette ecrit
   #201E1D plein sur le classeur, et noir a 60 % sur les trois autres tables. */
.classeur-table .table th {
  color: var(--color-text);
  /* Majuscule initiale (doctrine, regle 13 ; maquette 3.2) : plus de capitales espacees. */
  text-transform: none;
  letter-spacing: 0;
  font-weight: 600;
  border-bottom: 1px solid var(--color-divider);
}





/* --- Les onglets du classeur ------------------------------------------------------------------ */

/* Des liens et non des boutons : une adresse partagée doit rouvrir le même onglet, et la
   navigation sans script est ce que la politique de sécurité nous laisse faire de plus simple. */
/* **La barre defile, elle ne passe pas a la ligne.** C'est la construction de la maquette, et
   c'est une revue qui a montre pourquoi elle compte : avec `flex-wrap`, des qu'une fenetre
   descendait sous ~1400 px, la note du clic droit passait a la ligne et le trait vert de
   l'onglet ouvert se retrouvait 31 px au-dessus du filet au lieu d'etre pose dessus. Mesure au
   navigateur, sur un portable courant de 1366 px. */
.classeur__onglets {
  display: flex;
  overflow-x: auto;
  gap: 2px;
  flex: none;
  padding: 0 20px;
  margin-bottom: 10px;
}

/* **Les onglets en puces, comme les filtres d'« Echanges »** (maquette 3.2, Antoine,
   2026-10-03). La teinte de la feuille Excel, filet depuis le 2026-10-01, devient un point devant
   le libelle : le repere reste, sans souligne de couleur. */
.classeur__onglet {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: var(--rayon-pilule);
  text-decoration: none;
  color: var(--color-neutral-700);
  font-weight: 600;
  white-space: nowrap;
  --teinte-d-onglet: transparent;
}

.classeur__onglet::before {
  content: "";
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--filet-d-onglet, var(--teinte-d-onglet));
}

/* --- Les teintes d'onglet du modele FGF V4 (Antoine, 2026-09-08) ----------------------------- */

/* **Recopiees, et non demandees au moteur** : « ca ne bougera pas ». Relevees le 2026-09-08 sur
   la couleur d'etiquette de feuille d'un vrai classeur, onglet par onglet. Les Ilots RPG valent
   `#82BF6E` dans le modele, la meme teinte que Dossiers, mais Antoine passera cette feuille a
   `#C0E6F5` : c'est cette valeur-la qu'il a demande de poser des maintenant. Chaque teinte ne
   peint plus que le filet sous l'onglet (2026-10-01). */
.classeur__onglet--zones { --teinte-d-onglet: #18a08f; }
.classeur__onglet--contrats { --teinte-d-onglet: #fecb00; --filet-d-onglet: color-mix(in srgb, var(--teinte-d-onglet) 65%, var(--color-text)); }
.classeur__onglet--parcelles { --teinte-d-onglet: #0a423b; --filet-d-onglet: color-mix(in srgb, var(--teinte-d-onglet) 70%, var(--color-text)); }
.classeur__onglet--dossiers { --teinte-d-onglet: #82bf6e; --filet-d-onglet: color-mix(in srgb, var(--teinte-d-onglet) 80%, var(--color-text)); }
.classeur__onglet--droits { --teinte-d-onglet: #b4d9a8; --filet-d-onglet: color-mix(in srgb, var(--teinte-d-onglet) 65%, var(--color-text)); }
.classeur__onglet--personnes { --teinte-d-onglet: #e6f2e2; --filet-d-onglet: color-mix(in srgb, var(--teinte-d-onglet) 55%, var(--color-text)); }
.classeur__onglet--crm { --teinte-d-onglet: #ff6800; --filet-d-onglet: color-mix(in srgb, var(--teinte-d-onglet) 95%, var(--color-text)); }
.classeur__onglet--ilots_rpg { --teinte-d-onglet: #c0e6f5; --filet-d-onglet: color-mix(in srgb, var(--teinte-d-onglet) 60%, var(--color-text)); }

/* **Le filet d'une teinte pale est fonce** (Antoine, 2026-10-01) : sur le fond de l'onglet, six
   filets restaient sous les 3 pour 1 d'une marque graphique (doctrine, regle 4), jusqu'a 1,16
   pour Personnes. La teinte se melange a l'encre du texte, juste assez pour atteindre le seuil :
   foncee en theme clair, eclaircie en theme sombre, ou c'est Parcelles qui se perdait. Il se
   declare avec la teinte, dans le bloc de chaque onglet ci-dessus. */

.classeur__onglet:hover {
  background: var(--color-accent-100);
}

/* **L'onglet ouvert prend le vert du produit** et la graisse 800 : deux signes et non un seul,
   pour un ecran mal eclaire ou un daltonisme. Son filet reste dessous, mais ne compte pas comme
   un signe : celui de Parcelles se confond avec le vert. Son texte reprend le fond de page,
   lisible sur le vert des deux themes. */
.classeur__onglet--actif {
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-weight: 800;
}

/* **Et au survol aussi** : `a:hover` pose le vert du produit sur le texte et gagne en
   specificite ; sur le fond vert de l'onglet ouvert, le libelle disparaissait (relecture du
   2026-10-01). */
.classeur__onglet--actif:hover {
  color: var(--color-accent);
}

/* En theme sombre, le vert sur le fond de la puce ouverte reste sous 4,5 pour 1 : le libelle
   prend l'encre du texte, la graisse 800 garde le second signe. */
/* Declaree apres le survol, a specificite egale : elle l'emporte aussi sous la souris. */
[data-theme="sombre"] .classeur__onglet--actif {
  color: var(--color-text);
}

/* Le compteur d'un onglet, à sa place et sans chiffre. Il se distingue du libellé pour qu'on ne
   le lise pas comme une partie du nom de l'onglet. */
.classeur__compteur-absent {
  display: inline-block;
  margin-left: 6px;
  font-size: var(--taille-texte);
}

/* Sur le vert de l'onglet ouvert, le gris de la valeur absente ne se lirait pas. */
.classeur__onglet--actif .classeur__compteur-absent {
  color: inherit;
}

/* --- Explorer le FGF : la barre d'outils ------------------------------------------------------ */

/* La rangee mesuree dans la maquette : 51 px de haut, les segments a gauche, les exports et la
   bascule a droite. `flex-wrap` : sur une fenetre etroite, elle passe a la ligne plutot que de
   pousser les boutons hors de l'ecran. */
.classeur-barre {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 20px;
  background: var(--color-surface);
  border-bottom: 2px solid var(--color-divider);
}


/* Le nom du classeur et sa version, comme la maquette les écrit à côté des segments. */
.classeur-barre__nom {
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
  font-weight: 600;
  white-space: nowrap;
}

.classeur-barre__version {
  cursor: help;
}

/* Le reglage de l'affichage : la case et son libelle sur une rangee, dans la barre. Meme motif que
   les autres etiquettes a case du produit. */
.classeur-barre__affichage-etiquette {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  font: 500 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-neutral-700);
  cursor: pointer;
  white-space: nowrap;
}

.classeur-barre__espace {
  flex: 1;
  min-width: 0;
}

/* Le titre du choix des colonnes. **Un depliable quand il s'ouvre, un bouton eteint sinon** : la
   meme regle habille les deux, pour qu'ouvrir ou non ne change pas la hauteur de la barre. Le
   bouton eteint garde sa raison en infobulle. */
.classeur-barre__bascule {
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-text-muted);
  flex: none;
  border: 0;
  background: none;
  padding: 0;
  text-decoration: underline;
  cursor: pointer;
}

.classeur-barre__bascule[disabled] {
  text-decoration: none;
  cursor: help;
  opacity: 0.6;
}

/* Le choix des colonnes affichees, pose le 2026-09-06 a la place de la bascule d'un bloc. Un
   depliable et un formulaire : le navigateur porte le pliage et les cases, la politique de
   securite n'a rien a autoriser de plus. */
.classeur-barre__colonnes {
  position: relative;
  flex: none;
}

.classeur-barre__colonnes > summary {
  list-style: none;
}

/* **Le bouton se fixe en bas** (Antoine, 2026-09-06) : c'est le formulaire qui borne sa hauteur,
   et la seule liste qui defile. Avant, tout defilait ensemble et il fallait descendre jusqu'au
   bas des colonnes pour trouver « Appliquer ». */
.classeur-barre__colonnes-formulaire {
  position: absolute;
  right: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  min-width: 220px;
  max-height: 320px;
  padding: 10px 12px;
  border: 1px solid var(--color-neutral-300);
  border-radius: 6px;
  background: var(--color-surface);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
}

/* **Ce qui fait tenir le bouton est `overflow-y: auto`, et lui seul.** Mesure au navigateur le
   2026-09-06 : le retrait de `min-height: 0` ne change rien tant que le debordement est `auto`,
   qui annule deja la taille minimale automatique d'un element flexible. La declaration reste
   comme filet, si le debordement venait a changer — pas comme ce qui tient le bouton. */
.classeur-barre__colonnes-liste {
  list-style: none;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  margin: 0 0 8px;
  padding: 0;
  font: 400 var(--taille-etiquette)/1.6 var(--font-body);
  color: var(--color-neutral-700);
}

/* La case et le nom sur la meme rangee, le nom cliquable avec elle — meme motif que le panneau
   des couches de la carte. */
.classeur-barre__colonnes-liste label {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  cursor: pointer;
}

/* Le bouton ne defile pas avec la liste : il garde sa place au bas du cadre. */
/* **Deux boutons depuis le 2026-09-21** : « Colonnes essentielles » a cote d'« Appliquer ». La
   regle porte desormais leur rangee, qui garde le meme `flex: none` — c'est elle qui reste en bas
   pendant que la liste defile. `stretch` les met a la meme hauteur, le second etant plus long. */
.classeur-barre__colonnes-appliquer {
  flex: none;
  display: flex;
  gap: 8px;
  align-items: stretch;
}

.classeur-barre__colonnes-appliquer > .btn {
  flex: 1 1 auto;
  min-width: 0;
}

.classeur-barre__colonnes-note {
  flex: none;
  margin: 0 0 8px;
  font: 400 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-text-muted);
}

/* Le depliable « Code couleur ». Le pliage est porte par le navigateur : rien a autoriser cote
   politique de securite, et il marche sans script. */
/* **Monte dans la barre depuis le 2026-09-06** (Antoine). Il etait un bloc pleine largeur pose
   SOUS la barre : il portait donc son propre fond et son propre filet. Dans la barre, les deux
   font double emploi — la barre a deja les siens — et le fond, d'une teinte differente, y
   dessinait un pave plus clair au milieu.

   **Il prend toute la largeur quand il s'ouvre**, et retombe sous les autres commandes : ouvert
   sur une ligne partagee, sa grille de colonnes de 260 px ne tiendrait pas. */
.classeur-couleurs {
  flex-basis: auto;
  min-width: 0;
}

.classeur-couleurs[open] {
  flex-basis: 100%;
}

.classeur-couleurs__titre {
  /* Le retrait de 20 px etait celui d'un bloc pleine largeur ; dans la barre, la commande voisine
     le donne deja par l'espacement du groupe. */
  padding: 4px 0;
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  cursor: pointer;
  list-style: none;
}

.classeur-couleurs__titre::-webkit-details-marker {
  display: none;
}

.classeur-couleurs__titre::before {
  content: "\25b8";
  display: inline-block;
  margin-right: 8px;
  transition: transform .12s ease;
}

.classeur-couleurs[open] .classeur-couleurs__titre::before {
  transform: rotate(90deg);
}

.classeur-couleurs__phrase {
  margin: 0;
  padding: 6px 0 4px;
  font: 500 var(--taille-etiquette)/1.45 var(--font-body);
  color: var(--color-neutral-700);
  max-width: 92ch;
}

/* **La legende du code couleur, branchee le 2026-09-03.** La grille de la maquette : des colonnes
   de 260 px au minimum, qui se remplissent d'elles-memes selon la largeur.

   **Aucune couleur ici, et c'est la regle du chantier.** Les couleurs viennent du moteur avec les
   valeurs, cellule par cellule et pastille par pastille ; les recopier dans cette feuille est
   exactement ce que le moteur interdit, parce que cela a deja diverge. Ce bloc ne dessine que la
   disposition. */
.classeur-couleurs__grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px 20px;
  padding: 6px 0 8px;
}

.classeur-couleurs__groupe {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.classeur-couleurs__colonne {
  font: 700 var(--taille-etiquette)/1 var(--font-body);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.classeur-couleurs__pastilles {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

/* Le filet de la maquette : un noir tres dilue, qui detache la pastille de son fond quelle que
   soit sa couleur — un filet fixe serait invisible sur la moitie d'entre elles. */
.classeur-couleurs__pastille {
  padding: 4px 7px;
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  letter-spacing: 0;
  border: 1px solid rgba(0, 0, 0, .12);
}

/* --- Explorer les donnees carto (maquette validee le 2026-09-26) ----------------------------- */

/* **Deux colonnes : les couches, puis la couche ouverte.** L'ecran occupe la hauteur ; la liste et
   la table defilent chacune dans son cadre, le reste ne bouge pas. `min-height: 0` sans quoi un
   enfant de colonne flexible refuse de descendre sous la taille de son contenu et le defilement
   ne se declenche jamais. */
.donnees-carto {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  flex: 1;
  min-height: 0;
  background: var(--color-surface);
}
.donnees-carto--seule {
  grid-template-columns: minmax(0, 1fr);
}

.donnees-liste {
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-right: 1px solid var(--color-divider);
}
.donnees-liste__tete {
  padding: 14px 14px 8px;
  flex: none;
}
/* **Positionnee** : le menu des themes s'y cale. **Repliable** : la pastille des couches absentes
   et le bouton des themes ne tiennent pas toujours a cote du titre. */
.donnees-liste__ligne {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 9px;
}
.donnees-liste__couches {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: 0 8px 10px;
}
.donnees-liste__nom-de-famille {
  padding: 9px 8px 2px;
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-text-muted);
}
.donnees-liste__couche {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 2px 8px;
  border-radius: 9px;
  font: 400 var(--taille-texte)/22px var(--font-body);
  color: var(--color-text);
  text-decoration: none;
}
.donnees-liste__couche:hover {
  background: var(--color-neutral-100);
  color: var(--color-text);
}
.donnees-liste__couche[aria-current] {
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-weight: 600;
}
.donnees-liste__nom {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.donnees-liste__compte {
  font-size: var(--taille-etiquette);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--color-text-muted);
}
.donnees-liste__couche--vide .donnees-liste__compte {
  color: var(--color-neutral-400);
}
.donnees-liste__couche[aria-current] .donnees-liste__compte {
  color: var(--color-accent-500);
}
/* Aucune regle globale ne cache `[hidden]` : un lien en `display: flex` resterait visible. */
.donnees-liste__couche[hidden],
.donnees-liste__famille[hidden],
.donnees-recherche__effacer[hidden] {
  display: none;
}

/* La pastille jaune des couches absentes ; son detail se lit au survol. */
.donnees-signal {
  flex: none;
  padding: 0 8px;
  border-radius: 999px;
  background: var(--warn-bg);
  color: var(--warn-ink);
  font: 600 var(--taille-etiquette)/17px var(--font-body);
  white-space: nowrap;
  cursor: default;
}

/* --- Les themes de la carto (maquette validee le 2026-10-01) ---------------------------------
   Le bouton se tient a droite du titre de la colonne ; son menu s'ouvre par-dessus la liste,
   cale sous la ligne du titre et non sur le bouton. */
.donnees-themes {
  margin-left: auto;
}
.donnees-themes__bouton {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  padding: 2px 12px;
  border-radius: var(--rayon-bouton);
  font: 600 var(--taille-etiquette)/19px var(--font-body);
  list-style: none;
  white-space: nowrap;
}
.donnees-themes__bouton::-webkit-details-marker {
  display: none;
}
.donnees-themes__battement {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-accent-500);
  animation: donnees-themes-battement 1.2s ease-in-out infinite;
}
.donnees-themes[open] .donnees-themes__battement {
  display: none;
}
@keyframes donnees-themes-battement {
  50% { opacity: .25; }
}
@media (prefers-reduced-motion: reduce) {
  .donnees-themes__battement {
    animation: none;
  }
}
.donnees-themes__menu {
  position: absolute;
  z-index: 10;
  top: calc(100% + 2px);
  left: 0;
  width: 340px;
  max-width: calc(100vw - 32px);
  padding: 8px 0;
  border-radius: var(--rayon-cadre);
  background: var(--color-surface);
  box-shadow: 0 8px 28px color-mix(in srgb, var(--color-text) 16%, transparent), 0 0 0 1px var(--color-divider);
}
.donnees-themes__tete {
  padding: 4px 14px 8px;
  border-bottom: 1px solid var(--color-divider);
  font: 800 var(--taille-texte)/1.3 var(--font-body);
}
.donnees-themes__lignes {
  max-height: 60vh;
  overflow: auto;
}
.donnees-themes__theme {
  padding: 8px 14px;
  border-bottom: 1px solid var(--color-divider);
}
.donnees-themes__theme:last-child {
  border-bottom: 0;
}
.donnees-themes__ligne {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 24px;
}
.donnees-themes__nom {
  flex: 1;
  min-width: 0;
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
}
.donnees-themes__couches {
  margin-top: 1px;
  font-size: var(--taille-etiquette);
  line-height: 1.35;
  color: var(--color-neutral-600);
}
.donnees-themes__coche {
  padding: 0 4px;
  font-weight: 800;
  color: var(--color-accent-500);
  cursor: default;
}
.donnees-themes__pilule {
  flex: none;
  padding: 0 8px;
  border-radius: 999px;
  background: var(--color-accent-100);
  color: var(--color-accent);
  font: 600 var(--taille-etiquette)/17px var(--font-body);
  white-space: nowrap;
  cursor: default;
}
.donnees-themes__formulaire {
  display: inline;
  margin: 0;
}
.donnees-themes__geste {
  padding: 0 10px;
  border-radius: 999px;
  font: 600 var(--taille-etiquette)/18px var(--font-body);
  white-space: nowrap;
}
.donnees-themes__progression {
  margin-top: 6px;
}
.donnees-themes__barre {
  display: block;
  width: 100%;
  height: 6px;
  border: 0;
  border-radius: 999px;
  overflow: hidden;
  appearance: none;
  -webkit-appearance: none;
}
.donnees-themes__barre::-webkit-progress-bar {
  background: var(--color-neutral-200);
}
.donnees-themes__barre::-webkit-progress-value {
  background: var(--color-accent-500);
  border-radius: 999px;
}
.donnees-themes__barre::-moz-progress-bar {
  background: var(--color-accent-500);
  border-radius: 999px;
}
.donnees-themes__rang {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
  font-size: var(--taille-etiquette);
  font-variant-numeric: tabular-nums;
  color: var(--color-neutral-700);
}
.donnees-themes__etape {
  flex: 1;
}
.donnees-themes__perte {
  margin-top: 6px;
  padding: 7px 10px;
  border-radius: var(--rayon-cadre);
  background: var(--message-refus-bg);
  color: var(--message-refus-ink);
  font-size: var(--taille-etiquette);
  line-height: 1.45;
}
.donnees-themes__gestes {
  display: flex;
  gap: 6px;
  margin-top: 6px;
}

.donnees-recherche {
  position: relative;
}
/* `border-box` : un champ texte se mesure hors marges, et ses 44 px le faisaient deborder de la
   colonne des couches (Antoine, 2026-09-27). */
.donnees-recherche__champ {
  box-sizing: border-box;
  width: 100%;
  padding: 6px 30px 6px 14px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-100);
  color: var(--color-text);
  font: 400 var(--taille-texte)/1.3 var(--font-body);
}
.donnees-recherche__champ:focus {
  outline: 2px solid var(--color-accent-200);
}
.donnees-recherche__champ[disabled] {
  color: var(--color-text-muted);
  cursor: not-allowed;
}
.donnees-recherche__effacer {
  position: absolute;
  right: 9px;
  top: 50%;
  transform: translateY(-50%);
  padding: 0 3px;
  border: 0;
  background: none;
  color: var(--color-text-muted);
  font-size: var(--taille-ecran);
  cursor: pointer;
}

/* La couche ouverte : une ligne de titre, le tableau ou l'apercu, un pied fin. */
.donnees-vue {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}
.donnees-vue__tete {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 20px 10px;
  flex: none;
}
.donnees-vue__titre {
  flex: 1;
  min-width: 0;
}
.donnees-vue__nomme {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.donnees-vue__nom {
  margin: 0;
  font: 800 var(--taille-bloc)/1.2 var(--font-body);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.donnees-vue__mesures {
  font: 400 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}
.donnees-vue__outils {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  flex: none;
}
.donnees-vue__bouton {
  white-space: nowrap;
}
/* L'écran vide de la colonne de droite, à distance du bord comme le reste de la vue. */
.donnees-vue > .etat-vide {
  margin: 20px;
}

/* Le choix de la campagne du registre parcellaire. */
.donnees-campagnes {
  display: flex;
  flex: none;
  padding: 3px;
  border-radius: 999px;
  background: var(--color-neutral-100);
}
.donnees-campagnes__annee {
  padding: 1px 10px;
  border-radius: 999px;
  font: 600 var(--taille-etiquette)/19px var(--font-body);
  font-variant-numeric: tabular-nums;
  color: var(--color-neutral-700);
  text-decoration: none;
}
.donnees-campagnes__annee[aria-current] {
  background: var(--color-surface);
  color: var(--color-accent);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .08);
}

.donnees-echec {
  margin: 0;
  padding: 14px 20px;
  font: 600 var(--taille-texte)/1.4 var(--font-body);
  color: var(--message-refus-ink);
}
.donnees-echec__cause {
  font-weight: 400;
  color: var(--color-neutral-800);
}
.donnees-hors {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 14px 20px;
  font: 400 var(--taille-texte)/1.4 var(--font-body);
  color: var(--color-neutral-800);
}

/* **En-tete et premiere colonne fixes** : la table defile dans son cadre, en hauteur comme en
   largeur, et la reference de la ligne reste sous les yeux. */
.donnees-table {
  flex: 1;
  min-height: 0;
  overflow: auto;
  margin: 0 20px;
  border-top: 1px solid var(--color-divider);
}
.donnees-table .table {
  width: auto;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--taille-texte);
  font-variant-numeric: tabular-nums;
}
/* Des titres lisibles, et non des noms de colonnes : ni capitales ni espacement. */
.donnees-table .table th {
  padding: 0 12px;
  font: 600 var(--taille-etiquette)/28px var(--font-body);
  letter-spacing: 0;
  text-transform: none;
  border-bottom: 1px solid var(--color-divider);
  white-space: nowrap;
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
  z-index: 2;
}
/* La cellule tient sur une ligne et se coupe a 260 px : voir la regle plus haut, avec la table. */
.donnees-table .table tbody tr:hover td {
  background: var(--color-neutral-100);
}
.donnees-table .table th:first-child,
.donnees-table .table td:first-child {
  position: sticky;
  left: 0;
  background: var(--color-surface);
  font-weight: 600;
  border-right: 1px solid var(--color-divider);
  z-index: 1;
}
.donnees-table .table th:first-child {
  z-index: 3;
}
/* **Un en-tete dont le menu est ouvert deborde** : coupe a 260 px, il cachait le menu de la
   colonne (filtrer, trier, masquer), et ses voisins le recouvraient. */
.donnees-table .table th:has(.classeur__filtre-colonne[open]) {
  overflow: visible;
  z-index: 4;
}
/* Doctrine, regle 12 : toute colonne de nombres, en-tete compris, alignee a droite, en chiffres a
   chasse fixe, sur une ligne (`colonnes_des_couches.porte_des_nombres`). */
.donnees-table__nombre {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.donnees-table__nombre .donnees-table__intitule {
  margin-left: auto;
}
/* Un nombre ou une date ne se coupe jamais : seul le texte s'arrete a 260 px. */
.donnees-table .table td.donnees-table__nombre {
  max-width: none;
}

.donnees-apercu {
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 6px 20px 16px;
}
/* `object-fit: contain` garde les proportions : une image etiree ferait mentir la carte. */
.donnees-apercu__image {
  max-height: 100%;
  max-width: 100%;
  min-height: 0;
  object-fit: contain;
  border-radius: 10px;
}

.donnees-pied {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
  margin-top: auto;
  padding: 8px 20px;
  background: var(--color-neutral-100);
  border-top: 1px solid var(--color-divider);
  font-variant-numeric: tabular-nums;
}

/* --- La pagination commune au FGF et aux donnees carto (maquette du 2026-09-25) --------------- */

/* **La phrase des lignes a gauche, les boutons a droite**, dans la rangee de l'ecran qui la porte :
   `order` la remonte en tete sans que chaque gabarit la place lui-meme. */
.pagination-commune__lignes {
  order: -1;
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-text);
}

.pagination-commune {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-left: auto;
  flex: none;
}

.pagination-commune__bouton {
  min-width: 30px;
  padding: 4px 8px;
  font-size: var(--taille-ecran);
  line-height: 1;
  text-align: center;
}

.pagination-commune__page {
  padding: 0 8px;
  font: 500 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-text-muted);
  white-space: nowrap;
}


/* --- La carte --------------------------------------------------------------------------------- */

/* **La geometrie de la maquette, mesuree dans sa version executable** : la carte a gauche, une
   colonne fixe de 268 px a droite, separees par un filet de 2 px. La colonne ne se comprime pas —
   elle porte les panneaux, et un panneau qui retrecit devient illisible avant de devenir petit.

   `min-width: 0` sur la colonne de gauche : sans lui, la toile de la carte impose sa largeur et la
   grille deborde de l'ecran au lieu de se partager. */
.carte {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 268px;
  gap: 0;
  /* `stretch` et non `start` : les deux colonnes descendent jusqu'en bas de la zone. Avec
     `start`, elles s'arretaient a la hauteur de leur contenu et laissaient la bande grise. */
  align-items: stretch;
  /* La part de hauteur laissee par les bandeaux qui precedent. `min-height: 0` sans quoi une
     piste de grille refuse de descendre sous la taille de son contenu et la carte deborde. */
  flex: 1;
  min-height: 0;
}

.carte__colonne {
  display: flex;
  flex-direction: column;
  min-width: 0;
  border-right: 2px solid var(--color-divider);
}

/* La scene : la toile, et ce qui se pose par-dessus. **Elle existe pour servir de repere a la
   legende** — la colonne entiere ne convient pas, car sa barre du bas n'a pas de hauteur fixe et
   la legende s'y calait sur celle d'une autre barre ; le conteneur de la carte ne convient pas
   non plus, la bibliotheque de cartographie le remplit de son calque de tuiles. */
.carte__scene {
  position: relative;
  display: flex;
  flex: 1;
  min-height: 320px;
}

/* Le menu du clic droit : les coordonnees du point designe, et de quoi les emporter.

   **Pose par le script, jamais par un style ecrit dans la page** : la politique de securite de
   production interdit le second. Seules sa place change ; tout le reste est ici. */
.carte__menu {
  position: absolute;
  /* **Au-dessus des commandes de la bibliotheque de cartographie**, qui montent a 1000 : plus bas,
     le coin du menu tombe sous les boutons de zoom, et le clic dezoome au lieu de copier. */
  z-index: 1100;
  min-width: 200px;
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: 6px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.18);
}

/* **`display: flex` bat le `[hidden]` du navigateur**, comme pour le bandeau d'attente : sans
   cette regle, le menu reste pose sur la carte des le chargement. */
.carte__menu[hidden] {
  display: none;
}

/* Ce que « Interroger » ecrit sous le bouton. **Une hauteur bornee et un defilement** : une couche
   dense peut rendre plusieurs lignes, et un menu qui s'allonge sans fin sort de l'ecran. */
.carte__menu-trouvailles {
  display: flex;
  flex-direction: column;
  gap: 6px;
  max-width: 320px;
  max-height: 40vh;
  overflow-y: auto;
}

.carte__trouvaille {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
}

/* Le nom de la couche porte la ligne : c'est ce qu'on cherche a l'oeil en balayant la liste. */
.carte__trouvaille-couche {
  font-weight: 600;
}

.carte__trouvaille-objets {
  /* Un identifiant cadastral tient sur une ligne ; cinq n'y tiennent pas. */
  overflow-wrap: anywhere;
}

.carte__menu-coordonnees {
  margin: 0;
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
  /* Des chiffres de meme largeur : deux points l'un sous l'autre se comparent a l'oeil. */
  font-variant-numeric: tabular-nums;
  color: var(--color-neutral-800);
  /* Le point se selectionne a la souris, pour qui prefere copier a la main. */
  user-select: text;
}

.carte__menu-copie {
  align-self: flex-start;
  padding: 4px 8px;
  font: 500 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-neutral-800);
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: 4px;
  cursor: pointer;
}

.carte__menu-copie:hover {
  background: var(--color-neutral-100);
}

/* Vide tant que rien n'a ete copie : sans hauteur reservee, le menu ne saute pas au clic. */
.carte__menu-suite {
  margin: 0;
  font: 400 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-neutral-700);
}

/* La reserve ou le script pose ses motifs de hachure.

   Elle ne montre rien : un SVG de taille nulle, dont seules les definitions servent, pointees par
   les formes de la carte et les pastilles de la legende. */
.carte__motifs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* La legende de la carte, posee en bas a droite de la toile et fermee au depart.

   **Elle ne prend jamais plus du tiers de la hauteur** : une couche a cinquante-quatre classes —
   les servitudes d'utilite publique — remplirait sinon l'ecran. Au-dela, elle defile chez elle. */
/* Le retour a une selection remplacee d'un clic (chantier 5, constat 03 §3) : un message en haut
   au centre de la carte, au-dessus des formes, sous les menus. */
.carte__retour-de-selection {
  position: absolute;
  top: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 500;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  max-width: calc(100% - 24px);
  padding: 8px 10px;
  border: 1px solid var(--color-divider);
  border-radius: var(--rayon-bouton);
  background: var(--color-accent-100);
  color: var(--color-text);
  font-size: var(--taille-texte);
}

.carte__retour-de-selection[hidden] {
  display: none;
}

.carte__legende {
  position: absolute;
  right: 12px;
  /* **Au-dessus de la mention de source, jamais par-dessus.** La bibliotheque de cartographie
     pose sa mention dans ce meme coin et la peint plus haut que tout ; la recouvrir cacherait une
     mention qu'on est tenu d'afficher. Ces pixels sont la hauteur de sa bande, plus une marge. */
  bottom: 28px;
  z-index: 500;
  max-width: 240px;
  /* **Un tiers par defaut, et la poignee pour agrandir** (Antoine, 2026-09-05). La legende etait
     bornee a un tiers, sans recours : au-dela de six couches on lisait par la fente. La hauteur
     est desormais une hauteur, que la poignee du navigateur remplace ; le plafond ne sert plus
     qu'a l'empecher de couvrir la carte entiere. Elle est ancree en bas, donc elle grandit vers
     le haut. */
  height: 33%;
  min-height: 96px;
  max-height: calc(100% - 40px);
  overflow-y: auto;
  padding: 0 12px 8px;
  /* Un cadre blanc arrondi, filet fin et sans ombre (maquette « Carte, seconde lecture »,
     2026-10-03). */
  background: var(--crm-blanc);
  border: 1px solid var(--color-divider);
  border-radius: var(--rayon-cadre);
}

/* **La barre de titre est la poignee** (Antoine, 2026-09-06). La poignee du navigateur se posait
   en bas a droite, sous la forme de trois traits, alors que la legende est ancree en bas et grandit
   vers le haut : c'est son haut qu'on veut attraper. La double fleche verticale le dit au survol.
   `touch-action` empeche le navigateur tactile de faire defiler la page pendant le geste. */
.carte__legende-titre {
  /* **Elle reste en haut quand la legende defile.** Sans cela, la poignee remonte hors du cadre
     des que la liste depasse — c'est-a-dire exactement le cas qui motive l'agrandissement. */
  position: sticky;
  top: 0;
  /* **Toute la bande est teintee** (Antoine, 2026-10-04) : des collegues ne trouvaient pas ou
     tirer. Les marges negatives la portent jusqu'aux bords du cadre, qui l'arrondit en haut ;
     opaque, sinon la liste defile sous les mots du titre. */
  margin: 0 -12px 8px;
  padding: 2px 2px 2px 12px;
  /* **Collée au ras du haut, même en défilant** (Antoine, 2026-10-05) : le cadre n'a plus de
     retrait en haut, qui laissait voir la liste au-dessus de la bande. Ses coins suivent ceux du
     cadre. */
  border-radius: calc(var(--rayon-cadre) - 1px) calc(var(--rayon-cadre) - 1px) 0 0;
  background: var(--color-accent-100);
  border-bottom: 1px solid var(--color-divider);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-neutral-800);
  cursor: ns-resize;
  touch-action: none;
  user-select: none;
}

/* La croix commune vit dans la barre, **tout au bout** (Antoine, 2026-10-04) : elle garde son
   propre curseur, sinon elle annoncerait qu'on peut la tirer. */
.carte__legende-titre .carte__legende-fermer {
  margin-left: auto;
  cursor: pointer;
}

/* **Le bouton de la legende, la ou elle s'ouvre** (Antoine, 2026-10-04) : au coin de la carte
   qu'elle occupe, et cache tant qu'elle est ouverte. Meme ancrage qu'elle, au-dessus de la
   mention de source. */
.carte__scene > .carte__commande[data-ouvrir-la-legende] {
  position: absolute;
  right: 12px;
  bottom: 28px;
  z-index: 500;
}

.carte__scene > .carte__commande[data-ouvrir-la-legende][aria-pressed="true"] {
  display: none;
}

/* **Le bouton du reglage, au bout de la liste** (Antoine, 2026-10-05) : dans le flux et non
   tenu en bas, ou il couvrait les dernieres lignes ; pleine largeur, sans deborder du cadre. */
.carte__legende-reglage {
  display: block;
  width: 100%;
  margin-top: 8px;
  white-space: normal;
}

.carte__legende-reglage[hidden] {
  display: none;
}

/* Le corps se garnit au script : vide, il ne doit pas laisser un blanc sous le titre. */
.carte__legende-corps {
  display: block;
}

.carte__legende-couche + .carte__legende-couche {
  margin-top: 8px;
}

.carte__legende-nom {
  display: flex;
  align-items: baseline;
  gap: 4px;
  margin: 0 0 2px;
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-neutral-700);
}

.carte__legende-ligne {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 0;
  font: 500 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-neutral-700);
}

/* Une ligne qui se clique est un bouton, et un bouton arrive habille par le navigateur : sans ce
   deshabillage, la legende gagnerait un cadre et un fond gris par couleur. **Le dessin de la ligne
   ne change pas** : ce qui se voit est le curseur, le soulignement au survol et le cadre de focus,
   qui disent qu'il y a quelque chose a cliquer sans ajouter une cinquieme forme a lire. */
.carte__legende-ligne--cliquable {
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
}

.carte__legende-ligne--cliquable:hover {
  color: var(--color-text);
  text-decoration: underline;
}

.carte__legende-ligne--cliquable:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}

/* La pastille porte ses couleurs en attributs de dessin, jamais en style : elles viennent du
   moteur, et la politique de securite interdit un style ecrit dans la page.

   **Le cadre gris est a nous, et il ne bouge jamais.** Le moteur veut certaines couches
   entierement transparentes ; sans ce cadre, leur pastille serait un vide, et la ligne
   paraitrait cassee au lieu de dire  rien n est peint . */
.carte__legende-pastille {
  flex: none;
  box-sizing: content-box;
  width: 10px;
  height: 10px;
  border: 1px solid var(--color-neutral-400);
}

.carte__legende-vide {
  margin: 0;
  font: 500 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-text-muted);
}

/* Les etiquettes posees sur les formes.

   **Le cadre de la bibliotheque de cartographie est entierement demonte** : elle pose par defaut
   une bulle blanche a bord gris avec une fleche, faite pour une infobulle au survol. Une etiquette
   n'est pas une bulle : c'est du texte sur la carte, et six cents bulles blanches masqueraient le
   fond. Les couleurs, elles, viennent du moteur et sont posees par le script. */
.carte__etiquette-cadre.leaflet-tooltip {
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  white-space: nowrap;
  pointer-events: none;
}

.carte__etiquette-cadre.leaflet-tooltip::before {
  display: none;
}

/* La mesure ecrite pres du trace. **La bulle de la bibliotheque est gardee**, a l'inverse des
   etiquettes ci-dessus : il n'y en a qu'une, et elle doit se lire sur n'importe quel fond. */
.carte__mesure-pres-du-trace {
  font: 600 var(--taille-texte)/1.3 var(--font-body);
  color: var(--color-neutral-900);
}

/* **Les sauts de ligne du moteur se gardent** : « Commune » puis « Mme NOM », pour les maires,
   s'écrivent sur deux lignes, comme sur la carte imprimée. */
.carte__etiquette {
  font: 500 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-neutral-900);
  white-space: pre;
}

/* Le halo que le moteur demande quand le texte doit rester lisible sur une photographie aerienne.
   **Une ombre portee et non un fond plein** : un rectangle blanc sous chaque etiquette cacherait
   la forme qu'elle nomme.

   **Un blanc fixe, pas le jeton de surface** : la tuile derriere l'etiquette ne change pas avec le
   theme de l'application. En sombre, `--color-surface` posait un halo presque noir autour du seul
   texte que le moteur demande d'entourer, qui est noir. Meme raison que les trois jetons de refus
   plus haut : ce qui se lit sur une carte ne suit pas le theme. */
.carte__etiquette--sur-fond {
  text-shadow:
    0 0 2px #ffffff,
    0 0 4px #ffffff,
    0 0 6px #ffffff;
}

/* Le halo que le moteur declare autour d'une etiquette : un trait de l'epaisseur donnee, centre
   sur le contour des lettres et peint sous elles, comme le trace du moteur. Couleur et epaisseur
   arrivent par deux variables que `carte.js` pose sur l'etiquette. */
.carte__etiquette--halo {
  -webkit-text-stroke: var(--etiquette-halo-epaisseur, 0) var(--etiquette-halo-couleur, transparent);
  paint-order: stroke fill;
}

/* **En plein ecran, la grille devient la page.** Le navigateur lui donne toute la fenetre mais
   pose derriere elle un fond noir par defaut : sans cette ligne, les deux barres flottent sur du
   noir.

   **C'est la grille entiere qui s'etend depuis le 2026-08-20**, et non la seule colonne de
   gauche : celle-ci excluait les panneaux, qui se retrouvaient hors du cadre — plus moyen de
   cocher une couche en plein ecran. Antoine l'a demande. */
/* **Les panneaux sont replies par defaut en plein ecran**, et la poignee les ouvre. La colonne
   passe a zero plutot que d'etre masquee par `display: none`, qui couperait son defilement
   interne et la ferait sauter a l'ouverture.

   **`visibility: hidden` en plus de la largeur nulle, et c'est le correctif d'un vrai defaut.**
   Une largeur de zero fait disparaitre la colonne a l'oeil, pas du parcours de tabulation :
   mesure en contre-revue, cinq commandes sur six restaient atteignables au clavier. Quelqu'un qui
   navigue ainsi tombait dans des cases a cocher et des replis qu'il ne voyait pas. `visibility`
   les retire du parcours, et se leve avec l'ouverture. */
.carte:fullscreen {
  background: var(--color-bg);
  grid-template-columns: minmax(0, 1fr) 0;
}

.carte:fullscreen.carte--panneaux-ouverts {
  grid-template-columns: minmax(0, 1fr) 268px;
}

.carte:fullscreen .carte__panneaux {
  overflow: hidden;
  visibility: hidden;
}

/* **`hidden` et non `auto`, comme hors plein écran.** Cette règle est plus précise que celle de
   la colonne : elle y réimposait le défilement d'ensemble que le 2026-09-05 a retiré. Sans
   conséquence visible — les deux panneaux se compriment —, mais le jour où l'un cesserait de se
   comprimer, le défaut serait revenu en plein écran seulement. */
.carte:fullscreen.carte--panneaux-ouverts .carte__panneaux {
  overflow: hidden;
  visibility: visible;
}

/* La poignee, posee au bord droit de la carte en plein ecran. Elle n'existe pas ailleurs : le
   gabarit la rend `hidden`, et le code de la carte ne la revele qu'en plein ecran. */
.carte__poignee {
  position: absolute;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  z-index: 500;
  padding: 10px 8px;
  border: 2px solid var(--color-text);
  border-right: 0;
  background: var(--color-surface);
  color: var(--color-text);
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  writing-mode: vertical-rl;
  cursor: pointer;
}

.carte__poignee[hidden] {
  display: none;
}

/* Panneaux ouverts, la poignee se pose contre leur bord gauche. Sans cette ligne elle passait
   par-dessus leurs trente derniers pixels, ascenseur compris — mesure en contre-revue. */
.carte:fullscreen.carte--panneaux-ouverts .carte__poignee {
  right: 268px;
}

/* **L'opacite de la couche du dessus d'un fond compose ne s'ecrit pas ici** (releve en revue le
   2026-09-18) : la bibliotheque de carte repeint le style en ligne du conteneur de la couche
   depuis ses propres options, et une regle de classe perd contre elle. Elle vit donc dans
   `carte.js`, avec la raison. */

/* Le repere de la poignee, qui est en position absolue. Sans lui, elle se placerait par rapport
   a la page et non par rapport a la carte. */
.carte {
  position: relative;
}

/* Les deux barres qui encadrent la carte. Meme composition, hauteurs de la maquette : 8/14 en
   haut, 7/14 en bas. `flex-wrap` : sur une fenetre etroite, elles passent a la ligne plutot que
   de pousser les commandes hors de l'ecran. */
.carte__barre {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--color-surface);
  flex-wrap: wrap;
}

.carte__barre--haut {
  padding: 8px 14px;
  border-bottom: 1px solid var(--color-divider);
}

.carte__barre-espace {
  flex: 1;
  min-width: 8px;
}

/* Une commande de barre : plus petite que le bouton ordinaire, comme la maquette. */
.carte__commande {
  padding: 4px 8px;
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* **Une commande enclenchee se voit, et pas seulement pour un lecteur d'ecran.** L'etat vivait
   dans `aria-pressed` depuis toujours : le bouton l'annoncait aux outils d'accessibilite et ne
   changeait pas d'un pixel a l'oeil. Demande par Antoine le 2026-09-07, pour les etiquettes.

   **Discret, et c'est le mot qu'il a employe** : le fond du produit et un filet, pas une couleur
   d'alerte. Le meme motif sert a toutes les commandes enclenchables — etiquettes, legende, plein
   ecran — sans qu'aucune ait a le redire. */
.carte__commande[aria-pressed="true"] {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-bg);
}

/* Le dessin pose devant l'intitule, comme la maquette le montre. Il herite de la couleur du
   texte, donc il grise avec le bouton quand la commande n'existe pas encore. */
.carte__icone-commande {
  width: 13px;
  height: 13px;
  flex: none;
}

/* Le groupe des trois segments : une seule bordure autour, un filet entre chacun. C'est ce qui
   fait lire « un choix parmi trois » plutot que « trois boutons ». */
.segments {
  display: flex;
  border: 2px solid var(--color-text);
  flex: none;
}

/* Un segment servi masque le reste : `display: flex` battrait `hidden` (le reglage de la legende,
   que le script allume). */
.segments[hidden] {
  display: none;
}

/* Les segments sont des liens depuis le 2026-08-19 : `display` et `text-decoration` sont donc
   poses ici, un `<a>` n'etant ni une boite ni du texte nu comme l'etait le bouton. */
.segment {
  display: inline-block;
  padding: 6px 10px;
  background: transparent;
  border: 0;
  border-right: 1px solid var(--color-divider);
  color: var(--color-text);
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}

.segment:last-child {
  border-right: 0;
}

.segment--actif {
  background: var(--color-accent);
  color: var(--color-bg);
}

/* **Le sélecteur des trois vues du FGF, en pilule** (maquette `crm.html`, Antoine, 2026-09-26) :
   fond gris clair, segment actif blanc et ombré, texte vert. Un modificateur, parce que la carte
   emploie les mêmes segments et garde les siens. */
.segments--pilule {
  padding: 3px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-100);
}

.segments--pilule .segment {
  padding: 3px 11px;
  border-right: 0;
  border-radius: 999px;
  font: 600 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-neutral-700);
}

.segments--pilule .segment--actif {
  background: var(--crm-blanc);
  color: var(--color-accent);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
}

/* **Le segment desactive n'est pas un `.btn`**, donc la regle globale du gris ne l'atteint pas :
   elle est reprise ici. Sans elle, un segment eteint se lirait comme un segment disponible. */
.segment[disabled] {
  color: var(--color-text-muted);
  cursor: not-allowed;
}

/* La barre qu'un mode ouvre sous celle du haut : meme hauteur et meme filet que les deux autres
   barres de l'ecran, pour qu'elles se lisent comme une seule pile. */
/* **La même marge interne que la barre du haut, et elle manquait.** Sans elle le contenu
   commence au bord exact de la barre : l'intitulé « MESURER », en majuscules espacées, se lit
   comme s'il était coupé — c'est ce qu'Antoine a relevé le 2026-08-22, capture à l'appui. La
   barre du haut avait sa marge depuis toujours ; celle du mode ne l'a jamais eue, et ça ne se
   voyait pas tant qu'aucun mode ne commençait par du texte. */
.carte__barre--mode {
  border-top: 1px solid var(--color-divider);
  padding: 8px 14px;
}

.carte__intitule-de-mode {
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-text-muted);
  flex: none;
}

/* La phrase qui dit comment se sert le mode. Discrete : c'est un mode d'emploi, pas une commande. */
.carte__phrase-de-mode {
  font: 500 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-text-muted);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Le resultat d'une mesure, a cote de la phrase du mode.
   Plus lisible que la phrase qui le precede — c'est le seul chiffre de la barre, et celui qu'on
   vient chercher. Il reste vide tant qu'on n'a rien trace, et ne prend alors aucune place. */
.carte__mesure {
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-neutral-800);
  white-space: nowrap;
  margin-inline-start: auto;
}

/* --- Le profil altimetrique (maquette validee le 2026-09-26) ---------------------------------

   **Une bande de 156 px sous la carte**, ouverte au double-clic qui finit la ligne. Elle prend sa
   hauteur a la carte, et c'est le prix assume par la maquette : une coupe se lit de gauche a
   droite, sur toute la largeur. */
.carte__profil {
  flex: none;
  height: 156px;
  position: relative;
  padding: 8px 12px 6px;
  background: var(--crm-blanc);
  border-top: 1px solid var(--color-neutral-300);
}

.carte__profil[hidden] {
  display: none;
}

.carte__profil svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.carte__profil-graduation {
  font: 500 var(--taille-etiquette) var(--font-body);
  fill: var(--color-neutral-600);
}

.carte__profil-axe {
  stroke: var(--color-neutral-300);
  stroke-width: 1;
}

.carte__profil-guide {
  stroke: var(--color-neutral-200);
  stroke-width: 1;
}

.carte__profil-courbe {
  fill: none;
  stroke: var(--color-accent-500);
  stroke-width: 2;
  stroke-linejoin: round;
}

.carte__profil-aire {
  fill: var(--color-accent-100);
}

/* L'ecart entre terrain et surface : plein au-dessus (bati, canopee), hachure en dessous (creux :
   carriere, fosse). Le remplissage du creux est son motif, pose par le script. */
.carte__profil-ecart-dessus {
  fill: var(--profil-ecart-dessus);
  fill-opacity: .6;
}

.carte__profil-ecart-dessous {
  stroke: var(--profil-ecart-dessous);
  stroke-width: 1;
}

.carte__profil-creux-fond {
  fill: var(--profil-ecart-dessous);
  fill-opacity: .14;
}

.carte__profil-creux-trait {
  stroke: var(--profil-ecart-dessous);
  stroke-width: 1.5;
}

/* **Le trou, jamais un plateau** : un bout de ligne hors du relief connu se hachure. */
.carte__profil-trou {
  stroke: var(--color-neutral-400);
  stroke-width: 1;
  stroke-dasharray: 3 3;
}

.carte__profil-hachure-fond {
  fill: var(--color-neutral-100);
}

.carte__profil-hachure-trait {
  stroke: var(--color-neutral-300);
  stroke-width: 2;
}

.carte__profil-mention {
  font: 600 var(--taille-etiquette) var(--font-body);
  fill: var(--color-neutral-700);
}

.carte__profil-survol-trait {
  stroke: var(--color-neutral-800);
  stroke-width: 1;
  stroke-dasharray: 2 2;
}

.carte__profil-survol-point {
  fill: var(--crm-blanc);
  stroke: var(--color-accent-500);
  stroke-width: 2;
}

.carte__profil-capte {
  fill: transparent;
  cursor: crosshair;
}

.carte__profil-bulle {
  position: absolute;
  top: 2px;
  transform: translateX(-50%);
  background: var(--crm-blanc);
  border: 1px solid var(--color-neutral-400);
  box-shadow: 0 2px 6px rgba(0, 0, 0, .14);
  font: 600 var(--taille-etiquette) var(--font-body);
  padding: 2px 7px;
  white-space: nowrap;
  pointer-events: none;
  font-variant-numeric: tabular-nums;
}

/* Sur la carte : le point qui suit le survol de la courbe, et la ligne en deux traits quand un
   bout sort du relief. **La teinte du trace est celle de l'outil de trace**, reprise ici pour que
   la ligne ne change pas de couleur en passant en deux morceaux. */
.carte__profil-curseur {
  fill: #fff;
  stroke: var(--color-accent-500);
  stroke-width: 3;
}

.carte__profil-halo {
  fill: var(--ef-sun);
  fill-opacity: .35;
  stroke: none;
}

.carte__profil-connu {
  fill: none;
  stroke: #3388ff;
  stroke-width: 3;
}

.carte__profil-hors-relief {
  fill: none;
  stroke: #3388ff;
  stroke-width: 3;
  stroke-dasharray: 2 6;
  stroke-linecap: round;
}

/* Le repere de projection, sous la carte. Discret : c'est un renseignement, pas une commande. */
/* La barre d'echelle, sous le fond de plan (Antoine, 2026-09-26 : elle remplace le champ de
   saisie). Quatre cases alternees, noires et blanches, et trois reperes dessous. */
.carte__echelle {
  display: flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
  flex: 0 1 auto;
  margin: 0;
}

.carte__echelle-titre {
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-text-muted);
  white-space: nowrap;
}

/* La barre elle-meme : sa largeur est posee par le script, a la longueur ronde qu'elle represente.
   **Des teintes fixes et non des jetons** : la pastille reste blanche en mode sombre, et le jeton
   du noir y deviendrait clair. */
.carte__echelle-barre {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.carte__echelle-cases {
  display: flex;
  height: 5px;
  border: 1px solid #2d2b2b;
}

.carte__echelle-cases > span {
  flex: 1;
  background: #2d2b2b;
}

.carte__echelle-cases > span:nth-child(even) {
  background: #fff;
}

.carte__echelle-reperes {
  display: flex;
  justify-content: space-between;
  font: 500 var(--taille-etiquette)/1.1 var(--font-body);
  font-variant-numeric: tabular-nums;
  color: #2d2b2b;
  white-space: nowrap;
}

.carte__fond {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  flex: 0 1 auto;
  margin: 0;
}

.carte__fond-titre {
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-text-muted);
  white-space: nowrap;
  flex: none;
}

.carte__fond-choix {
  padding: 1px 6px;
  font: 600 var(--taille-etiquette)/1.15 var(--font-body);
  height: 22px;
  min-height: 0;
  min-width: 0;
}

/* **La hauteur doit être posée ici**, et c'est une contrainte de la bibliothèque de cartographie :
   sans hauteur explicite sur son conteneur, elle dessine une carte de zéro pixel — visible comme
   une page vide, sans aucune erreur. La largeur, elle, suit la colonne. */
.carte__toile {
  /* **La toile prend ce qui reste entre les deux barres**, et non une fraction de la fenetre :
     `60vh` laissait une bande grise sous la carte, releve par Antoine sur la version en ligne.
     La hauteur reste explicite au sens de la bibliotheque de cartographie — elle vient du parent
     et non du contenu —, ce qui est sa seule exigence. */
  flex: 1;
  min-height: 0;
  width: 100%;
}

/* La colonne de droite. Fond de surface pour se distinguer de la carte sans lui voler
   l'attention.

   **Ce n'est pas la colonne qui défile, c'est la liste des couches**, depuis la planche validée
   le 2026-09-05. La colonne défilait entière depuis le 2026-08-18, et l'encart Parcelle partait
   alors hors de l'écran dès qu'on descendait dans les cinquante-deux couches. Il est désormais
   posé en bas et la liste prend ce qui reste. Deux notes se contredisaient ici jusqu'au
   2026-09-05 : celle-ci remplace les deux. */
.carte__panneaux {
  /* Le repere du reservoir des couches, pose par-dessus les panneaux (2026-09-25). */
  position: relative;
  background: var(--color-surface);
  display: flex;
  flex-direction: column;
  /* L'écart et la marge des cadres blancs, sur le gris de la colonne (2026-10-03). */
  gap: 8px;
  padding: 8px;
  min-width: 0;
  /* `min-height: 0` sans quoi un enfant de grille refuse de descendre sous la taille de son
     contenu, et rien ne défile nulle part. */
  overflow: hidden;
  min-height: 0;
}

/* Le panneau des couches prend la hauteur restante, et defile chez lui.

   **Le defilement est porte par le panneau, et le titre y colle** (`position: sticky` plus bas) —
   et non par un conteneur interieur en `flex: 1`, qui etait le premier montage. Mesure au
   navigateur du 2026-09-05 : un `<details>` mis en `display: flex` n'a pas ses enfants pour
   enfants. Les moteurs recents glissent une boite anonyme entre le `<summary>` et le reste
   (`::details-content`), si bien que le conteneur interieur ne s'etirait pas : il gardait la
   hauteur de son contenu, ne defilait jamais, et sur cinquante-deux couches le bas de la liste
   devenait inatteignable — coupe par le `overflow: hidden` du panneau. */
.panneau--couches {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

/* **Replié, il ne réclame plus rien.** Sans cette ligne, son `flex: 1` continuerait de
   s'appliquer : un panneau fermé absorberait toute la place libre de la colonne — pas la hauteur
   qu'il avait ouvert, comme cette note l'a dit à tort jusqu'au 2026-09-05 — et laisserait un
   grand vide au-dessus de l'encart. */
.panneau--couches:not([open]) {
  flex: none;
}

/* **Le titre reste sous les yeux pendant que la liste passe dessous.** Il porte le compte du
   groupe et le repere vert ; le laisser partir au defilement rendait la colonne illisible des la
   deuxieme famille. Le fond est obligatoire : sans lui, la liste se lirait au travers. */
.panneau--couches .panneau__titre,
.panneau--parcelle .panneau__titre {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--color-accent-100);
}

/* **L'encart Parcelle est figé en bas de la colonne** : c'est là que la planche validée le
   2026-09-05 le pose, et c'est ce qui permet de cliquer une forme puis de lire ce qu'elle porte
   sans avoir à remonter.

   `margin-top: auto` et non le seul `flex: 1` du panneau des couches : celui-ci disparaît dès
   qu'on replie « Couches », et l'encart remontait alors se coller sous le panneau fermé, le vide
   passant dessous. Relevé en revue le 2026-09-05.

   Il garde sa hauteur naturelle et reste repliable ; plus haut que la moitié de la colonne, il
   défile chez lui plutôt que d'écraser la liste — et c'est **son corps** qui défile, pas le
   `<details>` entier, sans quoi le titre et la référence cadastrale partiraient avec. */
.panneau--parcelle {
  flex: none;
  margin-top: auto;
  max-height: 50%;
  overflow-y: auto;
}

/* **Couches replié, le plafond se lève.** Quelqu'un qui referme la liste le fait pour lire la
   parcelle : la brider à la moitié lui laisserait l'autre moitié vide sous les yeux. */
.panneau--couches:not([open]) ~ .panneau--parcelle {
  max-height: none;
}

/* **Les deux volets en cadres blancs arrondis** (maquette « Carte, seconde lecture », 2026-10-03),
   le cadre commun de la doctrine (regle 10) sur le gris de la colonne. */
.carte__panneaux > .panneau {
  border: 1px solid var(--color-divider);
  border-radius: var(--rayon-cadre);
  background: var(--crm-blanc);
}

/* Le bandeau du titre suit l'arrondi du cadre : le cadre ne rogne pas, il défile chez lui. */
.carte__panneaux > .panneau > .panneau__titre {
  border-radius: var(--rayon-cadre) var(--rayon-cadre) 0 0;
}

.carte__panneaux > .panneau:not([open]) > .panneau__titre {
  border-radius: var(--rayon-cadre);
}

/* Un panneau depliable de la colonne. Le pliage est porte par le navigateur : rien a autoriser
   cote politique de securite, et il marche sans script. */
.panneau {
  border-bottom: 1px solid var(--color-divider);
}

.panneau__titre {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  cursor: pointer;
  /* Le marqueur natif est retire des trois moteurs et remplace par le mot du compte a droite,
     comme la maquette. Meme raison qu'aux pastilles d'etat : `display: flex` le retire dans
     Chrome seulement. */
  list-style: none;
}

.panneau__titre::-webkit-details-marker {
  display: none;
}

.panneau__titre:hover {
  background: var(--color-neutral-200);
}

/* **Les deux titres de panneau sur fond vert clair** — la teinte que la maquette pose sur ce
   bandeau. Seul « Couches » la portait, pour en faire un repère unique ; Antoine a demandé
   l'inverse le 2026-09-05, l'encart Parcelle devant porter la même couleur que Couches.

   Mesures sur cette teinte : 14,56:1 pour le titre en thème clair, 13,13:1 en sombre ; 5,72:1 et
   8,11:1 pour le compte à sa droite. Le seuil du produit est 4,5:1.

   Le survol monte d'un cran plutôt que de passer au gris : un bandeau qui changerait de famille
   de couleur au passage de la souris se lirait comme un autre élément. */
.panneau--couches .panneau__titre:hover,
.panneau--parcelle .panneau__titre:hover {
  background: var(--color-accent-200);
}

/* **Le mot d'une commande de la barre, dans son propre element.** Celui du plein ecran change au
   clic, et l'ecrire sur le bouton entier emportait son dessin. Il ne porte aucune mise en forme
   propre : il herite du bouton, comme quand il en etait le seul texte. */
.carte__libelle-commande {
  display: contents;
}

/* --- La police de la bibliotheque de cartographie -------------------------------------- */

/* **Leaflet impose ses propres polices, et sa feuille passe apres la notre.** Elle est chargee
   par `{% block tete %}` de l'ecran, donc plus bas dans la page que `ef360.css` : a specificite
   egale, c'est elle qui gagne. Resultat mesure : la mention de source sous la carte s'affichait
   en Helvetica ou Arial, et les deux boutons de zoom en Lucida Console — trois polices etrangeres
   sur un ecran qu'Antoine regarde. C'est l'autre moitie de ce qu'il a signale le 2026-08-18 en
   disant que certaines polices n'etaient pas les bonnes.

   **On surcharge ici plutot que de modifier le fichier vendu** : un fichier de bibliotheque
   retouche a la main se perd a la premiere mise a jour, sans que rien ne le dise. La specificite
   est montee d'un cran (`.carte` devant) pour repasser devant la sienne.

   Les tailles et les graisses de Leaflet sont laissees telles quelles : seule la famille change. */
.carte .leaflet-container,
.carte .leaflet-control-zoom-in,
.carte .leaflet-control-zoom-out,
.carte .leaflet-container a.leaflet-popup-close-button {
  font-family: var(--font-body);
}

/* La poignee du panneau : le double chevron de la maquette, 13 px, vers le bas quand c'est
   replie et vers le haut quand c'est ouvert. Antoine a releve le 2026-08-18 qu'il manquait. */
.panneau__chevron {
  width: 13px;
  height: 13px;
  flex: none;
  display: block;
}

.panneau[open] .panneau__chevron {
  transform: rotate(180deg);
}

.panneau__nom {
  font: 700 var(--taille-bloc)/1.2 var(--font-body);
  flex: 1;
}

/* Le compte du panneau : « ? » tant que personne ne sait compter. L'infobulle porte la raison —
   un point d'interrogation seul se lit comme un defaut d'affichage. */
.panneau__compte {
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-neutral-700);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Les cinq renseignements de la parcelle, aux mesures de la maquette : l'intitule a gauche en
   gris, la valeur a droite en gras, un filet pointille entre les deux, et 7 px d'ecart d'une
   ligne a l'autre.

   **Le gris des intitules est celui de la maquette depuis le 2026-09-02**, et non plus le cran
   au-dessus que le panneau des couches s'impose plus bas dans ce fichier. Antoine a regarde les
   deux ecrans cote a cote et tranche : ici, l'ecart se voyait. Le prix est dit ou il se paie,
   dans `docs/DECISIONS.md` — ce gris passe sous le seuil de contraste que le produit se donne
   ailleurs. */
.panneau__renseignements {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 0 14px 10px;
}

/* **`display: flex` l'emporte sur `hidden`**, et c'est ce qui laissait les cinq renseignements
   d'une seule parcelle sous le resume d'une selection de plusieurs. Mesure le 2026-09-17. */
.panneau__renseignements[hidden] {
  display: none;
}

/* L'ecran scinde (Antoine, 2026-09-17) : deux tiers de carte, un tiers de classeur. Le tiroir
   traverse les deux colonnes, sur toute la largeur, parce qu'une table y respire. La grille ne
   prend ses deux rangees qu'une fois le tiroir ouvert : fermee, la carte garde toute la hauteur. */
/* **Chaque piece est placee a la main le temps du tiroir**, et non laissee au placement
   automatique : le tiroir traverse les deux colonnes, et sans placement explicite il repoussait
   le panneau de droite sous la carte. Mesure dans un vrai navigateur le 2026-09-17. */
.carte--scinde .carte__colonne {
  grid-row: 1;
  grid-column: 1;
}

.carte--scinde .carte__panneaux {
  grid-row: 1;
  grid-column: 2;
}

/* **Le partage se fait sur la place disponible, pas sur la fenetre** (2026-09-18) : des hauteurs
   en `vh` additionnaient les bandeaux du haut et poussaient le bas du tiroir sous le pli, ou ses
   pages devenaient invisibles. Les deux rangees prennent donc ce que le cadre leur laisse, la
   carte un peu plus de trois cinquiemes et le tiroir le reste — « l'ecran peut etre plus haut que
   ca », Antoine.

   `minmax(0, …)` sur les deux : sans lui, une piste refuse de descendre sous la hauteur de son
   contenu, et la table du tiroir pousse la carte hors de l'ecran. */
.carte--scinde {
  grid-template-rows: minmax(0, 1.55fr) minmax(0, 1fr);
}

.carte--scinde .carte__scene {
  min-height: 0;
}

.carte--scinde .carte__colonne,
.carte--scinde .carte__panneaux {
  min-height: 0;
}

.carte--scinde .carte__tiroir {
  grid-row: 2;
  grid-column: 1 / -1;
  min-height: 0;
}

/* **Le fond de la page et un filet fin** (maquette « Carte, seconde lecture », 3.4) : la table
   s'y pose dans son cadre blanc, comme dans la vue par onglet du FGF. */
.carte__tiroir {
  grid-column: 1 / -1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--color-bg);
  border-top: 1px solid var(--color-divider);
}

/* **La languette de l'ecran scinde** (maquette « Carte, seconde lecture », 5.1, 2026-10-03) :
   centree au bas de la carte. Le bas de la scene etant le bord haut du tiroir, elle s'y pose
   d'elle-meme quand il s'ouvre, et devient la poignee de hauteur (Antoine, 2026-09-21 : « la
   souris se transforme en fleche verticale au survol »). Au-dessus des calques de la carte. */
.carte__languette {
  position: absolute;
  left: 50%;
  bottom: 0;
  z-index: 1001;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 14px;
  border: 1px solid var(--color-divider);
  border-bottom: 0;
  border-radius: var(--rayon-cadre) var(--rayon-cadre) 0 0;
  background: var(--crm-blanc);
  color: var(--color-text);
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  white-space: nowrap;
  cursor: pointer;
  touch-action: none;
}

.carte__languette[aria-expanded="true"] {
  cursor: row-resize;
}

.carte__languette:hover,
.carte__languette:focus-visible {
  color: var(--color-accent);
}

.carte__languette-fleche::before {
  content: "\25B4";
}

.carte__languette[aria-expanded="true"] .carte__languette-fleche::before {
  content: "\25BE";
}

.carte__tiroir[hidden] {
  display: none;
}

/* **Le corps ne defile plus en entier** : la ligne des onglets reste sous les yeux et c'est la table
   qui bouge, dans son propre cadre (Antoine, 2026-09-18). */
/* **Aucune marge laterale ici** (Antoine, 2026-09-18) : la ligne des onglets touche les deux bords du
   tiroir, et ce sont les blocs sous elle qui reprennent le retrait. */
.carte__tiroir-corps {
  flex: 1;
  min-height: 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0 0 8px;
}

/* **Le tableau et la fiche d'une zone, cote a cote** (maquette « Zone », 2026-09-25). Sans zone
   choisie, la fiche est `hidden` et le tableau prend toute la largeur. */
.carte__tiroir-contenu {
  flex: 1;
  min-height: 0;
  display: flex;
}

/* La ligne de la zone choisie : fond vert pale, filet vert a gauche. **La premiere case se vise
   par la regle de la colonne figee**, sans quoi celle-ci l'emporte et la case reste blanche. */
.classeur-ligne--zone-choisie > td {
  background: var(--color-accent-100);
}

.classeur-table .table tbody tr.classeur-ligne--zone-choisie > td:first-child {
  background: var(--color-accent-100);
  box-shadow: inset 3px 0 0 var(--color-accent), inset -1px 0 0 var(--color-neutral-400);
}

/* La fiche ouverte retrecit le tableau : la barre d'onglets defile plutot que de passer sur deux
   lignes. **La fiche d'une zone comme celle d'un compte** (cadre commun, 2026-09-26). */
.carte__tiroir-contenu:has(> [data-fiche-du-compte]:not([hidden])) .tiroir__barre,
.carte__tiroir-contenu--avec-fiche .tiroir__barre {
  flex-wrap: nowrap;
  overflow-x: auto;
}

.carte__tiroir-contenu:has(> [data-fiche-du-compte]:not([hidden])) .tiroir__barre > *,
.carte__tiroir-contenu--avec-fiche .tiroir__barre > * {
  flex: none;
}

/* **Le cadre commun des fiches de l'ecran scinde** (Antoine, 2026-09-26) : la fiche d'une zone
   et celle d'un compte-proprietaire en derivent (`_cadre_de_fiche.html`), et se comportent donc de
   la meme facon. 360 px de large, de haut en bas du tiroir, a cote du tableau ; l'en-tete reste,
   le corps defile. **Aucune regle de place ni de hauteur ne vise leurs classes propres** : un
   controle le garde. */
.fiche-cadre {
  display: flex;
  flex: none;
  flex-direction: column;
  width: 360px;
  min-height: 0;
  overflow: hidden;
  border-left: 2px solid var(--color-accent);
  background: var(--color-bg);
}

.fiche-cadre[hidden] {
  display: none;
}

.fiche-cadre__contenu {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

.fiche-cadre__tete {
  display: flex;
  flex: none;
  align-items: flex-start;
  gap: 8px;
  padding: 9px 11px;
  background: var(--color-accent);
  color: #fff;
}

.fiche-cadre__etiquette {
  display: block;
  font-size: var(--taille-etiquette);
  font-weight: 800;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  opacity: 0.8;
}

.fiche-cadre__titre {
  font-size: var(--taille-ecran);
}

.fiche-cadre__tete > .croix-de-fermeture {
  margin: -6px -6px -6px auto;
}

.fiche-cadre__corps {
  display: grid;
  flex: 1;
  align-content: start;
  gap: 11px;
  min-height: 0;
  overflow-y: auto;
  padding: 10px 11px;
}

/* Dans le corps du cadre, qui porte deja le retrait. */
.fiche-de-zone__mot {
  margin: 0;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.fiche-de-zone__reglages {
  display: grid;
  gap: 6px;
}

.fiche-de-zone__reglage {
  display: grid;
  grid-template-columns: 120px 1fr;
  gap: 6px;
  align-items: center;
  margin: 0;
  font-size: var(--taille-etiquette);
}

.fiche-de-zone__libelle {
  color: var(--color-neutral-700);
}

.fiche-de-zone__menu {
  padding: 5px 6px;
  border: 1px solid var(--color-neutral-400);
  background: var(--color-surface);
  font: 600 var(--taille-etiquette) var(--font-body);
}

.fiche-de-zone__chiffres {
  margin: 0;
  font-size: var(--taille-etiquette);
  color: var(--color-neutral-800);
}

.fiche-de-zone__chiffres strong {
  font-size: var(--taille-ecran);
}

.fiche-de-zone__bloc {
  margin: 0;
}

.fiche-de-zone__titre-de-bloc {
  margin: 0 0 5px;
  font-size: var(--taille-texte);
  font-weight: 800;
  color: var(--color-neutral-700);
}

.fiche-de-zone__barre {
  display: flex;
  height: 14px;
  border: 1px solid var(--color-neutral-300);
  background: var(--color-neutral-300);
}

/* Ni largeur ni fond ici : la part et la couleur arrivent par `data-`, comme sur l'Avancement. */
.fiche-de-zone__segment {
  flex-basis: 0;
  min-width: 2px;
}

.fiche-de-zone__etats {
  display: grid;
  gap: 2px;
  margin: 6px 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--taille-etiquette);
}

.fiche-de-zone__etat {
  display: grid;
  grid-template-columns: 12px 1fr auto auto;
  gap: 6px;
  align-items: center;
}

.fiche-de-zone__pastille {
  display: block;
  width: 10px;
  height: 10px;
  background: var(--color-neutral-300);
}

.fiche-de-zone__surface {
  font-style: normal;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.fiche-de-zone__part {
  min-width: 44px;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.fiche-de-zone__a-regarder {
  display: grid;
  gap: 4px;
}

.fiche-de-zone__parcelle {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0 8px;
  padding: 5px 7px;
  border: 1px solid var(--color-neutral-300);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--taille-etiquette);
  text-decoration: none;
}

.fiche-de-zone__parcelle b {
  color: var(--color-accent-500);
}

.fiche-de-zone__parcelle small {
  grid-column: 2;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.fiche-de-zone__echange {
  margin: 0;
  padding: 6px 8px;
  border: 1px solid var(--color-neutral-300);
  background: var(--color-surface);
  font-size: var(--taille-etiquette);
  color: var(--color-neutral-800);
}

.fiche-de-zone__echange a {
  font-weight: 600;
}

/* **La seule ligne visuelle entre la carte et la table.** Elle est verte parce qu'Antoine l'a
   demandee ainsi : c'est elle qui separe les deux moities, a la place du bandeau de titre
   d'avant. Meme vert et meme encre que le bouton principal, pour la meme raison de contraste. */
/* **La barre n'est plus verte** (maquette 3.4, 2026-10-04) : sur le fond du tiroir, des puces
   comme les onglets du FGF, la portee en segment et des boutons secondaires. */
.tiroir__barre {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  color: var(--color-text);
  padding: 8px 10px;
}

/* **Une puce au point de la teinte de sa feuille**, comme `.classeur__onglet` : la classe du FGF
   posee a cote ne fournit que les deux variables du point. */
.tiroir__onglet {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border: 0;
  border-radius: var(--rayon-pilule);
  background: transparent;
  color: var(--color-neutral-700);
  font: 600 var(--taille-etiquette)/1.4 var(--font-body);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.tiroir__onglet::before {
  content: "";
  width: 8px;
  height: 8px;
  flex: none;
  border-radius: 50%;
  background: var(--filet-d-onglet, var(--teinte-d-onglet, transparent));
}

.tiroir__onglet:hover {
  background: var(--color-accent-100);
}

.tiroir__onglet--actif,
.tiroir__onglet--actif:hover {
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-weight: 800;
  cursor: default;
}

/* Comme la puce ouverte du FGF : en theme sombre, le vert sur ce fond reste sous 4,5 pour 1. */
[data-theme="sombre"] .tiroir__onglet--actif {
  color: var(--color-text);
}

/* Un onglet que le moteur ne sait pas encore filtrer : eteint, et sa raison au survol. */
.tiroir__onglet[disabled] {
  color: var(--color-text-muted);
  cursor: not-allowed;
}

.tiroir__onglet[disabled]:hover {
  background: transparent;
}

.tiroir__espace {
  flex: 1;
}

/* Le choix des lignes montrees : celles de la selection, ou toutes (2026-09-23). Les deux boutons
   reprennent l'allure des onglets, dont ils partagent la ligne. */
/* **Un segment depuis le 2026-09-25** (maquette de la carte) : deux choix colles dans un cadre. */
.tiroir__lignes {
  display: inline-flex;
  margin-left: 8px;
}

/* Ce que « voir sur la carte » dit sans quitter la page : rien a montrer, ou une selection
   tronquee. Au-dessus du corps du tiroir, que chaque fragment remplace. */
.tiroir__message {
  margin: 0;
  padding: 4px 10px;
  font-size: var(--taille-etiquette);
  background: var(--warn-bg);
  color: var(--warn-ink);
}

/* Le bouton des colonnes est un bouton secondaire du produit depuis le 2026-10-04 (maquette
   3.4) : son etat enfonce est celui de `.btn[aria-pressed="true"]`. */

/* **La bascule qui ecrit une colonne entiere** (Antoine, 2026-09-18). Elle se lit en permanence,
   et non au seul moment du clic : rien ne s'annule dans le classeur en memoire, et une saisie
   faite sans voir qu'elle portait sur trois cents lignes n'a pour issue que de ne pas enregistrer
   le projet. Allumee, son mot passe donc en inverse video, comme une etiquette d'alerte. */
.tiroir__bascule {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  cursor: pointer;
  font: var(--taille-etiquette)/1.6 var(--font-body);
}

/* **Le carre de la case ne se dessine plus** (Antoine, 2026-09-21) : « le bouton qui se colorie
   suffit ». Elle reste dans la page, et c'est ce qui compte — le formulaire de saisie l'emporte
   par `hx-include`, et elle garde sa place au clavier et pour qui ecoute la page. C'est le meme
   masquage que les libelles caches du produit, pas un `display: none` qui la retirerait des
   deux. */
.tiroir__bascule input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* **Le dessin d'un bouton secondaire** (maquette 3.4) : la bascule se lit comme une commande. */
.tiroir__bascule-mot {
  display: inline-block;
  border: 1px solid var(--color-divider);
  border-radius: var(--rayon-bouton);
  padding: 4px 10px;
  background: var(--crm-blanc);
  color: var(--color-text);
  font-weight: 600;
}

/* **Le focus se voit sur la pastille**, puisque la case ne se dessine plus : sans cette regle, on
   ne saurait plus ou l'on est en parcourant la barre au clavier. */
.tiroir__bascule input:focus-visible + .tiroir__bascule-mot {
  outline: 2px solid var(--ef-sun);
  outline-offset: 2px;
}


.tiroir__mot {
  margin: 8px 0 0;
  padding: 0 10px;
  font-size: var(--taille-etiquette);
}

/* **La table du tiroir est celle du classeur** (Antoine, 2026-09-18), et elle doit tenir dans la
   hauteur du tiroir : sa section et son cadre se plient a la place disponible, et c'est le cadre
   qui defile. le retrait lateral est ici, la ligne des onglets au-dessus touchant les bords. */
.carte__tiroir-corps .classeur__section {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  margin: 0 10px;
  border-width: 1px;
}

.carte__tiroir-corps .classeur-table {
  flex: 1;
  min-height: 0;
  overflow: auto;
}

/* La rangee de pagination du bloc garde sa place sous la table, sans la pousser hors du tiroir. */
.carte__tiroir-corps .classeur__pagination {
  flex: none;
}

/* La sélection de plusieurs parcelles (2026-09-17) : la surface, puis la liste des references,
   bornee en hauteur parce qu'elle peut en compter cent. */
.panneau__selection-surface,
.panneau__selection-pleine {
  margin: 0 14px 7px;
  font-size: var(--taille-etiquette);
  color: var(--color-neutral-800);
}

.panneau__selection-surface strong {
  font-size: var(--taille-texte);
}

.panneau__selection-pleine {
  color: var(--color-danger-600, var(--color-neutral-700));
}

/* Les references en petit et en gris, sous la surface qui compte d'abord (maquette de la carte,
   2026-09-25). */
.panneau__selection-liste {
  margin: 0 14px 9px;
  padding: 0;
  list-style: none;
  max-height: 84px;
  overflow-y: auto;
  color: var(--color-neutral-700);
  font: var(--taille-etiquette)/1.5 var(--font-body);
  font-variant-numeric: tabular-nums;
}

/* Sans selection, le seul geste utile est de choisir : le renvoi vers le FGF attend. */
.panneau--parcelle--vide .panneau__retour {
  display: none;
}

.panneau__renseignement {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding-bottom: 4px;
  font: 500 var(--taille-etiquette)/1.3 var(--font-body);
  border-bottom: 1px dotted var(--color-divider);
}

.panneau__intitule {
  color: var(--color-text-muted);
}

.panneau__renseignement[hidden] {
  display: none;
}

/* --- Rattacher depuis le volet (maquette « Carte, seconde lecture », 5.2, 2026-10-03) --------- */

.panneau__rattachement {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin: 0 14px 10px;
}

.panneau__rattachement[hidden],
.panneau__choix[hidden],
.panneau__refus[hidden] {
  display: none;
}

/* La valeur en lien, le chevron dit qu'elle s'ouvre. */
.panneau__lien {
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-accent);
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
  text-align: right;
  cursor: pointer;
}

.panneau__lien::after {
  content: " \25BE";
}

.panneau__lien:hover,
.panneau__lien:focus-visible {
  text-decoration: underline;
}

.panneau__choix {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px;
  border-radius: var(--rayon-bouton);
  background: var(--color-neutral-100);
}

.panneau__recherche {
  width: 100%;
  border-radius: var(--rayon-bouton);
  font-size: var(--taille-etiquette);
}

.panneau__options {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 180px;
  overflow-y: auto;
}

.panneau__option {
  padding: 4px 8px;
  border: 0;
  border-radius: var(--rayon-bouton);
  background: none;
  color: var(--color-text);
  font: 500 var(--taille-etiquette)/1.3 var(--font-body);
  text-align: left;
  cursor: pointer;
}

.panneau__option:hover,
.panneau__option:focus-visible {
  background: var(--color-accent-100);
  color: var(--color-accent);
}

/* La valeur que les parcelles choisies portent déjà. */
.panneau__option--actuelle {
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-weight: 600;
}

.panneau__refus {
  margin: 0;
  color: var(--message-refus-ink);
  font-size: var(--taille-texte);
}

.panneau__valeur {
  margin: 0;
  font-weight: 600;
  text-align: right;
}

/* Le bouton du panneau prend toute la largeur, comme la maquette : c'est le seul geste de la
   colonne, et un bouton court y flottait sans se distinguer d'une ligne de texte. */
.panneau__action {
  display: block;
  width: calc(100% - 28px);
  margin: 0 14px 12px;
  padding: 7px 10px;
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
}

.panneau__phrase {
  margin: 0 14px 7px;
  font: 500 var(--taille-etiquette)/1.35 var(--font-body);
  color: var(--color-neutral-700);
}

/* --- Les couches du projet, dans le panneau de la carte ---------------------------------- */

/* Ce qu on n a pas su lire, dit comme tel : la meme teinte que les autres etats inconnus du
   produit, pour qu un jaune veuille dire la meme chose partout. */
.panneau__phrase--inconnue {
  color: var(--warn-ink);
}

/* --- LE PANNEAU DES COUCHES, RELEVE SUR LA MAQUETTE ------------------------------------------
   « Ne peux-tu pas utiliser la maquette telle quelle ? » — Antoine, 2026-08-22, apres deux
   redactions faites a l'oeil sur une capture d'ecran.

   **Les valeurs ci-dessous ne sont plus estimees : elles sont copiees du fichier de la maquette**
   (le dessin de la maquette, bloc des couches), ou chaque element porte
   son style en clair. Graisses, tailles, interlignes, espacements, teintes : tels quels.

   **La seule chose qui devie, et elle devie partout de la meme facon : les gris.** La maquette
   ecrit ses petits textes en `--color-neutral-500` et `--color-neutral-600`. Mesures sur le fond
   du panneau, en theme clair : 2,38:1 et 3,55:1, la ou le produit exige 4,5:1. Le plus petit
   texte de l'ecran y serait le moins lisible. Ils passent donc tous en `--color-neutral-700`, qui
   donne 5,38:1 en clair et 8,85:1 en sombre. Rien d'autre n'est touche.

   **Ce qui n'est pas repris non plus : l'estompage.** La maquette pose `opacity: .62` sur la
   rangee d'une couche non remplie. Mesure : le texte principal tombe a 4,37:1 et les lignes
   secondaires a 2,55:1. Une couche eteinte reste dans le projet, et c'est une information ;
   elle se distingue par sa pastille, pas en devenant illisible. */

/* --- L'en-tete d'une famille de couches ------------------------------------------------------
   « ZONES DE TRAVAIL 3 » — le nom en petites capitales espacees a gauche, le compte a droite.
   Le bandeau clair de la maquette est le « fond » qu'Antoine demandait : il donne au panneau ses
   paliers de lecture sans encadrer chaque couche. */
/* Le bloc des vues d'une personne, en tete du panneau des couches (2026-09-20). Replie d'office,
   comme les familles juste dessous : l'ecran est dense, et ce bloc ne sert qu'au moment ou l'on
   change de decor. */
.couches__vues {
  margin: 0;
}

/* **Les affichages enregistres, une icone dans l'en-tete des couches** (maquette de la carte,
   2026-09-25). Posee par rapport a la colonne des panneaux, elle reste en place quand la liste
   defile ; le titre des couches lui laisse sa place a droite. **Centree dans la bande du titre,
   en retrait du bord du cadre** (Antoine, 2026-10-05) : posee a 6 pixels du haut de la colonne,
   elle chevauchait le bord du cadre des couches, qui commence 8 pixels plus bas. */
.couches__vues-titre {
  position: absolute;
  top: 30px;
  right: 20px;
  z-index: 2;
  display: flex;
  margin: 0;
  padding: 4px;
  border: 1px solid var(--color-neutral-400);
  background: var(--color-bg);
  cursor: pointer;
}

.panneau--couches > .panneau__titre {
  padding-right: 48px;
}

.couches__vues-titre::-webkit-details-marker {
  display: none;
}

.couches__vues-corps {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px 14px 12px;
}

.couches__vues-champ {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--taille-texte);
}

.couches__vues-menu,
.couches__vues-saisie {
  width: 100%;
  padding: 4px 6px;
  border: 1px solid var(--color-divider);
  border-radius: 4px;
  background: var(--color-surface);
  color: inherit;
}

/* Cachee par l'attribut `hidden` tant qu'il y a des vues : sans cette regle, le `display: flex`
   du corps la rendrait visible malgre lui. C'est le piege releve le 2026-09-19. */
.couches__vues-phrase[hidden],
.couches__vues-menu[hidden],
.couches__vues-bouton[hidden],
.couches__vues-message[hidden] {
  display: none;
}

.couches__vues-phrase,
.couches__vues-message {
  margin: 0;
  font-size: var(--taille-texte);
  color: var(--color-text-muted);
}

.couches__vues-gestes {
  display: flex;
  gap: 8px;
}

.couches__vues-bouton {
  flex: 1;
}

/* Enregistrer d'un bout, Supprimer de l'autre, loin d'« Appliquer » (chantier 1, 2026-10-02). */
.couches__vues-pied {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.couches__vues-retrait {
  flex: none;
  margin-left: auto;
}

.couches__famille {
  margin: 0;
}

/* Le bandeau lui-meme. C'est desormais le `summary` qui le porte : le groupe est repliable et
   arrive ferme, sur demande d'Antoine du 2026-09-04. Le curseur dit qu'on peut cliquer. */
.couches__famille-titre {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin: 0;
  padding: 8px 14px 6px;
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-divider);
  cursor: pointer;
  list-style: none;
}

.couches__famille-titre::-webkit-details-marker {
  display: none;
}

.couches__famille-titre:hover {
  background: var(--color-neutral-100);
}

/* Le meme double chevron que les panneaux, a la taille du bandeau : vers le bas quand c'est
   replie, vers le haut quand c'est ouvert. `align-self` parce que le bandeau aligne ses lignes
   sur la ligne de base du texte, ou un dessin n'en a pas. */
.couches__famille-chevron {
  width: 10px;
  height: 10px;
  flex: none;
  display: block;
  align-self: center;
}

.couches__famille[open] .couches__famille-chevron {
  transform: rotate(180deg);
}

.couches__famille-nom {
  margin: 0;
  font: 700 var(--taille-texte)/1.2 var(--font-body);
  color: var(--color-neutral-700);
}

/* `margin-left` pousse le compte a droite ; le chevron et le nom restent colles a gauche. */
.couches__famille-compte {
  margin-left: auto;
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-neutral-700);
}


/* --- La poignee de rangement -----------------------------------------------------------------
   La barre pointillee demandee par Antoine le 2026-09-04 : deux colonnes de trois points, tracees
   ici et non par une icone. Toutes les icones du produit viennent de la maquette, et celle-ci n'y
   figure pas ; la dessiner en feuille evite d'en inventer une qui pretendrait en venir.

   `radial-gradient` plutot que six elements : un seul fond, aucun balisage de plus dans une liste
   qui compte deja cinquante-deux rangees. */
.couches__poignee {
  width: 10px;
  height: 16px;
  flex: none;
  align-self: center;
  padding: 0;
  border: 0;
  border-radius: 2px;
  background-color: transparent;
  background-image: radial-gradient(circle, var(--color-neutral-500) 1px, transparent 1.2px);
  background-size: 4px 5px;
  background-position: 1px 1px;
  background-repeat: repeat;
  cursor: grab;
  opacity: .45;
  /* Le doigt qui saisit la poignee deplace la couche, il ne fait pas defiler le panneau. */
  touch-action: none;
  user-select: none;
}

.couches__poignee:hover,
.couches__poignee:focus-visible {
  opacity: 1;
}

/* Ce qu'on saisit s'efface pendant le trajet, et la place visee se marque d'un filet : sans ces
   deux marques, un deplacement long ne dit ni ce qu'on tient ni ou cela tombera. */
.couches__poignee:active {
  cursor: grabbing;
}

.couches__ligne--saisie,
.couches__famille--saisie {
  opacity: .4;
}

/* Le filet se pose du cote ou le bloc tombera, et non toujours en haut : le lacher se fait
   au-dessus ou au-dessous selon la moitie survolee, et un filet toujours en haut annoncait la
   moitie du temps une place qui n est pas la bonne. Releve en revue. */
.couches__ligne--visee-dessus,
.couches__famille--visee-dessus {
  box-shadow: inset 0 2px 0 0 var(--color-accent);
}

.couches__ligne--visee-dessous,
.couches__famille--visee-dessous {
  box-shadow: inset 0 -2px 0 0 var(--color-accent);
}

.couches {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* --- Une rangee de couche --------------------------------------------------------------------
   Deux blocs : le corps — qui porte la case, le nom et le detail — puis la marge de droite. La
   maquette, elle, donne sa colonne a la case ; ici elle reste dans l etiquette pour que le nom
   reste cliquable, et c est le retrait du detail qui refait l alignement.
   **Aucun encadre, aucun fond de
   rangee** : la maquette pose une liste sobre ou seul un filet separe deux couches. Une premiere
   redaction donnait a chaque couche sa fiche a bord arrondi — plus decoratif, et plus loin.

   Les deux remplissages sont ceux de la maquette : 5 px repliee, 9 px deployee. */
.couches__ligne {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 5px 14px;
  border-bottom: 1px solid var(--color-divider);
}

.couches__ligne:has(.couches__case:checked),
.couches__ligne--eteinte {
  padding-top: 9px;
  padding-bottom: 9px;
}

.couches__corps {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

/* La case et le nom sur la meme rangee, le nom cliquable avec elle. */
.couches__etiquette {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  min-width: 0;
  cursor: pointer;
}

/* Une couche que la carte ne sait pas dessiner reste listee — un trou ferait croire qu elle
   n existe pas — mais elle ne se donne pas l air cliquable. */
.couches__ligne--eteinte .couches__etiquette {
  cursor: not-allowed;
}

/* **Et elle se distingue a l oeil, pas seulement a la souris.** La reecriture du panneau avait
   emporte ce signal : il ne restait que le curseur, qui ne dit rien a qui lit, et le gris du
   contour de la case desactivee. Releve en revue.

   `--color-neutral-700` et non un estompage : 5,38:1 en theme clair, 8,85:1 en sombre, la ou le
   seuil du produit est 4,5:1. C est le meme choix qu au reste du panneau, et pour la meme raison
   — une couche eteinte reste dans le projet, et c est une information. */
.couches__ligne--eteinte .couches__nom {
  color: var(--color-neutral-700);
}

/* --- La case a cocher, telle qu'Antoine la decrit --------------------------------------------
   « C'est un carre sobre, colorie en vert lorsqu'il est selectionne (pas de coche). »

   **Le carre remplace celui du navigateur, il ne le recouvre pas.** `appearance: none` retire le
   dessin natif en gardant l'element : le clavier, le libelle cliquable et les aides a la lecture
   d'ecran continuent de fonctionner, ce qu'un faux carre en `<span>` aurait casse.

   Dimensions, contour et teintes viennent de la maquette : 15 px, contour de 2 px a la couleur du
   texte, rempli a l'accent une fois coche. Le decalage de 2 px vers le bas aligne le carre sur la
   premiere ligne du nom, qui est plus haute que lui. */
/* **Une seule case a cocher pour le produit**, comme `.segments` est un seul groupe de segments.
   La carte l'emploie pour ses couches, le classeur pour ses colonnes (Antoine, 2026-09-06) : deux
   regles jumelles finiraient par diverger d'un filet, ce qui est deja arrive une fois ici. */
.ef-case,
.couches__case {
  appearance: none;
  -webkit-appearance: none;
  flex: none;
  width: 15px;
  height: 15px;
  margin: 2px 0 0;
  border: 2px solid var(--color-text);
  border-radius: 0;
  background: transparent;
  cursor: pointer;
}

/* **Sans coche, l'etat ne se dirait plus que par la couleur** — et le produit a deja ete repris
   une fois pour cela (revue du lot B). Le remplissage vert s'accompagne donc d'un contour plus
   epais : deux signaux pour un seul etat, dont un qui survit a une vision des couleurs
   deficiente. L'attribut natif, lui, reste lu par les aides a la lecture d'ecran. */
.ef-case:checked,
.couches__case:checked {
  border-width: 3px;
  border-color: var(--color-accent);
  background: var(--color-accent);
}

.ef-case:disabled,
.couches__case:disabled {
  cursor: not-allowed;
  border-color: var(--color-neutral-400);
}

/* Le contour de mise au point clavier ne doit pas dependre du remplissage : sur une case cochee,
   un contour vert sur fond vert serait invisible. */
.ef-case:focus-visible,
.couches__case:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
}

/* Le nombre d'objets, a cote du nom (Antoine, 2026-09-10). **`flex: none`** : c'est le nom qui
   se coupe quand la place manque, jamais le nombre — un nombre tronque est un chiffre faux. */
/* **`align-self`** : le nom fait 11,5 px et le nombre 9,5 px ; alignes par le haut, le second
   flotte au-dessus de la ligne du premier. La case, elle, reste calee en haut — c'est ce que
   `align-items` du parent lui donne, et une ligne de base la ferait descendre. */
/* Le geste « Placer » des personnes du FGF : un formulaire qui ne doit rien ajouter au bouton. */
.couches__placement {
  display: contents;
}

/* Les personnes du FGF sans point, pliées sous la ligne de leur couche (2026-09-27). */
.couches__sans-point {
  margin: 2px 0 4px 22px;
}

.couches__sans-point > summary {
  cursor: pointer;
}

.couches__sans-point-liste {
  max-height: 160px;
  margin: 4px 0 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
  font: 400 var(--taille-etiquette)/1.35 var(--font-body);
}

.couches__sans-point-liste > li + li {
  margin-top: 3px;
}

.couches__sans-point-motif {
  display: block;
  color: var(--color-neutral-700);
}

.couches__compte {
  align-self: baseline;
  flex: none;
  color: var(--color-neutral-700);
  font: 500 var(--taille-etiquette)/1.3 var(--font-body);
  font-variant-numeric: tabular-nums;
}

.couches__nom {
  align-self: baseline;
  flex: 1 1 auto;
  min-width: 0;
  font: 600 var(--taille-etiquette)/1.25 var(--font-body);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Le detail d'une couche affichee ----------------------------------------------------------
   `display: none` et non une hauteur nulle : ce qui n'est pas montre ne doit pas non plus etre
   atteignable au clavier — meme regle qu'au panneau replie du plein ecran, ou le contraire etait
   un vrai defaut.

   `:has()` et non le combinateur de fratrie : la case a cocher est **dans** le libelle, elle
   n'est donc soeur de rien. Le mecanisme n'est pas neuf ici — la feuille l'emploie deja pour le
   depliage de la barre de titre et pour les droits de l'administration.

   Le retrait de 24 px aligne le detail sous le nom, et non sous la case : 15 px de case plus les
   9 px qui l'en separent. C'est l'alignement de la maquette, ou la case tient sa propre colonne. */
.couches__detail {
  display: none;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  padding-left: 24px;
  min-width: 0;
}

.couches__ligne:has(.couches__case:checked) .couches__detail {
  display: flex;
}

/* **Une couche non dessinable montre son detail sans condition**, et c'est le contraire d'une
   exception decorative : sa case est desactivee, donc rien ne peut jamais la cocher, donc son
   lien « Ouvrir » serait dans la page sans qu'aucun geste ne le revele. Or la consultation en
   table est le **seul** acces a la donnee de ces couches-la. Releve en revue, ou un test
   affirmait un acces qui n'existait pas. */
.couches__ligne--eteinte .couches__detail {
  display: flex;
}


/* Le menu qui choisit comment une couche est peinte, sur une couche affichee. **Il s'ouvre depuis
   le 2026-09-05** : le moteur donne les apparences, le serveur les sert, le script les pose. Le
   curseur ne dit donc plus qu'il est mort. Les 170 px sont le plafond de la maquette. */
.couches__style {
  max-width: 170px;
  min-width: 0;
  margin-top: 2px;
  padding: 3px 6px;
  border: 1px solid var(--color-divider);
  border-radius: 0;
  background: var(--color-surface);
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-text);
  cursor: pointer;
}

/* Le controle qui dit si cette couche porte ses noms. **Aligne sur le menu de style**, dont il
   est le voisin : deux controles de la meme carte qui ne s'alignent pas se lisent comme deux
   choses sans rapport. */
.couches__etiquetage {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: 3px;
  color: var(--color-text);
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  cursor: pointer;
}

/* **`display: flex` bat le `[hidden]` du navigateur**, comme le menu de la carte plus bas :
   sans cette regle, le controle est pose a l'ecran en permanence, y compris sur une couche que le
   moteur ne donne pas a etiqueter — ou le cocher ne fait rien. */
.couches__etiquetage[hidden] {
  display: none;
}

/* **Une liste deroulante depuis le 2026-09-18**, et non plus une case a cocher (Antoine) : elle
   dit *quoi* ecrire sur la couche, « Aucune » comprise. Meme habillage que le menu de style, dont
   elle est la voisine : deux menus de la meme carte qui ne se ressemblent pas se lisent comme deux
   mecanismes differents. Elle prend la place qui reste apres le mot « Etiquette ». */
.couches__menu-d-etiquette {
  flex: 1;
  min-width: 0;
  max-width: 120px;
  padding: 2px 5px;
  border: 1px solid var(--color-divider);
  border-radius: 0;
  background: var(--color-surface);
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-text);
  cursor: pointer;
}

.couches__menu-d-etiquette[hidden] {
  display: none;
}

/* **Le choix de campagne du registre parcellaire graphique** (Antoine, 2026-09-20). Meme
   habillage que l'etiquetage juste au-dessus : deux choix de la meme rangee qui ne se ressemblent
   pas se lisent comme deux mecanismes differents.

   **Pas de regle `[hidden]` ici**, contrairement aux deux menus voisins : celui-ci n'est pas
   servi puis revele par le script — le serveur ne l'ecrit que lorsqu'il y a plusieurs campagnes
   a choisir. Un `display: flex` qui battrait un `[hidden]` inexistant serait une precaution
   contre un mecanisme qui n'existe pas. */
.couches__campagne {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: 3px;
  color: var(--color-text);
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  cursor: pointer;
}

.couches__menu-de-campagne {
  flex: 1;
  min-width: 0;
  max-width: 120px;
  padding: 2px 5px;
  border: 1px solid var(--color-divider);
  border-radius: 0;
  background: var(--color-surface);
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-text);
  cursor: pointer;
}

/* La phrase sous le menu : ce qui empeche cette couche d'etre peinte comme elle devrait. **Une
   lecture, pas une commande** — d'ou le gris et la petite taille, et non celle du menu. */
.couches__origine {
  margin: 0;
  font: 500 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-neutral-700);
}

/* --- La marge de droite : la pastille, puis « Ouvrir » ----------------------------------------
   C'est la colonne que la maquette pose a droite de chaque rangee. Sortir « Ouvrir » du detail
   est ce qui le remet dans le cadre de 268 px — il en depassait, releve par Antoine. */
.couches__marge {
  display: flex;
  flex: none;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}

/* La pastille d'etat se montre sur une ligne repliee comme sur une ligne deployee : on doit
   pouvoir balayer la liste et voir d'un coup ce qui est rempli.

   **La teinte n'est jamais le seul signal** : le mot est ecrit en toutes lettres a l'interieur.
   C'est la regle du produit depuis la revue du lot B, ou une pastille disait son etat par sa
   seule couleur. Les deux couples de teintes sont ceux de la maquette, et ils passent le seuil de
   contraste du produit : 7,04:1 pour « remplie », 5,30:1 pour « jamais alimentee ». */
.couches__etat {
  flex: none;
  padding: 3px 6px;
  border-radius: 0;
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  white-space: nowrap;
}

.couches__etat--remplie {
  background: var(--ok-bg);
  color: var(--ok-ink);
}

.couches__etat--vide,
.couches__etat--inconnu {
  background: var(--void-bg);
  color: var(--void-ink);
}

/* « Ouvrir » : un bouton discret, pas un lien souligne. Il ne parait qu'une fois la couche
   affichee — sauf sur une couche que la carte ne sait pas dessiner, ou la table est le seul
   acces a la donnee. */
.couches__ouvrir {
  display: none;
  flex: none;
  padding: 3px 6px;
  border: 1px solid var(--color-divider);
  background: transparent;
  color: var(--color-text);
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  text-decoration: none;
}

.couches__ligne:has(.couches__case:checked) .couches__ouvrir,
.couches__ligne--eteinte .couches__ouvrir {
  display: block;
}

.couches__ouvrir:hover,
.couches__ouvrir:focus-visible {
  border-color: var(--color-accent);
  background: var(--color-accent);
  color: var(--color-bg);
}

/* Ce qui n a pas pu etre dessine. Ecrit par le script, servi vide. */
.couches__refus {
  margin: 0 14px 10px;
  padding: 6px 8px;
  background: var(--warn-bg);
  color: var(--warn-ink);
  font: 500 var(--taille-etiquette)/1.4 var(--font-body);
}

/* Le meme message, mais sous la case de sa couche : il se cale sur le retrait du detail, et il
   n'a pas la marge du panneau puisqu'il est deja dans une ligne. */
.couches__refus--ligne {
  margin: 0 0 0 24px;
}


/* La note d'emprise : du texte fixe, vrai, et depliable parce qu'il est long. Le vert de l'accent
   la fait lire comme une explication qu'on peut ouvrir, pas comme un avertissement. */
.note {
  margin: 0 14px 10px;
}

.note__titre {
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-accent);
  cursor: pointer;
}

.note__texte {
  margin: 8px 0;
  font: 500 var(--taille-etiquette)/1.45 var(--font-body);
  color: var(--color-neutral-700);
}

.note__liste {
  margin: 0;
  font: 500 var(--taille-etiquette)/1.45 var(--font-body);
}

.note__liste dt {
  font-weight: 700;
}

.note__liste dd {
  margin: 0 0 6px;
  color: var(--color-neutral-700);
}

/* Sous une fenetre etroite, la colonne passe sous la carte plutot que de l'ecraser : a 268 px
   fixes, une fenetre de telephone ne laisserait presque rien a la carte. */
@media (max-width: 900px) {
  .carte {
    grid-template-columns: minmax(0, 1fr);
    /* **La pleine hauteur s'arrete ici.** Empilees dans une fenetre qui ne defile pas, la carte
       et la colonne se partageraient une hauteur d'ecran et deviendraient toutes deux trop
       courtes ; le bas de la colonne serait inatteignable. Sous ce seuil, la page redefile et la
       carte reprend une hauteur fixe. */
    flex: none;
    min-height: auto;
  }

  .ecran--pleine-hauteur {
    overflow: auto;
  }

  .carte__scene {
    flex: none;
    height: 60vh;
    min-height: 0;
  }

  .carte__colonne {
    border-right: 0;
  }

  .carte__panneaux {
    overflow: visible;
    border-top: 2px solid var(--color-text);
  }
}

/* --- Signaler un probleme -------------------------------------------------------------------- */

/* La page entiere, sans script, et la fenetre par-dessus l'ecran : les memes pieces, dans le style
   des ecrans refaits (maquette validee le 2026-09-29). Largeur de lecture : une zone de saisie
   pleine largeur se lit mal, et un signalement se relit avant de partir. */
.signalement {
  max-width: 62ch;
  font: 400 var(--taille-texte)/1.5 var(--font-body);
}

/* Le formulaire dans le cadre commun (maquette 3.10, 2026-10-03). */
.signalement__formulaire {
  padding: 16px 18px;
  border-radius: var(--rayon-cadre);
  background: var(--crm-blanc);
}

.signalement__joint > summary {
  cursor: pointer;
  color: var(--color-text-muted);
  font: 600 var(--taille-etiquette)/1.4 var(--font-body);
}

.signalement__joint > summary + * {
  margin-top: 8px;
}

/* Le titre des reperes est celui du repli : il ne se redit pas dessous. */
.signalement__joint .signalement__sous-titre {
  display: none;
}

/* La zone de saisie deborde la largeur commune des champs : c'est le seul champ de l'application
   ou l'on ecrit plusieurs phrases, et `.champ` borne a 42ch pour les saisies courtes. */
.signalement__formulaire .champ {
  max-width: none;
}

/* **L'étiquette et le champ sont ceux de tout formulaire** (chantier 2, revue 01 §8) : l'étiquette
   en minuscules et le champ arrondi à 12 px, ombré, en faisaient une fenêtre d'un autre produit. */

.signalement__aide {
  margin: 4px 0 14px;
  color: var(--color-neutral-700);
  font: 400 var(--taille-etiquette)/1.5 var(--font-body);
}

/* Ce qui part avec le message : un bloc gris, les reperes en fiches (intitule a gauche, fait a
   droite), comme la fiche du General. */
.signalement__envoi {
  margin: 0 0 16px;
  padding: 10px 14px;
  border-radius: 14px;
  background: var(--color-neutral-100);
}

.signalement__sous-titre {
  margin: 0 0 6px;
  color: var(--color-accent);
  font: 700 var(--taille-texte)/1.4 var(--font-body);
  letter-spacing: normal;
  text-transform: none;
}

.signalement__reperes {
  margin: 0;
}

.signalement__repere {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  gap: 10px;
  padding: 6px 0;
  border-top: 1px solid var(--color-neutral-200);
}

.signalement__repere:first-child {
  border-top: 0;
}

.signalement__intitule {
  color: var(--color-neutral-700);
  font: 400 var(--taille-texte)/1.4 var(--font-body);
}

/* Les erreurs et les echanges refuses tiennent une ligne chacun. */
.signalement__valeur {
  margin: 0;
  font: 600 var(--taille-texte)/1.4 var(--font-body);
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.signalement__details {
  margin: 4px 0 0;
}

.signalement__details summary {
  padding: 4px 0;
  color: var(--color-neutral-700);
  font: 400 var(--taille-texte)/1.4 var(--font-body);
  cursor: pointer;
}

.signalement__details .signalement__reperes {
  margin: 2px 0 0;
}

.signalement__actions {
  display: flex;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 9px;
  margin: 0;
}

/* La fenetre : les arrondis et l'ombre des panneaux. Elle defile d'elle-meme quand les reperes
   depassent la hauteur de l'ecran. */
.fenetre-du-signalement {
  width: min(560px, calc(100vw - 32px));
  max-height: calc(100vh - 48px);
  overflow: auto;
  padding: 18px 22px 20px;
  border: 0;
  border-radius: 18px;
  background: var(--crm-blanc);
  box-shadow: 0 12px 40px rgba(0, 0, 0, .2);
  color: var(--color-text);
}

.fenetre-du-signalement::backdrop {
  background: color-mix(in srgb, #201e1d 35%, transparent);
}

.signalement--fenetre {
  max-width: none;
}

.signalement__en-tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 12px;
}

.signalement__titre {
  margin: 0;
  font: 800 var(--taille-bloc)/1.3 var(--font-heading);
}



.signalement__refus {
  margin: 0 0 14px;
  padding: 10px 14px;
  border: 1px solid var(--color-divider);
  border-left: 4px solid var(--etat-bloque);
  border-radius: var(--rayon-bouton);
  background: var(--message-refus-bg);
  color: var(--message-refus-ink);
  font: 600 var(--taille-texte)/1.5 var(--font-body);
}

.signalement__resultat {
  margin: 0 0 14px;
  padding: 10px 14px;
  border-radius: 12px;
  background: var(--ok-bg);
  color: var(--ok-ink);
  font: 600 var(--taille-texte)/1.5 var(--font-body);
}

.signalement__capture {
  margin: 0 0 14px;
}

.signalement__demande-de-capture {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Masquee quand une capture est jointe : sans cette regle, `display: flex` l'emporte sur `hidden`. */
.signalement__demande-de-capture[hidden] {
  display: none;
}

.signalement__demande-de-capture > .btn {
  flex: none;
  white-space: nowrap;
}

.signalement__aide--capture {
  margin: 0;
}

.signalement__apercu {
  margin: 0;
  overflow: hidden;
  border-radius: 12px;
  background: var(--color-neutral-100);
}

.signalement__image {
  display: block;
  width: 100%;
  max-height: 240px;
  object-fit: contain;
  background: var(--color-neutral-200);
}

.signalement__legende {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 6px 12px;
  font: 600 var(--taille-etiquette)/1.4 var(--font-body);
}

/* --- L'accueil en cartes : « Mes demandes » et « Reprendre un projet » (2026-09-29) ---------- */
.accueil__demandes,
.accueil .accueil__reprise {
  display: flex;
  flex-direction: column;
  margin: 0 24px 14px;
  overflow: hidden;
  border: 0;
  border-radius: 14px;
  background: var(--crm-blanc);
  box-shadow: 0 0 0 1px var(--color-neutral-200);
}

.accueil__carte-tete {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--color-neutral-200);
}

.accueil .accueil__surtitre {
  padding: 0;
  color: var(--color-text);
  font: 800 var(--taille-ecran)/1.4 var(--font-heading);
  letter-spacing: normal;
  text-transform: none;
}

.accueil__reprise > .accueil__surtitre {
  padding: 10px 16px;
  border-bottom: 1px solid var(--color-neutral-200);
}

.accueil .accueil__ligne {
  border-top: 0;
  border-bottom: 1px solid var(--color-neutral-200);
}

.accueil .accueil__vers-la-bibliotheque {
  border-top: 0;
  background: var(--color-neutral-100);
}

.accueil__liste-des-demandes {
  margin: 0;
  padding: 0;
  list-style: none;
}

.accueil__demande {
  padding: 10px 16px;
  border-bottom: 1px solid var(--color-neutral-200);
}

.accueil__demande:last-child {
  border-bottom: 0;
}

.accueil__demande-tete {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.accueil__demande-message {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font: 600 var(--taille-texte)/1.4 var(--font-body);
}

/* Les pastilles de l'accueil : l'etat en toutes lettres, la teinte le redit, jamais seule. */
.accueil__pilule,
.accueil__etat {
  flex: none;
  padding: 0 9px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-200);
  color: var(--color-neutral-800);
  font: 600 var(--taille-etiquette)/19px var(--font-body);
  letter-spacing: normal;
  text-transform: none;
  white-space: nowrap;
}

/* « Nouveau » et « n nouvelles réponses » : un signal de la marque, en vert foret. Le jaune ne
   dit plus que « pas encore enregistre » (revue 01 §4). */
.accueil__pilule--nouveau {
  background: var(--color-accent-100);
  color: var(--color-text);
}

.accueil__pilule--nouveau::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  margin-right: 5px;
  border-radius: 50%;
  background: var(--color-accent);
  vertical-align: 1px;
}

/* Une demande en cours prend l'etat en cours, plus le bleu des processus. */
.accueil__etat--en-cours {
  background: color-mix(in srgb, var(--etat-en-cours) 16%, transparent);
  color: var(--color-text);
}

.accueil__etat--resolue {
  background: var(--ok-bg);
  color: var(--ok-ink);
}

.accueil__demande .accueil__date {
  width: 120px;
  text-align: right;
}

/* Le mot de l'equipe, en bulle comme les echanges du CRM. */
.accueil__reponse {
  margin: 8px 0 2px;
  padding: 8px 12px;
  border-radius: 12px 12px 12px 4px;
  background: var(--color-accent-100);
  font: 400 var(--taille-texte)/1.5 var(--font-body);
  white-space: pre-line;
}

.accueil__reponse-auteur {
  display: block;
  margin-bottom: 2px;
  color: var(--color-accent);
  font: 700 var(--taille-etiquette)/1.4 var(--font-body);
}

/* ------------------------------------------- « Calculer ou mettre a jour » (M12) */

/* Refait le 2026-08-18 a la disposition de la maquette, mesuree sur sa version executable.
   Les deux colonnes ne sont pas decoratives : elles disent que les deux moities du projet se
   chargent separement, l'une en plusieurs minutes et l'autre tout de suite. */
/* **Une seule grille, et c'est un constat de revue.** Le conteneur portait lui aussi deux
   colonnes, que chacun de ses enfants annulait aussitot : un enfant ajoute plus tard sans cette
   annulation serait alle se loger dans la colonne de gauche sans que rien ne le dise. Les deux
   colonnes etaient celles des moities, retirees depuis. */
.calculer {
  display: flex;
  flex-direction: column;
  gap: 24px;
  max-width: 780px;
  margin: 0 auto;
}

.calculer__titre {
  margin: 0;
  font: 800 var(--taille-titre)/1.1 var(--font-heading);
  letter-spacing: -.02em;
}

.calculer__phrase {
  margin: 0;
  font: 500 var(--taille-texte)/1.5 var(--font-body);
  color: var(--color-neutral-700);
  max-width: 76ch;
}

/* Le formulaire qui lance vraiment un calcul. **`display: contents` est ce qui opère** : sans lui,
   le formulaire deviendrait un élément de la rangée souple et le bouton cesserait d'en être un —
   il se retrouverait seul sur sa ligne, à côté de l'indice au lieu d'être aligné avec lui. Avec
   lui, le formulaire ne produit aucune boîte et le bouton reprend sa place.
   *(Une première rédaction posait aussi `margin: 0` en l'annonçant comme le correctif : un élément
   qui ne produit pas de boîte n'a pas de marge rendue, la ligne était donc sans effet. Relevé en
   revue le 2026-08-25.)* */
.calculer__formulaire {
  display: contents;
}

/* Le sélecteur de fichier des trois sources qui en prennent un. **Il prend toute la largeur de la
   carte** : posé dans la rangée souple à côté du bouton, un nom de fichier long — et ce sont
   toujours des noms longs — poussait le bouton hors de la carte. Ce qu'un lecteur d'écran annonce
   à la place de « parcourir » est l'`aria-label` du champ, depuis le 2026-09-03.

   `display: contents` sur le formulaire fait que ce bloc est, lui, un élément direct de la rangée
   souple : d'où la largeur pleine demandée ici et pas sur un parent. */
.calculer__depot {
  flex: 1 1 100%;
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 4px;
}

/* Ce que le classeur depose apporte, montre une fois au retour du depot (2026-09-18). **Ni
   avertissement ni refus** : un constat. D'ou le fond ordinaire et le trait discret de la
   proposition, plutot que le jaune du bandeau d'alerte. */
.calculer__inventaire {
  border: 1px solid var(--color-neutral-300);
  border-left: 3px solid var(--color-accent);
  padding: 13px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}


.calculer__pastille {
  display: inline-block;
  padding: 4px 10px;
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
  border: 1px solid var(--color-neutral-400);
  background: var(--color-surface);
  color: var(--color-neutral-700);
}

.calculer__pastille--ok {
  background: var(--ok-bg);
  color: var(--ok-ink);
  border-color: transparent;
}

/* Les trois choix en pilules (maquette du 2026-09-26) ; la pilule ouverte est pleine, et celle
   que l'etat du projet suggere porte « suggere ». */
.calculer__tuiles {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.calculer__tuile {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  border-radius: 999px;
  background: var(--color-neutral-100);
  box-shadow: 0 0 0 1px var(--color-neutral-200);
  color: var(--color-neutral-800);
  font: 600 var(--taille-texte)/1.2 var(--font-body);
  text-decoration: none;
}

.calculer__tuile:hover {
  box-shadow: 0 0 0 1px var(--color-accent);
}

.calculer__tuile--active {
  background: var(--color-accent);
  box-shadow: none;
  color: var(--rail-ink);
}

.calculer__tuile-icone {
  width: 15px;
  height: 15px;
}

.calculer__tuile-titre {
  font: inherit;
}

/* Le recapitulatif de la mise a jour et son geste dans le cadre commun (maquette 3.6). */
.calculer__cadre {
  margin-top: 20px;
  padding: 2px 18px 16px;
  border-radius: var(--rayon-cadre);
  background: var(--crm-blanc);
}

.calculer__cadre .calculer__fiche {
  margin-top: 0;
  border-top: 0;
}

/* L'avertissement rare, au survol ou au focus de sa marque. */
.calculer__info {
  color: var(--color-text-muted);
  font-size: var(--taille-ecran);
  cursor: help;
}

/* Les lignes d'un choix, un intitule a gauche, comme l'ecran General. */
.calculer__fiche {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr);
  margin: 20px 0 0;
  border-top: 1px solid var(--color-neutral-200);
}

/* **Le libellé se centre comme sa ligne** : calé en haut, il flottait au-dessus du texte d'en
   face dès que la ligne portait un bouton. */
.calculer__fiche > dt {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 10px 0;
  border-bottom: 1px solid var(--color-neutral-200);
  color: var(--color-text-muted);
  font-size: var(--taille-texte);
}

.calculer__fiche > dd {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  margin: 0;
  padding: 10px 0;
  border-bottom: 1px solid var(--color-neutral-200);
}

.calculer__lien {
  color: var(--color-accent-500);
  font-weight: 600;
  font-size: var(--taille-texte);
}

.calculer__droite {
  margin-left: auto;
}

/* Le pied d'un geste : le bouton, et ce qu'il remplace ecrit a cote de lui. */
.calculer__geste {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin-top: 18px;
}

/* **Le bouton se cale à droite** (maquette du 2026-09-26) : posé juste après le texte, il
   suivait sa longueur, et deux lignes voisines n'alignaient pas leurs boutons. */
.calculer__fiche > dd > .btn,
.calculer__fiche > dd > .calculer__formulaire > .btn {
  margin-left: auto;
}

.calculer__fiche .calculer__geste {
  flex-basis: 100%;
  margin-top: 4px;
}

.calculer__perte {
  max-width: 52ch;
  color: var(--color-neutral-700);
  font-size: var(--taille-texte);
}

.calculer__signal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0 0 18px;
  padding: 10px 14px;
  border-radius: 14px;
  background: var(--warn-bg);
  color: var(--warn-ink);
  font-size: var(--taille-texte);
}

.calculer__signal .btn {
  margin-left: auto;
}

@media (max-width: 760px) {
  .calculer__fiche {
    grid-template-columns: 1fr;
  }

  .calculer__fiche > dt {
    padding-bottom: 0;
    border-bottom: 0;
  }
}

/* Le depot unique : une zone en pointilles, qui porte le vrai champ de fichier. */
.calculer__formulaire--depot {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 100%;
}

.calculer__formulaire--depot .calculer__depot {
  border: 1.5px dashed var(--color-neutral-400);
  padding: 18px;
  align-items: center;
  text-align: center;
}

.calculer__depot-phrase {
  font: 600 var(--taille-texte)/1.4 var(--font-body);
}

.calculer__depot-formats {
  font: 500 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-neutral-700);
}

.calculer__reconnu {
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: flex-start;
}

.calculer__reconnu-refus {
  margin: 0;
  padding: 8px 12px;
  background: var(--message-refus-bg);
  color: var(--message-refus-ink);
  font: 500 var(--taille-texte)/1.5 var(--font-body);
}

.calculer__attenue {
  color: var(--color-neutral-700);
}

@media (max-width: 900px) {
  /* Les deux grilles fixes de la maquette — quatre cartouches, trois familles — se replient sur
     deux colonnes en fenêtre étroite. Sans ce repli, chaque case tombe sous les cent pixels et le
     texte y devient illisible.

     **La rangée des quatre chiffres du classeur en faisait partie jusqu'au 2026-09-06**, où elle a
     quitté son écran (Antoine, pour la place). Elle seule est retirée d'ici : le repli des deux
     autres écrans n'a rien à voir avec cette demande. */
  .avancement__chiffres {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Sur deux colonnes, le troisieme chiffre ouvre une rangee : pas de filet a sa gauche. */
  .avancement__chiffre:nth-child(odd) {
    padding-left: 0;
    border-left: 0;
  }
}

/* ---------------------------------------------------------------- « Rapprochement » (M11) */

/* **La maquette validée par Antoine le 2026-09-26** : une ligne de tete, le filtre par famille et
   la recherche, puis une liste serree sous un en-tete fixe, et le pied. C'est la liste qui defile,
   comme dans la bibliotheque. */
.rapprochement {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  background: var(--crm-blanc);
  border-radius: 14px;
  overflow: hidden;
  font: 400 var(--taille-texte)/1.5 var(--font-body);
}

/* Jamais lance : le bouton seul, au centre d'un cadre a sa hauteur (maquette 3.11). */
.rapprochement:has(> .rapprochement__tete:only-child) {
  height: auto;
}

.rapprochement__tete:only-child {
  justify-content: center;
  padding: 40px 20px;
}

.rapprochement__tete:only-child .rapprochement__gestes {
  margin: 0;
}

.rapprochement__tete {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 14px 24px 12px;
  font-size: var(--taille-texte);
  color: var(--color-text-muted);
}

/* Un morceau de la tete ne se coupe jamais : c'est la ligne qui passe a la suivante. */
.rapprochement__tete > * {
  white-space: nowrap;
}

.rapprochement__point {
  flex: none;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--color-neutral-400);
}

.rapprochement__fort {
  font-weight: 600;
  color: var(--color-text);
}

.rapprochement__relecture {
  color: var(--color-accent-500);
  text-decoration: none;
}

.rapprochement__gestes {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 0 auto;
}

.rapprochement__pilule {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 9px;
  border-radius: 999px;
  font: 600 var(--taille-etiquette)/19px var(--font-body);
  white-space: nowrap;
}

.rapprochement__pilule--ok {
  background: var(--color-accent-100);
  color: var(--color-accent);
}

.rapprochement__pilule--neutre {
  background: var(--color-neutral-200);
  color: var(--color-neutral-800);
}

.rapprochement__pilule--cours {
  background: var(--color-accent-100);
  color: var(--color-accent);
}

.rapprochement__pilule--cours::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--color-accent-500);
  animation: rapprochement-bat 1.2s ease-in-out infinite;
}

@keyframes rapprochement-bat {
  50% {
    opacity: .25;
  }
}

/* Il manque une moitie du projet : les deux gestes qui la ramenent. */
.rapprochement__manque {
  display: flex;
  gap: 8px;
  padding: 6px 24px;
}

/* Le filtre par famille et la recherche. */
.rapprochement__barre {
  flex: none;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 24px 10px;
}



.rapprochement__nombre {
  margin-left: 5px;
  font-style: normal;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}

.segment--actif .rapprochement__nombre {
  color: var(--color-accent-500);
}

.rapprochement__recherche {
  width: 260px;
  margin: 0 0 0 auto;
}

.rapprochement__champ {
  box-sizing: border-box;
  width: 100%;
  padding: 6px 14px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-100);
  color: var(--color-text);
  font: 400 var(--taille-texte)/1.3 var(--font-body);
}

.rapprochement__champ:focus {
  outline: 2px solid var(--color-accent-200);
}

/* **La liste, sous un en-tete fixe.** L'en-tete et chaque ligne partagent la meme grille : sans
   quoi les intitules ne tomberaient pas au-dessus des valeurs. La colonne « Famille » ne parait que
   si la page mele deux familles ; celle des parcelles du compte, que si un compte y figure. */
.rapprochement__defile {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: 0 14px;
}

.rapprochement__defile--estompe {
  opacity: .45;
  pointer-events: none;
}

.rapprochement__tetes,
.rapprochement__ligne {
  display: grid;
  grid-template-columns: 22px 128px 170px minmax(0, 1fr) 112px minmax(0, 1.3fr) 150px;
  gap: 0 12px;
  align-items: center;
  min-height: 31px;
  padding: 3px 10px;
  border-bottom: 1px solid var(--color-neutral-200);
  font-size: var(--taille-texte);
}

.rapprochement__defile--sans-famille .rapprochement__tetes,
.rapprochement__defile--sans-famille .rapprochement__ligne {
  grid-template-columns: 22px 128px minmax(0, 1fr) 112px minmax(0, 1.3fr) 150px;
}

.rapprochement__defile--droits .rapprochement__tetes,
.rapprochement__defile--droits .rapprochement__ligne {
  grid-template-columns: 22px 128px minmax(0, .8fr) 112px minmax(0, 1fr) minmax(0, 1.1fr) 150px;
}

/* Une page qui mele les familles et porte un compte sans ayant droit a les deux colonnes. */
.rapprochement__defile--droits:not(.rapprochement__defile--sans-famille) .rapprochement__tetes,
.rapprochement__defile--droits:not(.rapprochement__defile--sans-famille) .rapprochement__ligne {
  grid-template-columns:
    22px 128px 170px minmax(0, .8fr) 112px minmax(0, 1fr) minmax(0, 1.1fr) 150px;
}

.rapprochement__tetes {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: 5px 10px;
  background: var(--crm-blanc);
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.rapprochement__tetes[hidden] {
  display: none;
}

.rapprochement__ligne:hover {
  background: var(--color-neutral-100);
}

.rapprochement__ligne--cochee,
.rapprochement__ligne--cochee:hover {
  background: var(--color-accent-100);
}

.rapprochement__ligne > * {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.rapprochement__ligne--traitee > :not(.rapprochement__geste) {
  color: var(--color-text-muted);
}

.rapprochement__ligne--traitee .rapprochement__reference {
  font-weight: 500;
}

.rapprochement__reference {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.rapprochement__gris {
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.rapprochement__surface {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.rapprochement__geste {
  display: flex;
  justify-content: flex-end;
}

.rapprochement__ligne > .rapprochement__geste {
  overflow: visible;
}

.rapprochement__candidats {
  display: flex;
  gap: 4px;
}

.rapprochement__candidat {
  padding: 0 8px;
  border-radius: 999px;
  background: var(--color-neutral-100);
  font-size: var(--taille-etiquette);
  font-variant-numeric: tabular-nums;
  color: var(--color-neutral-800);
}

.rapprochement__tetes input[type="checkbox"],
.rapprochement__ligne input[type="checkbox"] {
  width: 14px;
  height: 14px;
  margin: 0;
  accent-color: var(--color-accent);
  cursor: pointer;
}

.rapprochement__tetes input[type="checkbox"]:disabled,
.rapprochement__ligne input[type="checkbox"]:disabled {
  cursor: default;
}

/* **Le lot prend la place de l'en-tete des colonnes** des qu'une ligne est cochee. */
.rapprochement__lot {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 31px;
  padding: 4px 10px;
  border-radius: 10px;
  background: var(--color-accent-100);
  font-size: var(--taille-texte);
  color: var(--color-accent);
}

.rapprochement__lot[hidden] {
  display: none;
}

.rapprochement__espace {
  margin-left: auto;
}

.rapprochement__cause {
  margin: 12px 10px;
  font-size: var(--taille-texte);
  color: var(--color-neutral-700);
}

.rapprochement__pied {
  flex: none;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 24px 12px;
  border-top: 1px solid var(--color-neutral-200);
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

/* **En fenetre etroite, la liste garde ses colonnes et defile de cote** : sept colonnes fixes n'y
   tiendraient pas, et chaque case tomberait sous la largeur d'une reference. */
@media (max-width: 900px) {
  .rapprochement__tetes,
  .rapprochement__ligne {
    min-width: 780px;
  }

  .rapprochement__defile--droits:not(.rapprochement__defile--sans-famille) .rapprochement__tetes,
  .rapprochement__defile--droits:not(.rapprochement__defile--sans-famille) .rapprochement__ligne {
    min-width: 960px;
  }

  .rapprochement__barre {
    flex-wrap: wrap;
  }

  /* Les quatre pilules passent a la ligne plutot que de rogner la derniere. */
  .rapprochement__filtre {
    flex-wrap: wrap;
    border-radius: 14px;
  }
}

/* ------------------------------------------------------ « Outils » (M14) */

/* **La maquette validée par Antoine le 2026-09-26** : une ligne par outil, rangée par famille ;
   ouvrir un outil resserre la liste à gauche et pose son panneau à droite. Même style sobre et
   arrondi que les contrats épurés. */
.outils {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 0 26px;
  align-items: start;
}

.outils--ouvert {
  grid-template-columns: 330px minmax(0, 1fr);
}

/* Un outil qui prend toute la largeur : la liste s'efface (photos de terrain, 2026-09-30). */
.outils--ouvert.outils--pleine-largeur {
  grid-template-columns: minmax(0, 1fr);
}

/* L'outil « Photos de terrain » : la carte à gauche, le tableau à droite (maquette validée par
   Antoine le 2026-09-30). **La carte prend l'essentiel** (Antoine, 2026-10-01) : le tableau garde
   de quoi lire une ligne, vignette, nom et texte. */
.photos {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(320px, 3fr);
  gap: 12px;
  height: calc(100vh - 230px);
  min-height: 480px;
  padding: 4px 12px 12px;
}

.photos__carte {
  position: relative;
  min-height: 0;
  border-radius: 10px;
  overflow: hidden;
}

.photos__fond {
  position: absolute;
  inset: 0;
}

.photos--placer .photos__fond {
  cursor: crosshair;
}

/* Au-dessus des plans de la bibliotheque, qui montent jusqu'a 700. */
.photos__cadrer {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 800;
  padding: 5px 10px;
  border: 0;
  border-radius: 6px;
  background: #fff;
  color: var(--color-accent);
  font: 600 var(--taille-etiquette) var(--font-body);
  cursor: pointer;
}

.photos__tableau {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--color-bg);
  border-radius: 10px;
  overflow: hidden;
}

.photos__tete {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0;
  padding: 10px 12px;
  border-bottom: 1px solid var(--color-neutral-200);
}

.photos__compte {
  color: var(--color-neutral-700);
  font-size: var(--taille-etiquette);
}

.photos__titre {
  font-size: var(--taille-texte);
}

.photos__ajouter {
  margin-left: auto;
}

/* Dans l'en-tete du tableau, le bouton garde sa largeur, et le nom choisi ne se lit qu'aux
   lecteurs d'ecran : l'envoi part des le choix. */
.photos__ajouter .depot-de-fichier__bouton {
  width: auto;
}

.photos__ajouter .depot-de-fichier__choisi {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.photos__refus {
  flex-basis: 100%;
  margin: 0;
}

.photos__lignes {
  flex: 1;
  margin: 0;
  padding: 0;
  overflow: auto;
  list-style: none;
}

.photos__ligne {
  display: grid;
  grid-template-columns: 60px minmax(0, 1fr) auto 26px;
  gap: 4px 10px;
  align-items: center;
  padding: 9px 12px;
  border-bottom: 1px solid var(--color-neutral-200);
  cursor: pointer;
}

.photos__ligne--choisie {
  background: var(--color-accent-100);
  box-shadow: inset 3px 0 0 #ffcc00;
}

.photos__vignette {
  grid-row: span 2;
  width: 60px;
  height: 45px;
  border-radius: 5px;
  background: var(--color-neutral-200);
  object-fit: cover;
}

.photos__nom {
  overflow: hidden;
  font-weight: 700;
  font-size: var(--taille-texte);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.photos__nom small {
  margin-left: 6px;
  color: var(--color-neutral-700);
  font-weight: 400;
}

.photos__mention {
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--color-neutral-200);
  color: var(--color-neutral-800);
  font: 700 var(--taille-etiquette) var(--font-body);
  white-space: nowrap;
}

.photos__mention[hidden] {
  display: none;
}

.photos__oter {
  grid-row: span 2;
  grid-column: 4;
  padding: 2px 6px;
  border: 0;
  border-radius: 5px;
  background: none;
  color: var(--color-text-muted);
  font-size: var(--taille-bloc);
  cursor: pointer;
}

.photos__oter:hover:not(:disabled) {
  background: var(--color-neutral-200);
  color: var(--color-danger, #a8321f);
}

.photos__texte {
  grid-column: 2 / 4;
  width: 100%;
  padding: 4px 7px;
  border: 1px solid transparent;
  border-radius: 5px;
  background: transparent;
  color: var(--color-text);
  font-size: var(--taille-texte);
}

.photos__texte:hover:not(:disabled),
.photos__texte:focus {
  border-color: var(--color-neutral-300);
  background: var(--color-neutral-100);
}

/* La note que le serveur vient de garder : le filet vert de ce qui est acquis, sans phrase. */
.photos__texte.photos__texte--gardee {
  border-color: var(--etat-acquis);
}

.photos__geste {
  display: flex;
  grid-column: 2 / 5;
  gap: 8px;
}

.photos__geste[hidden] {
  display: none;
}

.photos__illisibles {
  padding: 8px 12px;
  color: var(--color-neutral-700);
}

/* **Seul le disque d'un repère se clique** : la boîte de 96 px couvrirait les parcelles autour,
   et un clic voisin ouvrirait l'aperçu au lieu de la sélection. */
.leaflet-marker-icon.carte__photo.leaflet-interactive {
  pointer-events: none;
}

.leaflet-marker-icon.carte__photo.leaflet-interactive circle {
  pointer-events: visiblePainted;
  cursor: pointer;
}

/* La photo choisie : son disque cerclé de jaune, et la poignée qui tourne son cône. */
.carte__photo--choisie svg circle {
  stroke: #ffcc00;
  stroke-width: 4;
}

.photos__poignee {
  border: 1.5px solid #000;
  border-radius: 50%;
  background: #ffcc00;
  cursor: grab;
}

.photos__apercu {
  width: 168px;
}

.photos__apercu img {
  display: block;
  width: 168px;
  border-radius: 6px 6px 0 0;
}

.photos__apercu p {
  margin: 0;
  padding: 6px 2px 0;
  font-size: var(--taille-etiquette);
  line-height: 1.35;
}

.photos__apercu b {
  display: block;
  font-size: var(--taille-etiquette);
}

@media (max-width: 900px) {
  .photos {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: 360px auto;
    height: auto;
  }
}

.outils__liste {
  min-width: 0;
}

.outils__famille {
  margin: 6px 0 10px;
}

.outils__nom-de-famille {
  display: flex;
  gap: 10px;
  align-items: baseline;
  margin: 0;
  padding: 8px 10px 6px;
  border-bottom: 1px solid var(--color-neutral-200);
  font-size: var(--taille-texte);
  font-weight: 700;
}

.outils__note {
  font-style: normal;
  font-weight: 500;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

/* Une ligne par outil : icône, nom et description, sortie, bouton. */
.outils__outil {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) 120px 92px;
  gap: 0 14px;
  align-items: center;
  padding: 7px 10px;
  border-radius: 10px;
}

.outils__outil:hover {
  background: var(--color-neutral-100);
}

.outils__outil--actif,
.outils__outil--actif:hover {
  background: var(--color-accent-100);
}

.outils__icone {
  grid-row: span 2;
  width: 18px;
  height: 18px;
  color: var(--color-accent);
}

.outils__nom {
  font-size: var(--taille-texte);
  font-weight: 600;
}

.outils__lien {
  color: inherit;
  text-decoration: none;
}

.outils__description {
  grid-column: 2;
  font-size: var(--taille-texte);
  color: var(--color-text-muted);
}

.outils__sortie {
  grid-row: span 2;
  grid-column: 3;
  font-size: var(--taille-etiquette);
  color: var(--color-neutral-700);
}

.outils__geste {
  grid-row: span 2;
  grid-column: 4;
  justify-self: end;
}

.outils__ouvrir {
  padding: 6px 14px;
  font-size: var(--taille-texte);
}

.outils__fleche {
  font-weight: 500;
}

.outils__outil--eteint .outils__nom,
.outils__outil--eteint .outils__icone {
  color: var(--color-text-muted);
}

/* Le travail qui tourne se dit sur sa ligne, même panneau fermé. */
.outils__tourne {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 8px;
  font-size: var(--taille-etiquette);
  font-weight: 600;
  color: var(--color-accent);
}

.outils__puce {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-accent-500);
  animation: outils-battement 1.2s ease-in-out infinite;
}

@keyframes outils-battement {
  50% {
    opacity: .25;
  }
}

/* Panneau ouvert, il ne reste de la liste que l'icône et le nom. */
.outils--ouvert .outils__outil {
  grid-template-columns: 22px minmax(0, 1fr);
}

.outils--ouvert .outils__description,
.outils--ouvert .outils__sortie,
.outils--ouvert .outils__geste {
  display: none;
}

/* --- Le panneau d'un outil ------------------------------------------------------------------- */

.outils__panneau {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--color-accent-100);
  border-radius: 18px;
  overflow: hidden;
}

.outils__panneau-tete {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 22px 4px;
}

.outils__panneau-titre {
  margin: 0;
  font-size: var(--taille-bloc);
}

.outils__fermer {
  margin-left: auto;
  color: var(--color-text-muted);
}

.outils__formulaire,
.outils__suivi {
  display: flex;
  flex-direction: column;
  margin: 0;
}

.outils__panneau-corps {
  padding: 4px 22px 12px;
}

.outils__ligne {
  display: grid;
  grid-template-columns: 110px minmax(0, 1fr);
  gap: 10px;
  align-items: start;
  margin: 0;
  padding: 12px 0;
  border-bottom: 1px solid var(--color-neutral-200);
}

.outils__ligne:last-child {
  border-bottom: 0;
}

.outils__etiquette {
  padding-top: 4px;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.outils__precision {
  display: block;
  font-style: normal;
  font-weight: 500;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.outils__en-ligne {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.outils__borne {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.outils__champ {
  width: 220px;
  padding: 7px 14px;
  border: 0;
  border-radius: 999px;
  background: var(--crm-blanc);
  box-shadow: 0 0 0 1px var(--color-neutral-200);
  color: var(--color-text);
  font: inherit;
  font-size: var(--taille-texte);
  font-variant-numeric: tabular-nums;
}

/* Les choix en pastilles : un découpage, un format, une projection. */
.outils__choix {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.outils__option {
  position: relative;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--crm-blanc);
  box-shadow: 0 0 0 1px var(--color-neutral-200);
  color: var(--color-neutral-700);
  font-size: var(--taille-etiquette);
  text-decoration: none;
  cursor: pointer;
}

.outils__option input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.outils__option--retenue,
.outils__option:has(input:checked) {
  background: var(--color-accent);
  box-shadow: none;
  color: #f3f2f2;
  font-weight: 600;
}

.outils__option:has(input:focus-visible) {
  outline: 2px solid var(--color-accent-400);
  outline-offset: 2px;
}

.outils__cases {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px 12px;
}

.outils__case {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border-radius: 9px;
  font-size: var(--taille-texte);
}

.outils__case:has(input:checked) {
  background: var(--crm-blanc);
}

.outils__case input {
  margin: 0;
  accent-color: var(--color-accent);
}

/* **Le seul jaune du panneau** : des parcelles qui ne correspondent pas, dans un outil qui
   produit un document. */
.outils__ecart {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 12px 0 0;
  padding: 8px 12px;
  border-radius: 12px;
  background: var(--warn-bg);
  color: var(--warn-ink);
  font-size: var(--taille-texte);
}

.outils__ecart::before {
  content: "";
  flex: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--ef-sun);
}

.outils__ecart-lien {
  margin-left: auto;
  border-bottom: 1px solid currentColor;
  color: var(--warn-ink);
  font-weight: 600;
  text-decoration: none;
}

/* La barre d'action : le bilan à gauche, les gestes à droite. */
.outils__action {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 22px;
  border-top: 1px solid var(--color-neutral-200);
  background: var(--crm-blanc);
}

.outils__bilan {
  font-size: var(--taille-texte);
  color: var(--color-neutral-700);
}

.outils__bilan b {
  color: var(--color-text);
}

.outils__espace {
  margin-left: auto;
}

.outils__geste-du-suivi {
  margin: 0;
}

.outils__message {
  margin: 10px 0 0;
  padding: 10px 12px;
  border-radius: 12px;
  background: var(--crm-blanc);
  font-size: var(--taille-texte);
  color: var(--color-neutral-800);
}

/* --- Le suivi, dans le panneau -------------------------------------------------------------- */

.outils__barre {
  width: 100%;
  height: 6px;
  margin: 8px 0 2px;
  border: 0;
  border-radius: 999px;
  overflow: hidden;
  background: var(--color-neutral-200);
  appearance: none;
}

.outils__barre::-webkit-progress-bar {
  background: var(--color-neutral-200);
}

.outils__barre::-webkit-progress-value {
  border-radius: 999px;
  background: var(--color-accent-500);
}

.outils__barre::-moz-progress-bar {
  border-radius: 999px;
  background: var(--color-accent-500);
}

.outils__rang {
  margin: 0;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.outils__manques {
  margin: 14px 0 0;
  font-size: var(--taille-texte);
}

.outils__manque {
  margin: 4px 0 0;
  padding: 7px 10px;
  border-radius: 10px;
  background: var(--crm-blanc);
  font-size: var(--taille-texte);
}

.outils__etapes {
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
}

.outils__etape {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  padding: 6px 0;
  border-bottom: 1px solid var(--color-neutral-200);
  font-size: var(--taille-texte);
}

.outils__etape:last-child {
  border-bottom: 0;
}

.outils__etape-pastille {
  justify-self: center;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1.5px var(--color-neutral-400);
}

.outils__etape-mention {
  font-style: normal;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.outils__etape--faite .outils__etape-pastille {
  background: var(--color-accent-500);
  box-shadow: none;
}

.outils__etape--en-cours .outils__etape-pastille {
  background: var(--color-accent-500);
  box-shadow: none;
  animation: outils-battement 1.2s ease-in-out infinite;
}

.outils__etape--a-venir,
.outils__etape--sans-objet {
  color: var(--color-text-muted);
}

.outils__etape--interrompue .outils__etape-pastille {
  background: var(--refus-bg);
  box-shadow: none;
}

.outils__etape--interrompue .outils__etape-mention {
  color: var(--refus-bg);
}

/* --- La réponse à l'écran : les vérifications d'une parcelle absente ------------------------- */

.outils__verifications {
  display: grid;
  gap: 4px;
  margin-top: 4px;
}

.outils__verification {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0 10px;
  padding: 8px 10px;
  border-radius: 10px;
  background: var(--crm-blanc);
}

.outils__verdict {
  grid-row: span 2;
  align-self: center;
  padding: 1px 9px;
  border-radius: 999px;
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-size: var(--taille-etiquette);
  font-weight: 600;
  white-space: nowrap;
}

.outils__conclusion,
.outils__candidats {
  grid-column: 1;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.outils__reference {
  margin-right: 8px;
  color: var(--color-accent-500);
  font: 600 var(--taille-etiquette) var(--font-body);
  font-variant-numeric: tabular-nums;
}

.outils__mention {
  margin-right: 8px;
}

.outils__couches,
.outils__comptes {
  margin: 0;
  padding-left: 18px;
  font-size: var(--taille-texte);
}

/* Les ajouts d'un quarta : une liste par nature, et les différences en tableau, pour lecture. */
.outils__differences {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--taille-texte);
}

.outils__differences th,
.outils__differences td {
  padding: 4px 8px 4px 0;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--color-neutral-200);
  overflow-wrap: anywhere;
}

.outils__differences th {
  font-weight: 500;
  color: var(--color-text-muted);
}

.outils__proposition {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}

/* ----------------------------------------------------- « General » (page de garde) */

/* La page de garde du projet (piste C, validee le 2026-09-26) : une colonne etroite et centree,
   le nom en grand, la fiche, puis l'etat du FGF et de la carto. */
.general {
  /* **Marges comprises**, comme dans la maquette (piste C, `*{box-sizing:border-box}`) : sans
     cette regle, la colonne mesurait 812 px au lieu de 760. */
  box-sizing: border-box;
  position: relative;
  display: flex;
  flex-direction: column;
  max-width: 760px;
  width: 100%;
  margin: 0 auto;
  padding: 30px 26px 32px;
}

.general__identite {
  display: flex;
  flex-direction: column;
}

/* Le menu « ⋯ » des gestes rares (maquette 3.3, 2026-10-03), en haut a droite de la colonne. */
.general__plus {
  position: absolute;
  top: 30px;
  right: 26px;
  z-index: 3;
}

.general__plus > summary {
  list-style: none;
}

.general__plus > summary::-webkit-details-marker {
  display: none;
}

.general__autres-gestes {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  display: flex;
  flex-direction: column;
  min-width: 220px;
  padding: 6px;
  border-radius: var(--rayon-cadre);
  background: var(--crm-blanc);
  box-shadow: 0 0 0 1px var(--color-divider);
}

.general__menu-entree {
  display: block;
  width: 100%;
  padding: 7px 10px;
  border: 0;
  border-radius: var(--rayon-bouton);
  background: none;
  color: var(--color-text);
  font: 500 var(--taille-texte)/1.3 var(--font-body);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.general__menu-entree:hover,
.general__menu-entree:focus-visible {
  background: var(--color-accent-100);
}

/* Le nom et la note se modifient sur place : sans cadre, un fond pale au survol et a la saisie. */
.general__nom {
  display: block;
  width: 100%;
  margin: 2px 0 0 -10px;
  padding: 2px 10px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--color-text);
  font: 800 var(--taille-vitrine)/1.25 var(--font-heading);
  letter-spacing: -0.015em;
}

.general__note-de-mission {
  display: block;
  width: 100%;
  margin: 8px 0 0 -10px;
  padding: 6px 10px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--color-neutral-800);
  font: 400 var(--taille-ecran)/1.55 var(--font-body);
  resize: none;
}

.general__nom:hover,
.general__nom:focus,
.general__note-de-mission:hover,
.general__note-de-mission:focus {
  background: var(--color-neutral-100);
  outline: 0;
}

.general__nom:disabled:hover,
.general__note-de-mission:disabled:hover {
  background: transparent;
}


/* La fiche : l'intitule a gauche, le fait a droite, un filet entre chaque ligne. */
/* La fiche et l'etat dans le cadre commun (maquette 3.3, 2026-10-03). */
.general__fiche {
  margin-top: 22px;
  display: grid;
  grid-template-columns: 150px 1fr;
  padding: 2px 18px;
  border-radius: var(--rayon-cadre);
  background: var(--crm-blanc);
}

.general__intitule {
  padding: 9px 0;
  border-bottom: 1px solid var(--color-neutral-200);
  color: var(--color-text-muted);
  font-size: var(--taille-texte);
}

.general__fait,
.general__equipe {
  padding: 9px 0;
  border-bottom: 1px solid var(--color-neutral-200);
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 16px;
}

.general__precision {
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
}

.general__membre {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.general__pastille {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--color-accent-100);
  color: var(--color-accent);
  display: inline-grid;
  place-items: center;
  flex: none;
  /* Les initiales d'un collaborateur, un peu plus petites (Antoine, 2026-10-04 ; derogation a la
     regle 2). */
  font: 700 11px var(--font-body);
  font-style: normal;
}

.general__choix {
  position: relative;
}



.general__menu {
  position: absolute;
  z-index: 6;
  top: calc(100% + 6px);
  left: 0;
  width: 240px;
  background: var(--color-bg);
  border-radius: 14px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.12);
  padding: 8px;
  display: grid;
  gap: 2px;
}

.general__chercher {
  width: 100%;
  padding: 6px 12px;
  border: 0;
  border-radius: 999px;
  font: 400 var(--taille-texte) var(--font-body);
  background: var(--color-neutral-100);
  color: var(--color-text);
  margin-bottom: 4px;
}

/* Une case par formulaire : htmx envoie celui de la case qui change. */
.general__collaborateur {
  margin: 0;
}

.general__case {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border-radius: 9px;
  cursor: pointer;
  font-size: var(--taille-texte);
}

.general__case:hover {
  background: var(--color-neutral-100);
}

.general__case input[type="checkbox"] {
  accent-color: var(--color-accent);
  margin: 0;
}

.general__collaborateur[hidden] {
  display: none;
}

/* L'ajout d'un extérieur se confirme : sa case cochée découvre l'avertissement et le bouton. */
.general__confirmation {
  display: none;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
  padding: 2px 8px 8px;
}

.general__collaborateur:has(input:checked) .general__confirmation {
  display: flex;
}

.general__avertissement {
  margin: 0;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

/* Le client du projet : une ligne de la fiche que htmx remplace seule, intitule compris. Le rond
   prend la teinte de son sigle (`crm-teinte-N`), comme les personnes du CRM. */
.general__ligne-du-client {
  display: contents;
}

.general__rond {
  width: 24px;
  height: 24px;
  padding: 0;
  box-sizing: border-box;
  border-radius: var(--rayon-pilule);
  display: inline-grid;
  place-items: center;
  flex: none;
  background: var(--crm-fond);
  color: var(--crm-encre);
  font: 700 var(--taille-etiquette) var(--font-body);
  font-style: normal;
}

/* Le client lui-meme rouvre le menu : pas de second bouton a cote. */
.general__client {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 2px 9px 2px 2px;
  margin-left: -2px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font: inherit;
  color: inherit;
  cursor: pointer;
  list-style: none;
}

.general__client::-webkit-details-marker {
  display: none;
}

.general__client:hover,
.general__choix[open] > .general__client {
  background: var(--color-neutral-100);
}

.general__client--fige,
.general__client--fige:hover {
  cursor: default;
  background: transparent;
}

.general__choix-du-client {
  margin: 0;
}

/* La question du choix, posee sur la ligne choisie (chantier 2, revue 02 §13) : l'attention, et
   les deux gestes dans l'ordre de toute confirmation. */
.general__confirmation-du-client {
  margin: 0;
  padding: 8px;
  border-left: 4px solid var(--etat-a-surveiller);
  border-radius: var(--rayon-bouton);
  background: var(--message-attention-bg);
  color: var(--message-attention-ink);
  font-size: var(--taille-texte);
}

.general__confirmation-phrase {
  margin: 0 0 8px;
}

.general__confirmation-du-client .confirmation__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
}

button.general__case {
  width: 100%;
  border: 0;
  background: transparent;
  font: 400 var(--taille-texte)/1.5 var(--font-body);
  color: var(--color-text);
  text-align: left;
}

button.general__case--retenue {
  font-weight: 700;
}

button.general__case--aucun {
  color: var(--color-text-muted);
}

/* Le lien vers la table des clients, au pied du menu, pour un administrateur (2026-09-27). */
a.general__case--gestion {
  color: var(--color-accent-500);
  text-decoration: none;
}

.general__coche {
  margin-left: auto;
  color: var(--color-accent);
  font-weight: 800;
}

.general__filet {
  border: 0;
  border-top: 1px solid var(--color-neutral-200);
  margin: 4px 6px;
}

/* L'etat : une ligne par moitie, son icone, son mot, ses signaux, son geste discret. */
.general__section {
  margin-top: 26px;
  font: 700 var(--taille-ecran)/1.5 var(--font-body);
}

.general__composants {
  margin-top: 10px;
  padding: 2px 18px;
  border-radius: var(--rayon-cadre);
  background: var(--crm-blanc);
}

.general__composant {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--color-neutral-200);
}

.general__icone {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  background: var(--color-accent-100);
  color: var(--color-accent);
  display: grid;
  place-items: center;
  flex: none;
}

.general__icone-dessin {
  width: 17px;
  height: 17px;
  stroke-width: 1.7;
}

.general__mot {
  width: 56px;
  font-size: var(--taille-ecran);
  font-weight: 700;
  cursor: default;
}

/* Les signaux se rangent en trois colonnes, le point, les mots, le geste : deux signaux l'un sous
   l'autre gardent leurs gestes alignes. */
.general__signaux {
  display: grid;
  grid-template-columns: 8px auto auto;
  align-items: center;
  gap: 4px 8px;
}

.general__etat {
  display: contents;
  white-space: nowrap;
  font-size: var(--taille-texte);
  color: var(--color-neutral-800);
}

.general__mots {
  white-space: nowrap;
}

.general__point {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-neutral-400);
}

.general__etat--ok .general__point {
  background: var(--color-accent-500);
}

.general__etat--attend .general__point {
  background: var(--ef-sun);
}

.general__geste {
  margin-left: 14px;
  font-weight: 600;
  font-size: var(--taille-texte);
  color: var(--color-accent-500);
  text-decoration: none;
}

.general__geste:hover,
.general__geste:focus-visible {
  text-decoration: underline;
}

.general__gestes {
  margin-top: 26px;
  display: flex;
  gap: 8px;
}

.general__fermeture {
  display: contents;
}

/* Le formulaire de la fermeture directe ne s'interpose pas dans la rangée des gestes. */
.bibliotheque__fermeture {
  display: contents;
}

/* --- L'écran « Opération en cours » — motif M13, le suivi seulement ------------------------- */

.operation {
  max-width: 1100px;
}

/* Le bloc qui se remplace lui-même toutes les deux secondes. Un cadre plein, comme les panneaux
   d'avancement : c'est le même genre d'objet — un état qu'on regarde, pas une commande. */
.operation__etat {
  /* **Le cadre est celui du suivi commun** (chantier 2, revue 06 §1) : le filet noir de 2 px en
     faisait un second autour de lui. */
  border: 0;
  background: transparent;
}

/* **Un calcul se suit sans cadre** (maquette du 2026-09-26) : le processus tient seul dans sa
   colonne, et le cadre noir des autres operations l'enfermait sur toute la largeur. */
.operation__etat--calcul {
  border: 0;
  background: transparent;
}

/* Un geste du pied du suivi : le formulaire ne prend aucune place a lui. */
.operation__geste {
  margin: 0;
}

.operation__phrase {
  margin: 0;
  padding: 12px 14px;
  color: var(--color-neutral-700);
  font-size: var(--taille-etiquette);
  font-weight: 500;
  line-height: 1.5;
}

.operation__erreur {
  margin: 0 14px 14px;
  background: var(--refus-bg);
  color: var(--refus-ink);
  padding: 10px;
  font-size: var(--taille-ecran);
}

/* L'abandon du suivi, en tête du bloc : c'est la seule chose qui compte quand il paraît. */
.operation__abandon {
  margin: 0;
  background: var(--warn-bg);
  color: var(--warn-ink);
  padding: 10px 14px;
  border-bottom: 2px solid var(--color-text);
  font-size: var(--taille-ecran);
}

.operation__bloc {
  border-top: 1px solid var(--color-divider);
  padding: 12px 14px 0;
}

.operation__bloc-titre {
  margin: 0;
  font-size: var(--taille-bloc);
  font-weight: 700;
  line-height: 1.2;
}

.operation__attente {
  margin: 10px 14px 14px;
  background: var(--warn-bg);
  color: var(--warn-ink);
  padding: 10px;
  font-size: var(--taille-ecran);
}

.operation__bloc .operation__attente {
  margin-left: 0;
  margin-right: 0;
}

/* Ce que le calcul a dû décider seul. Le bloc emprunte l'habillage de M15 — c'est un
   avertissement, et il n'y a pas de raison qu'il ressemble à autre chose ; seules la marge dans
   le cadre du suivi et la liste des phrases sont à poser ici. */
.operation__avertissements {
  margin: 12px 14px 0;
}

.operation__avertissements-liste {
  margin: 2px 0 0;
  padding-left: 18px;
}

.operation__avertissements p {
  margin: 0;
}

/* Les étapes du calcul, à la place des deux pavés jaunes qui les réclamaient jusqu'au
   2026-09-04. Elles se lisent en liste, pas en barre : le moteur nomme chaque étape, et un nom
   renseigne plus qu'un pourcentage sur un calcul qui dure des minutes. */
.operation__etapes {
  border-top: 1px solid var(--color-divider);
  padding: 12px 14px;
}

.etapes {
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
}

.etape {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: baseline;
  padding: 6px 0;
  border-bottom: 1px solid var(--color-divider);
  font-size: var(--taille-ecran);
}

.etape:last-child {
  border-bottom: 0;
}

.etape__rang {
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted, inherit);
  font-size: var(--taille-texte);
}

.etape__nom {
  flex: 1 1 auto;
}

.etape__statut {
  font-size: var(--taille-texte);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.etape__detail {
  flex: 1 1 100%;
  font-size: var(--taille-texte);
  color: var(--color-text-muted, inherit);
}

/* **L'étape en cours se voit d'un coup d'œil** : c'est la seule information que l'on cherche en
   revenant sur cet écran. */
.etape--en-cours {
  font-weight: 700;
}

/* **Chaque etape porte son etat, et pas seulement celle qui tourne** (Antoine, 2026-09-05, puis
   2026-09-07). Seule l'etape en cours se distinguait : les faites et les a-venir se lisaient
   pareil, en texte ordinaire, si bien qu'un calcul a moitie fait paraissait a peine commence.

   « Termine » passe au vert, comme Antoine l'a demande : c'est le seul etat qu'on cherche a
   compter des yeux en revenant sur l'ecran. */
.etape--terminee .etape__statut {
  color: var(--ef-leaf);
  font-weight: 600;
}

/* **Ce qui n'a pas commence s'efface**, sans disparaitre : le denominateur doit rester lisible. */
.etape--a-faire .etape__nom,
.etape--a-faire .etape__statut {
  color: var(--color-text-muted, inherit);
}

/* **Non applicable reste affichée**, en retrait : la masquer ferait bouger le dénominateur d'un
   type de projet à l'autre. */
.etape--sans-objet {
  opacity: 0.55;
}

.etape--avertissement .etape__statut,
.etape--erreur .etape__statut {
  background: var(--warn-bg);
  color: var(--warn-ink);
  padding: 1px 6px;
}

/* Le temps écoulé, en bas du suivi (Antoine, 2026-09-07). **En retrait, et c'est voulu** : on le
   cherche quand on se demande depuis combien de temps ça dure, pas pendant qu'on lit les étapes.
   Les chiffres sont tabulaires — sans cela, le nombre saute d'un rafraîchissement à l'autre. */

/* --- Le suivi d'un calcul, maquette validee par Antoine le 2026-09-23 -----------------------
   Coins droits et charte EF360 : vert pour ce qui avance, vert clair pour la reussite, rouge des
   refus pour l'arret. La barre est un `<progress>` : la politique de securite refuse les styles
   ecrits dans la page, et la largeur d'une barre dessinee en serait un. */
.operation__progression {
  margin: 12px 14px 0;
}

.operation__barre {
  display: block;
  width: 100%;
  height: 8px;
  appearance: none;
  border: 0;
  background: var(--color-neutral-100);
  color: var(--color-accent);
}

.operation__barre::-webkit-progress-bar {
  background: var(--color-neutral-100);
}

.operation__barre::-webkit-progress-value {
  background: var(--color-accent);
}

.operation__barre::-moz-progress-bar {
  background: var(--color-accent);
}

.operation__progression--terminee .operation__barre::-webkit-progress-value {
  background: var(--ef-leaf);
}

.operation__progression--terminee .operation__barre::-moz-progress-bar {
  background: var(--ef-leaf);
}

.operation__progression--arretee .operation__barre::-webkit-progress-value {
  background: var(--message-refus-ink);
}

.operation__progression--arretee .operation__barre::-moz-progress-bar {
  background: var(--message-refus-ink);
}

.operation__rang {
  margin: 6px 0 0;
  font-size: var(--taille-etiquette);
  color: var(--color-neutral-700);
}

.operation__arret {
  margin: 12px 14px 0;
  padding: 8px 12px;
  background: var(--message-refus-bg);
  color: var(--message-refus-ink);
  font: 600 var(--taille-texte)/1.5 var(--font-body);
}

.operation__pied {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 14px;
}

/* « Arreter le calcul » : du texte rouge, sans bordure, comme la maquette le dessine. */
.operation__arreter {
  color: var(--message-refus-ink);
}

/* La pastille de chaque etape : une coche verte, une pastille qui bat, un cercle vide, ou un
   point d'exclamation rouge la ou le calcul s'est arrete. */
.etape__pastille {
  width: 16px;
  height: 16px;
  flex: none;
  align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--color-neutral-400);
  border-radius: 50%;
  font: 700 var(--taille-etiquette)/1 var(--font-body);
}

.etape__pastille--faite {
  background: var(--ok-bg);
  border-color: var(--ef-leaf);
  color: var(--ok-ink);
}

.etape__pastille--faite::before {
  content: "\2713";
}

.etape__pastille--en-cours {
  border-color: var(--color-accent);
  background: var(--color-accent);
  animation: retour-au-travail-battement 1.6s ease-in-out infinite;
}

.etape__pastille--sans-objet {
  border-style: dashed;
}

.etape__pastille--interrompue {
  background: var(--message-refus-bg);
  border-color: var(--message-refus-ink);
  color: var(--message-refus-ink);
}

.etape__pastille--interrompue::before {
  content: "!";
}

@media (prefers-reduced-motion: reduce) {
  .etape__pastille--en-cours {
    animation: none;
  }
}

/* Le suivi d'un calcul dans l'ecran de calcul (maquette du 2026-09-26) : le titre et le temps
   ecoule, puis les etapes en processus — une pastille par etape, reliee a la suivante par un
   trait qui verdit a mesure. */
.suivi-du-calcul {
  max-width: 560px;
  margin: 0 auto;
}

.calculer__suivi {
  padding: 8px 0 24px;
}

.processus {
  list-style: none;
  margin: 0;
  padding: 0;
}

.processus__etape {
  position: relative;
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  padding: 0 0 14px;
}

.processus__etape:last-child {
  padding-bottom: 0;
}

.processus__etape::after {
  content: "";
  position: absolute;
  left: 7px;
  top: 19px;
  bottom: 3px;
  width: 2px;
  background: var(--color-neutral-300);
}

.processus__etape:last-child::after {
  display: none;
}

.processus__etape--faite::after {
  background: var(--processus-vert);
}

.processus__pastille {
  position: relative;
  width: 16px;
  height: 16px;
  box-sizing: border-box;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--crm-blanc);
  box-shadow: inset 0 0 0 1.5px var(--color-neutral-400);
  font: 800 var(--taille-etiquette)/1 var(--font-body);
}

.processus__etape--faite .processus__pastille {
  background: var(--processus-vert);
  box-shadow: none;
  color: var(--processus-coche);
}

.processus__etape--faite .processus__pastille::before {
  content: "\2713";
}

.processus__etape--courante .processus__pastille {
  box-shadow: inset 0 0 0 2px var(--processus-bleu-fond);
}

.processus__etape--courante .processus__pastille::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid transparent;
  border-top-color: var(--processus-bleu);
  border-right-color: var(--processus-bleu);
  animation: processus-tourne .9s linear infinite;
}

.processus__etape--sans-objet .processus__pastille {
  background: var(--color-neutral-200);
  box-shadow: inset 0 0 0 1.5px var(--color-neutral-300);
}

.processus__etape--coupee .processus__pastille {
  background: var(--refus-bg);
  box-shadow: none;
}

.processus__nom {
  font-size: var(--taille-texte);
}

.processus__etape--courante .processus__nom {
  color: var(--processus-bleu);
  font-weight: 700;
}

.processus__etape--suivante .processus__nom,
.processus__etape--sans-objet .processus__nom {
  color: var(--color-text-muted);
}

.processus__mention {
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
  font-variant-numeric: tabular-nums;
}

.processus__etape--coupee .processus__mention {
  color: var(--message-refus-ink);
}

@keyframes processus-tourne {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .processus__etape--courante .processus__pastille::before {
    animation: none;
  }
}

.suivi-du-calcul__arret {
  margin: 18px 0 0;
  padding: 10px 14px;
  border-radius: 12px;
  background: var(--message-refus-bg);
  color: var(--message-refus-ink);
  font-size: var(--taille-texte);
}

.suivi-du-calcul__arret p {
  margin: 0;
}

.suivi-du-calcul__arret p + p {
  margin-top: 4px;
}

.suivi-du-calcul__geste {
  margin: 0;
}

.suivi-du-calcul__arreter {
  color: var(--message-refus-ink);
  border-color: currentColor;
}

/* --- La parcelle désignée : du classeur à la carte, et retour ------------------------------- */

/* Le surlignage de la ligne sur laquelle on revient de la carte. La teinte est celle que la
   maquette emploie pour la même chose, et la règle est écrite comme elle : sur l'attribut, pas
   sur une classe, parce que c'est un état de la ligne, pas une variante de style.
   **L'attribut ne se pose que sur la ligne désignée** — jamais sur les autres avec une valeur
   fausse : ce qui est peint doit désigner une ligne et une seule. */
[data-rowon="true"] {
  background: var(--color-accent-100);
}

/* Une parcelle de la carte se clique : le curseur le dit avant qu'on ait essayé. */
.carte__parcelle {
  cursor: pointer;
}

/* La parcelle sélectionnée. **Peinte par la feuille de style et non par le code de la carte** :
   Leaflet pose ses couleurs en attributs de présentation, que toute règle CSS surclasse — le
   style d'une couche reste ainsi une décision de l'écran, pas du script.

   **Elle garde la couleur de son style** (Antoine, 2026-09-25, option C de la maquette
   `docs/refonte_ui/selection_sur_la_carte.html`) : repeinte en vert pâle, elle perdait son état
   de signature au moment où on la regardait. Un trait jaune la cerne, et **les autres parcelles
   pâlissent** tant qu'une sélection existe. Le trait est une couleur fixe et non un jeton du
   thème : la carte ne change pas de fond avec le thème sombre. */
/* **Un point ou une ligne sans contour, choisi, est cerné de jaune comme une parcelle** (Antoine,
   2026-10-05) : repeint en jaune sur 2,5 pixels, un point de quelques pixels ne se voyait plus
   choisi. Il garde sa couleur, et quatre ombres décalées tracent autour 2 pixels de jaune, puis
   un pixel sombre qui les détache d'un fond clair. */
.carte__parcelle--selectionnee:not(.carte__parcelle--cernee):not(.carte__parcelle--surface):not(.carte__contour-de-ligne) {
  filter:
    drop-shadow(2px 0 0 var(--selection-jaune)) drop-shadow(-2px 0 0 var(--selection-jaune))
    drop-shadow(0 2px 0 var(--selection-jaune)) drop-shadow(0 -2px 0 var(--selection-jaune))
    drop-shadow(1px 0 0 var(--selection-lisere)) drop-shadow(-1px 0 0 var(--selection-lisere))
    drop-shadow(0 1px 0 var(--selection-lisere)) drop-shadow(0 -1px 0 var(--selection-lisere));
}

/* **Le jaune cerne l'ensemble des surfaces choisies** (Antoine, 2026-10-01) : la limite commune
   de deux parcelles voisines ne ressort plus. Le contour est une copie du tracé, masquée dans
   l'ensemble (`nouveauContourDeLaSelection`) : seule sa moitié extérieure se voit, soit 3 pixels
   de jaune bordés d'un pixel sombre, qui le détache d'un fond clair. */
.carte__contour-de-selection {
  pointer-events: none;
}

.carte__contour-de-selection path {
  fill: none;
  stroke-linejoin: round;
}

.carte__contour-de-selection-lisere {
  stroke: #101820;
  stroke-width: 8;
}

.carte__contour-de-selection-trait {
  stroke: #ffe600;
  stroke-width: 6;
}

/* **Une ligne du foncier non cadastré garde sa couleur quand on la choisit** : son trait est sa
   couleur, et le repeindre effacerait son état. C'est son contour, tracé dessous, qui prend le
   trait jaune, du même débord que celui d'une parcelle. */
.carte__contour-de-ligne.carte__parcelle--selectionnee {
  stroke: #ffe600;
  stroke-width: 9.5;
}

/* **La forme entière pâlit** (`opacity`), et c'est ce qui respecte chaque style : fixer
   `fill-opacity` remplissait les parcelles d'un style en contour seul, dont le fond est à zéro
   (revue du 2026-09-25). Mesuré le même jour : au volume de nos projets (6 400 parcelles), aucune
   différence de latence ne se mesure, ni au clic ni en déplaçant la carte ; à 20 000, 60 ms au
   clic contre 31 ms sans projecteur. */
.carte--avec-selection .carte__parcelle:not(.carte__parcelle--selectionnee) {
  opacity: 0.28;
}

/* **La zone choisie, en lumiere comme une selection** (maquette « Zone », 2026-09-25) : les
   autres zones palissent, son bord s'epaissit. La couleur reste celle que le moteur donne. */
.carte--avec-zone-choisie .carte__zone:not(.carte__zone--choisie) {
  opacity: 0.25;
}

.carte__zone--choisie {
  stroke-width: 5px;
}

/* **Une zone ne capte le clic que sur son bord** : son interieur laisse passer le clic aux
   parcelles qu'elle contient, qui restent le geste central de la carte. */
.leaflet-pane > svg path.leaflet-interactive.carte__zone {
  pointer-events: visibleStroke;
  /* **Le fond reste leger** (maquette « Zone ») : le bord porte l'etat, et les parcelles se voient
     dessous avec leurs couleurs. **Il suit le curseur d'opacite** (Antoine, 2026-09-27) : le
     script pose la variable sur le plan de la couche, jusqu'au plein a 100 %. */
  fill-opacity: var(--remplissage-de-la-couche, 0.12);
}

/* Le nom d'une zone, au coin haut-gauche de ses bornes : du texte sur la carte, sans bulle. */
.carte__nom-de-zone.leaflet-tooltip {
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
  color: #fff;
  font: 700 var(--taille-etiquette) var(--font-body);
  text-shadow: 0 0 3px #201e1d, 0 0 2px #201e1d, 0 0 1px #201e1d;
  white-space: nowrap;
  pointer-events: none;
}

.carte__nom-de-zone.leaflet-tooltip::before {
  display: none;
}

/* Masquee ou a 0 %, la couche des zones emporte leurs noms (Antoine, 2026-09-27). */
.carte--sans-noms-de-zone .carte__nom-de-zone.leaflet-tooltip {
  display: none;
}

/* Le formulaire du retour vers le classeur ne doit rien ajouter à la mise en page : le bouton
   qu'il contient garde les marges que le panneau lui donne. */
.panneau__retour {
  margin: 0;
}

/* Le rectangle en cours de trace : le filet de l'accent, un voile a peine visible. */
.carte__rectangle-de-selection {
  stroke: var(--color-accent);
  stroke-dasharray: 4 3;
  fill: var(--color-accent);
  fill-opacity: 0.08;
}

/* --- Le menu du clic droit du classeur ------------------------------------------------------ */

/* Posé sur le corps de la page, aux coordonnées du clic : dans la table, il serait rogné par son
   cadre de défilement dès que la ligne visée est près du bord. */
.menu-contextuel {
  position: fixed;
  z-index: 1000;
  min-width: 160px;
  padding: 4px 0;
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  box-shadow: 0 4px 12px rgb(0 0 0 / 18%);
}

.menu-contextuel__entree {
  display: block;
  padding: 6px 12px;
  color: var(--color-text);
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
  text-decoration: none;
  cursor: pointer;
}

.menu-contextuel__entree:hover,
.menu-contextuel__entree:focus {
  background: var(--color-accent-100);
}

/* --- L'écran « Échanges » en fil (maquette « CRM : les échanges en fil », 2026-09-25) ---------- */

/* **Recopie de la maquette** (`docs/refonte_ui/crm.html`) : surfaces arrondies, puces, le vert de
   la marque et le gris, aucun trait de séparation. Les noms prennent le préfixe `crm-` ; les
   valeurs sont celles de la maquette, rapportées aux jetons de la feuille quand ils existent. */
.crm {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  font-size: var(--taille-texte);
}

.crm-bascule {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  font: 600 var(--taille-texte) var(--font-body);
  color: var(--color-neutral-800);
  text-decoration: none;
  cursor: pointer;
}

.crm-bascule i {
  position: relative;
  display: inline-block;
  width: 30px;
  height: 17px;
  border-radius: 9px;
  background: var(--color-neutral-300);
  transition: background 0.15s;
}

.crm-bascule i::after {
  content: "";
  position: absolute;
  left: 2px;
  top: 2px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--crm-blanc);
  transition: left 0.15s;
}

.crm-bascule[aria-checked="true"] i {
  background: var(--color-accent-500);
}

.crm-bascule[aria-checked="true"] i::after {
  left: 15px;
}

.crm-corps {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr);
  flex: 1;
  min-height: 0;
  gap: 0 10px;
  padding: 10px;
}

/* La liste des personnes */
.crm-liste {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

.crm-haut {
  position: relative;
  display: grid;
  gap: 9px;
  padding: 2px 6px 10px;
}

.crm-champ {
  width: 100%;
  padding: 7px 14px;
  border: 0;
  border-radius: 999px;
  font: var(--taille-texte) var(--font-body);
  background: var(--color-neutral-100);
  color: var(--color-text);
}

.crm-champ:focus {
  outline: 2px solid var(--color-accent-200);
}

.crm-filtres {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
}

.crm-filtre {
  padding: 3px 10px;
  border-radius: 999px;
  font-size: var(--taille-etiquette);
  color: var(--color-neutral-700);
  text-decoration: none;
  white-space: nowrap;
}

.crm-filtre--actif {
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-weight: 600;
}

.crm-periode {
  display: inline-block;
}

/* Le délai de relance du projet, sous le filtre « À relancer » (2026-10-01). */
.crm-delai {
  margin-top: 6px;
}

.crm-menu-date {
  position: absolute;
  left: 6px;
  right: 6px;
  top: 100%;
  z-index: 2;
  display: grid;
  gap: 1px;
  padding: 6px;
  border-radius: 14px;
  background: var(--crm-blanc);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  font-size: var(--taille-etiquette);
}

.crm-menu-date__choix {
  padding: 5px 10px;
  border-radius: 9px;
  color: inherit;
  text-decoration: none;
}

.crm-menu-date__choix:hover {
  background: var(--color-neutral-100);
}

.crm-menu-date__choix--actif {
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-weight: 600;
}

.crm-menu-date__libre {
  display: grid;
  gap: 4px;
  margin-top: 4px;
  padding: 6px 10px 4px;
  color: var(--color-neutral-700);
  border-top: 1px solid var(--color-neutral-200);
}

.crm-menu-date__champ {
  width: 118px;
  border: 0;
  border-bottom: 1px dotted var(--color-neutral-500);
  background: transparent;
  color: var(--color-text);
  font: var(--taille-etiquette) var(--font-body);
  padding: 1px 2px;
}

.crm-personnes {
  display: grid;
  align-content: start;
  gap: 2px;
  overflow: auto;
}

.crm-personne {
  display: grid;
  grid-template-columns: 34px 1fr auto;
  align-items: center;
  gap: 0 10px;
  padding: 8px 10px;
  border-radius: 12px;
  color: inherit;
  text-decoration: none;
}

.crm-personne:hover {
  background: var(--color-neutral-100);
}

.crm-personne--active,
.crm-personne--active:hover {
  background: var(--color-accent-100);
}

.crm-pastille {
  position: relative;
  grid-row: span 2;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--crm-fond);
  color: var(--crm-encre);
  font: 700 var(--taille-etiquette) var(--font-body);
}

/* Le jaune est réservé à la relance : une seule pastille le porte. */
.crm-pastille--alerte::after {
  content: "";
  position: absolute;
  right: 0;
  top: 0;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ef-sun);
  border: 2px solid var(--crm-blanc);
}

/* **La teinte stable d'une personne** : (31 × code de la 1re initiale + code de la 2de) modulo 8.
   Le rond prend le fond et l'encre, le nom dans le fil du projet l'encre seule. */
.crm-teinte-0 {
  --crm-fond: #e6eef7;
  --crm-encre: #2b4c7e;
}

.crm-teinte-1 {
  --crm-fond: #f3e6ef;
  --crm-encre: #7a3563;
}

.crm-teinte-2 {
  --crm-fond: #e8f1e4;
  --crm-encre: #3f6b2e;
}

.crm-teinte-3 {
  --crm-fond: #f6eae1;
  --crm-encre: #8a4b22;
}

.crm-teinte-4 {
  --crm-fond: #e4eff0;
  --crm-encre: #2f5e66;
}

.crm-teinte-5 {
  --crm-fond: #eee9f5;
  --crm-encre: #54408a;
}

.crm-teinte-6 {
  --crm-fond: #f2ece2;
  --crm-encre: #6e5a3a;
}

.crm-teinte-7 {
  --crm-fond: #f5e6e6;
  --crm-encre: #8a3434;
}


.crm-personne__nom {
  overflow: hidden;
  font-size: var(--taille-texte);
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.crm-personne__date {
  font-style: normal;
  font-size: var(--taille-etiquette);
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}

.crm-personne__apercu {
  grid-column: 2 / -1;
  overflow: hidden;
  font-size: var(--taille-etiquette);
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--color-text-muted);
}

.crm-personne__apercu--signal {
  color: var(--warn-ink);
}

/* Le fil */
.crm-fil {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  border-radius: 18px;
  background: color-mix(in srgb, var(--color-accent-100) 50%, var(--crm-blanc));
}

.crm-fil__tete {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  padding: 12px 18px 10px;
}

.crm-fil__titre {
  margin: 0;
  font-size: var(--taille-bloc);
  font-weight: 800;
}

.crm-fil__sous {
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.crm-fil__sous a {
  color: inherit;
  text-decoration: none;
}

.crm-fil__recherche {
  margin-left: auto;
}

.crm-champ--loupe {
  width: 180px;
  background: var(--crm-blanc);
}

.crm-liens {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 0 18px 10px;
}

.crm-liens a {
  padding: 3px 11px;
  border-radius: 999px;
  font-size: var(--taille-etiquette);
  font-weight: 600;
  color: var(--color-accent-500);
  text-decoration: none;
  background: var(--crm-blanc);
  box-shadow: 0 0 0 1px var(--color-accent-200);
}

.crm-liens a:hover {
  box-shadow: 0 0 0 1px var(--color-accent-500);
}

/* **En colonne inversée** : le navigateur ouvre le fil en bas, sur le plus récent, sans script ;
   le gabarit écrit donc les bulles du plus récent au plus ancien. */
.crm-defile {
  flex: 1;
  display: flex;
  flex-direction: column-reverse;
  gap: 6px;
  overflow: auto;
  padding: 6px 18px 14px;
}

/* Juste au-dessus du premier jour, comme la maquette : sans marge automatique, la colonne
   inversée le pose contre le plus ancien, et non contre le haut du fil. */
.crm-plus-anciens {
  align-self: center;
  padding: 2px 0 6px;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
  text-decoration: none;
}

.crm-jour {
  align-self: center;
  margin: 8px 0 2px;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: var(--taille-etiquette);
  font-weight: 600;
  color: var(--color-text-muted);
  background: var(--crm-blanc);
}

.crm-bulle {
  align-self: flex-start;
  max-width: 78%;
  padding: 9px 13px 7px;
  border-radius: 18px;
  font-size: var(--taille-texte);
  background: var(--crm-blanc);
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
}

.crm-bulle__pour {
  display: block;
  margin-bottom: 1px;
  font-size: var(--taille-etiquette);
  font-weight: 700;
  color: var(--crm-encre);
  text-decoration: none;
}

.crm-bulle__texte {
  margin: 0;
  white-space: pre-wrap;
}

/* Le pied d'une bulle : les gestes à gauche, la signature à droite, sur une seule ligne. */
.crm-bulle__pied {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  margin-top: 3px;
  font-size: var(--taille-etiquette);
}

.crm-bulle__meta {
  margin-left: auto;
  color: var(--color-text-muted);
}

/* Corriger et retirer, montrés au survol d'une bulle ou quand on y travaille. */
.crm-gestes {
  display: flex;
  gap: 10px;
  visibility: hidden;
}

.crm-bulle:hover .crm-gestes,
.crm-bulle:focus-within .crm-gestes,
.crm-gestes--ouverts {
  visibility: visible;
}

.crm-gestes__correction summary {
  cursor: pointer;
  color: var(--color-accent-500);
}

.crm-gestes__formulaire {
  display: grid;
  gap: 6px;
  margin-top: 6px;
}

.crm-gestes__champ {
  display: grid;
  gap: 2px;
  font-weight: 600;
}

/* Les étiquettes d'un échange (maquette du 2026-10-01, états 1 à 3) : sous la bulle, à gauche de
   la signature ; la croix ne paraît qu'au survol de la bulle. */
.crm-etiquettes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
}

.crm-etiquette {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 1px 9px;
  border-radius: var(--rayon-pilule);
  font-size: var(--taille-etiquette);
  font-weight: 600;
  color: var(--color-accent);
  background: var(--color-accent-100);
  white-space: nowrap;
}

.crm-etiquette__filtre {
  color: inherit;
  text-decoration: none;
}

.crm-etiquette__filtre:hover {
  text-decoration: underline;
}

.crm-etiquette__formulaire {
  display: inline;
}

.crm-etiquette__retirer {
  padding: 0 2px;
  border: 0;
  font-size: var(--taille-etiquette);
  line-height: 1;
  color: inherit;
  background: transparent;
  text-decoration: none;
  cursor: pointer;
}

.crm-bulle .crm-etiquette__retirer {
  visibility: hidden;
}

.crm-bulle:hover .crm-etiquette__retirer,
.crm-bulle:focus-within .crm-etiquette__retirer {
  visibility: visible;
}

.crm-etiquette__ajout {
  position: relative;
}

.crm-etiquette__ajout summary {
  font-weight: 600;
  color: var(--color-text-muted);
  cursor: pointer;
  list-style: none;
}

.crm-etiquette__ajout summary:hover {
  color: var(--color-accent-500);
}

.crm-etiquette__menu {
  position: absolute;
  z-index: 6;
  bottom: calc(100% + 6px);
  left: 0;
  display: grid;
  gap: 2px;
  width: 230px;
  max-height: 260px;
  overflow-y: auto;
  box-sizing: border-box;
  padding: 8px;
  border: 1px solid var(--color-divider);
  border-radius: var(--rayon-cadre);
  background: var(--color-bg);
}

.crm-etiquette__case {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--taille-texte);
  cursor: pointer;
}

.crm-etiquette__champ {
  box-sizing: border-box;
  width: 100%;
  padding: 4px 8px;
  border: 1px solid var(--color-divider);
  border-radius: var(--rayon-bouton);
  font-size: var(--taille-texte);
  color: var(--color-text);
  background: var(--color-bg);
}

/* La saisie, toujours en bas */
.crm-saisie {
  display: grid;
  gap: 6px;
  margin: 0 12px 12px;
  padding: 8px 8px 8px 16px;
  border-radius: 20px;
  background: var(--crm-blanc);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}

.crm-saisie__ligne {
  display: flex;
  align-items: flex-end;
  gap: 8px;
}

.crm-saisie__ligne textarea {
  flex: 1;
  min-height: 36px;
  max-height: 120px;
  padding: 6px 0;
  border: 0;
  box-sizing: border-box;
  resize: none;
  field-sizing: content;
  font: var(--taille-texte) var(--font-body);
  color: var(--color-text);
  background: transparent;
}

.crm-saisie__ligne textarea:focus {
  outline: none;
}

.crm-envoyer {
  flex: none;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: 50%;
  font-size: var(--taille-bloc);
  color: #fff;
  background: var(--color-accent);
  cursor: pointer;
}

.crm-reglages {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.crm-puce {
  padding: 2px 10px;
  border: 0;
  border-radius: 999px;
  font: var(--taille-etiquette) var(--font-body);
  color: var(--color-neutral-800);
  background: var(--color-neutral-100);
}

.crm-puce__champ {
  padding: 0;
  border: 0;
  font: inherit;
  color: inherit;
  background: transparent;
}

.crm-puce--date .crm-puce__champ {
  width: 104px;
}

/* **À la largeur de ce qu'il porte, dans une borne** : une adresse de connexion y entre entière,
   et un nom démesuré ne pousse pas les autres puces hors de la saisie. */
.crm-puce--ef .crm-puce__champ {
  width: auto;
  field-sizing: content;
  min-width: 8ch;
  max-width: 34ch;
  border-bottom: 1px dotted var(--color-neutral-500);
}

.crm-puce:focus-within {
  outline: 2px solid var(--color-accent-200);
}

/* Doctrine, regle 9 : eteinte, la fleche prend le dessin de tout bouton eteint. Sa forme ronde
   attend l'arbitrage d'Antoine (revue du 2026-10-02, 05 §13). */
.crm-envoyer:disabled {
  background: transparent;
  color: var(--void-ink);
  border: 1px dashed var(--color-neutral-500);
  cursor: not-allowed;
}

/* La rangée « avec », au-dessus du texte (maquette du 2026-09-26, partie 4) : une puce par
   personne choisie, son rond du CRM et sa croix, puis le « + » de l'équipe du Général. */
.crm-avec {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding-top: 2px;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.crm-avec__personne {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 4px 2px 2px;
  border-radius: 999px;
  font: 600 var(--taille-etiquette) var(--font-body);
  color: var(--color-accent);
  background: var(--color-accent-100);
}

.crm-avec__personne--fixe {
  padding-right: 10px;
}

.crm-avec__rond {
  display: inline-grid;
  place-items: center;
  flex: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--crm-fond);
  color: var(--crm-encre);
  font: 700 var(--taille-etiquette) var(--font-body);
  font-style: normal;
}

.crm-avec__retirer {
  padding: 0 4px;
  border: 0;
  border-radius: 50%;
  font: 700 var(--taille-texte)/1 var(--font-body);
  color: var(--color-accent-500);
  background: transparent;
  cursor: pointer;
}

.crm-avec__retirer:hover {
  background: var(--color-accent-200);
}

.crm-avec__choix {
  position: relative;
}

.crm-avec__ajouter {
  display: block;
  width: 22px;
  height: 22px;
  box-sizing: border-box;
  padding: 0;
  border: 1px dashed var(--color-neutral-400);
  border-radius: 50%;
  font: 600 var(--taille-texte)/20px var(--font-body);
  text-align: center;
  color: var(--color-text-muted);
  background: var(--color-bg);
  cursor: pointer;
  list-style: none;
}

.crm-avec__ajouter::-webkit-details-marker {
  display: none;
}

.crm-avec__ajouter:hover,
.crm-avec__choix[open] > .crm-avec__ajouter {
  border-style: solid;
  border-color: var(--color-accent-500);
  color: var(--color-accent);
}

/* **Ouvert vers le haut** : la saisie est en bas du fil. */
.crm-avec__menu {
  position: absolute;
  z-index: 6;
  bottom: calc(100% + 6px);
  left: 0;
  display: grid;
  gap: 2px;
  width: 250px;
  max-height: 320px;
  overflow-y: auto;
  box-sizing: border-box;
  padding: 8px;
  border-radius: 14px;
  background: var(--color-bg);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.12);
}

.crm-avec__chercher {
  width: 100%;
  box-sizing: border-box;
  margin-bottom: 4px;
  padding: 6px 12px;
  border: 0;
  border-radius: 999px;
  font: 400 var(--taille-texte) var(--font-body);
  color: var(--color-text);
  background: var(--color-neutral-100);
}

.crm-avec__case {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border-radius: 9px;
  font-size: var(--taille-texte);
  cursor: pointer;
}

.crm-avec__case:hover {
  background: var(--color-neutral-100);
}

.crm-avec__case[hidden] {
  display: none;
}

.crm-avec__coche {
  margin: 0;
  accent-color: var(--color-accent);
}

/* Un nom long passe à la ligne, la raison restant à droite, comme sur la maquette. */
.crm-avec__nom {
  min-width: 0;
}

.crm-avec__case small {
  margin-left: auto;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.crm-avec__filet {
  margin: 4px 6px;
  border: 0;
  border-top: 1px solid var(--color-neutral-200);
}

.crm-brouillon-perdu {
  margin: 10px;
  padding: 10px 14px;
  border-radius: 14px;
  background: var(--warn-bg);
  color: var(--warn-ink);
}

/* --- La vue par entité du classeur — maquette A, « la fiche épurée », 2026-09-27 --------------- */
/* **Recopie de la maquette** (`docs/refonte_ui/entites_a.html`) : les pièces d'« Échanges », trois
   tailles de texte (12, 13 et 17 px), un rond pour une personne et un carré pour une chose du
   foncier. Les valeurs sont celles de la maquette, rapportées aux jetons de la feuille. */
.entites {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  font-size: var(--taille-texte);
}

.entites__corps {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr);
  flex: 1;
  min-height: 0;
  gap: 0 10px;
  padding: 10px;
}

.entites__ic {
  flex: none;
  width: 14px;
  height: 14px;
}

/* La colonne : la tête d'« Échanges », puis ses lignes. */
.entites__colonne {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

.entites__haut {
  position: relative;
  display: grid;
  gap: 9px;
  padding: 2px 6px 10px;
}

.entites__cherche {
  display: flex;
  align-items: center;
  gap: 6px;
}

.entites__recherche {
  flex: 1;
  min-width: 0;
}

.entites__champ-rond {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
  padding: 6px 14px;
  border: 0;
  border-radius: 999px;
  font: var(--taille-texte) var(--font-body);
  color: var(--color-text);
  background: var(--color-neutral-100);
}

.entites__champ-rond:focus {
  outline: 2px solid var(--color-accent-200);
}

.entites__regroupements {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
}

.entites__regroupement,
.entites__liens-onglet {
  padding: 3px 7px;
  border-radius: 999px;
  font-size: var(--taille-etiquette);
  color: var(--color-neutral-700);
  text-decoration: none;
  white-space: nowrap;
}

.entites__regroupement:hover,
.entites__liens-onglet:hover {
  background: var(--color-neutral-100);
}

.entites__regroupement--actif,
.entites__liens-onglet--actif,
.entites__regroupement--actif:hover {
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-weight: 600;
}

.entites__compte {
  font-weight: inherit;
}

.entites__lignes {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: auto;
  display: grid;
  align-content: start;
  gap: 2px;
}

/* La ligne d'« Échanges », pour les quatre natures (note 2). */
.entites__ligne {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  align-items: center;
  gap: 0 10px;
  min-height: 52px;
  box-sizing: border-box;
  padding: 8px 10px;
  border-radius: 12px;
  color: inherit;
  text-decoration: none;
  scroll-margin-top: 40px;
}

.entites__ligne:hover {
  background: var(--color-neutral-100);
}

.entites__ligne--actif,
.entites__ligne--actif:hover {
  background: var(--color-accent-100);
}

/* La ligne ouverte revient en vue par son ancre ; elle n'a pas à porter l'anneau du clavier. */
.entites__ligne:target:not(:focus-visible) {
  outline: none;
}

.entites__pastille {
  position: relative;
  grid-row: span 2;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--crm-fond);
  color: var(--crm-encre);
  font: 700 var(--taille-etiquette) var(--font-body);
}

/* Un rond désigne quelqu'un ; un carré une chose du foncier (Antoine, 2026-09-27, piste 2). */
.entites__carre {
  position: relative;
  grid-row: span 2;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  color: var(--color-text-muted);
  background: var(--color-neutral-100);
  box-shadow: inset 0 0 0 1px var(--color-neutral-300);
}

.entites__carre .entites__ic {
  width: 18px;
  height: 18px;
}

.entites__carre--petit {
  grid-row: auto;
  flex: none;
  width: 20px;
  height: 20px;
  border-radius: 6px;
}

.entites__carre--petit .entites__ic {
  width: 12px;
  height: 12px;
}

.entites__pastille--alerte::after {
  content: "";
  position: absolute;
  right: 0;
  top: 0;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ef-sun);
  border: 2px solid var(--crm-blanc);
}

.entites__nom {
  overflow: hidden;
  font-size: var(--taille-texte);
  font-weight: 600;
  line-height: 1.35;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.entites__droite {
  font-style: normal;
  font-size: var(--taille-etiquette);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--color-text-muted);
}

.entites__seconde {
  grid-column: 2 / -1;
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  min-height: 1em;
  font-size: var(--taille-etiquette);
  line-height: 1.35;
  color: var(--color-text-muted);
}

.entites__seconde-texte {
  overflow: hidden;
  min-width: 0;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.entites__suite {
  justify-self: center;
  padding: 6px 0;
  font: 600 var(--taille-etiquette) var(--font-body);
  color: var(--color-accent-500);
  text-decoration: none;
}

/* La pastille d'état, la même partout : les couleurs du code couleur du FGF, posées par
   `classeur.js` depuis `data-fond` et `data-encre`. */
.entites__etat {
  display: inline-flex;
  flex: none;
  align-items: center;
  gap: 4px;
  height: 22px;
  padding: 0 9px;
  border: 0;
  border-radius: 999px;
  font: 600 var(--taille-etiquette) var(--font-body);
  white-space: nowrap;
  color: var(--color-text);
  background: var(--color-neutral-200);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.06);
  text-decoration: none;
}

.entites__etat--vide {
  font-weight: 500;
  color: var(--color-text-muted);
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--color-neutral-300);
}

.entites__etat--petit {
  height: 18px;
  padding: 0 7px;
  font-weight: 500;
}

/* Les menus : le « + » de la colonne, « Associer », « Ranger ». */
.entites__nouveau,
.entites__ancre,
.entites__geste {
  position: relative;
}

.entites__geste-titre {
  list-style: none;
}

.entites__lien {
  color: inherit;
}

.entites__texte {
  min-width: 0;
}

.entites__menu {
  position: absolute;
  z-index: 9;
  top: calc(100% + 6px);
  left: 0;
  display: grid;
  gap: 2px;
  width: 320px;
  box-sizing: border-box;
  padding: 8px;
  border-radius: 14px;
  background: var(--crm-blanc);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.14);
}

.entites__menu--nouveau {
  left: auto;
  right: 0;
  width: 250px;
}

.entites__menu .entites__champ-rond {
  margin-bottom: 4px;
}

.entites__choix-liste {
  display: grid;
  gap: 2px;
  max-height: 260px;
  overflow-y: auto;
}

.entites__choix {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border-radius: 9px;
  font-size: var(--taille-texte);
  cursor: pointer;
}

.entites__choix:hover {
  background: var(--color-neutral-100);
}

.entites__choix[hidden] {
  display: none;
}

.entites__choix input {
  margin: 0;
  accent-color: var(--color-accent);
}

.entites__choix small {
  margin-left: auto;
  font-size: var(--taille-etiquette);
  white-space: nowrap;
  color: var(--color-text-muted);
}

.entites__choix--creer {
  font-weight: 600;
  color: var(--color-accent);
}

.entites__filet {
  width: calc(100% - 12px);
  margin: 4px 6px;
  border: 0;
  border-top: 1px solid var(--color-neutral-200);
}

.entites__pied-menu {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 6px 8px 2px;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.entites__pied-menu select {
  padding: 3px 8px;
  border: 1px solid var(--color-neutral-300);
  border-radius: 8px;
  font: var(--taille-texte) var(--font-body);
  background: var(--crm-blanc);
}

.entites__pied-menu > .btn {
  margin-left: auto;
}

.entites__types {
  display: flex;
  gap: 2px;
  padding: 2px 2px 4px;
}

.entites__type {
  padding: 3px 10px;
  border-radius: 999px;
  font-size: var(--taille-etiquette);
  color: var(--color-neutral-700);
  cursor: pointer;
}

.entites__type input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.entites__type:has(input:checked) {
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-weight: 600;
}

.entites__type:focus-within {
  outline: 2px solid var(--color-accent-200);
}

/* Le code couleur en bulle, par-dessus, sans rien pousser (note 9). */
.entites__couleurs {
  position: relative;
}

.entites__couleurs[open] > .entites__couleurs-bouton {
  background: var(--crm-blanc);
}

.entites__bulle-couleurs {
  position: absolute;
  z-index: 9;
  top: calc(100% + 4px);
  right: 0;
  display: grid;
  gap: 6px;
  width: 430px;
  max-width: calc(100vw - 32px);
  box-sizing: border-box;
  padding: 10px 14px 12px;
  border-radius: 14px;
  background: var(--crm-blanc);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.14);
}

.entites__bulle-couleurs h5 {
  margin: 2px 0 0;
  font: 600 var(--taille-etiquette) var(--font-body);
  color: var(--color-text-muted);
}

.entites__couleurs-valeurs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

/* La fiche. */
.entites__fiche {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  border-radius: 18px;
  background: color-mix(in srgb, var(--color-accent-100) 50%, var(--crm-blanc));
}

.entites__fil-retour {
  padding: 12px 18px 0;
}

.entites__retour {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 14px 0 4px;
  font: 600 var(--taille-etiquette) var(--font-body);
  color: var(--color-accent-500);
  text-decoration: none;
}

.entites__tete {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  margin: 4px 6px 0;
  padding: 12px 18px 10px;
}

.entites__fil-retour + .entites__tete {
  padding-top: 8px;
}

.entites__titre {
  margin: 0;
  font: 800 var(--taille-bloc)/1.3 var(--font-heading);
}

.entites__icone {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  margin-left: -6px;
  border-radius: 50%;
  color: var(--color-text-muted);
  cursor: pointer;
  list-style: none;
}

.entites__icone::-webkit-details-marker {
  display: none;
}

.entites__icone:hover {
  background: var(--crm-blanc);
  color: var(--color-accent);
}

.entites__renommer[open] {
  display: contents;
}

.entites__renommer[open] > .entites__icone {
  display: none;
}

.entites__sous-titre {
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.entites__commandes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0 6px 4px;
  padding: 0 12px 4px;
}

.entites__en-ligne {
  display: inline-flex;
  margin: 0;
}

.entites__corps-fiche {
  flex: 1;
  min-height: 0;
  overflow: auto;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-content: start;
  gap: 12px 16px;
  padding: 16px 18px 18px;
}

.entites__corps-fiche--une {
  grid-template-columns: minmax(0, 1fr);
}

.entites__col-faits,
.entites__col-droite,
.entites__col-seule {
  display: grid;
  align-content: start;
  gap: 10px;
  min-width: 0;
}

.entites__bloc {
  padding: 10px 14px 12px;
  border-radius: 14px;
  background: var(--crm-blanc);
}

.entites__bloc h4,
.entites__entete-bloc h4 {
  margin: 0 0 6px;
  font: 600 var(--taille-etiquette) var(--font-body);
  color: var(--color-text-muted);
}

.entites__faits {
  display: grid;
  grid-template-columns: 128px minmax(0, 1fr);
  align-items: baseline;
  gap: 4px 12px;
  margin: 0;
}

.entites__fait-nom {
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.entites__fait-valeur {
  min-width: 0;
  margin: 0;
  font-size: var(--taille-texte);
  overflow-wrap: anywhere;
}

.entites__fait-ouvrir {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  min-height: 22px;
  margin-left: -6px;
  padding: 1px 6px;
  border-radius: 6px;
  color: var(--color-text);
  text-decoration: none;
}

.entites__fait-ouvrir:hover {
  background: var(--color-neutral-100);
}

.entites__ic--survol {
  opacity: 0;
  color: var(--color-text-muted);
}

.entites__fait-ouvrir:hover .entites__ic--survol,
.entites__fait-ouvrir:focus .entites__ic--survol {
  opacity: 1;
}

.entites__fait-ouvrir--vide {
  min-width: 84px;
  border-radius: 6px 6px 0 0;
  box-shadow: inset 0 -1px 0 var(--color-neutral-300);
}

.entites__fait-ouvrir--long {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-left: 0;
}

.entites__texte--long {
  white-space: pre-wrap;
}

.entites__fait-absent {
  color: var(--color-text-muted);
  cursor: help;
}

.entites__valeurs {
  display: grid;
  gap: 2px;
}

/* La saisie d'un fait, et la correction de l'identifiant. */
.entites__saisie,
.entites__edition {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0;
}

.entites__champ {
  min-width: 0;
  max-width: 100%;
  padding: 3px 10px;
  border: 1px solid var(--color-accent-200);
  border-radius: 8px;
  font: var(--taille-texte) var(--font-body);
  color: var(--color-text);
  background: var(--crm-blanc);
}

.entites__menu .entites__champ {
  padding: 6px 14px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-100);
}

.entites__champ--long {
  width: 100%;
  padding: 6px 10px;
  border-radius: 10px;
  font: var(--taille-texte)/1.5 var(--font-body);
  resize: vertical;
}

/* Les échanges d'une personne, avec la saisie d'« Échanges » (note 6). */
.entites__echanges {
  display: grid;
  align-content: start;
  gap: 6px;
  min-width: 0;
}

.entites__entete-bloc {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 0 4px;
}

.entites__entete-bloc h4 {
  margin: 0;
}

.entites__lien-sobre {
  font: 600 var(--taille-etiquette) var(--font-body);
  color: var(--color-accent-500);
  text-decoration: none;
}

.entites__fil {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.entites__jour {
  align-self: center;
  padding: 2px 10px;
  border-radius: 999px;
  font: 600 var(--taille-etiquette) var(--font-body);
  color: var(--color-text-muted);
  background: var(--crm-blanc);
}

.entites__bulle {
  align-self: flex-start;
  max-width: 94%;
  padding: 9px 13px 7px;
  border-radius: 18px;
  font-size: var(--taille-texte);
  background: var(--crm-blanc);
  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
}

.entites__bulle--nouvelle {
  background: var(--ok-bg);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--ok-ink) 20%, var(--ok-bg));
}

.entites__bulle-texte {
  margin: 0;
  white-space: pre-wrap;
}

.entites__bulle-meta {
  display: block;
  margin-top: 3px;
  text-align: right;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

/* La saisie d'« Échanges », à la taille de la maquette : aucun texte sous 12 px ici. */
.entites .crm-saisie {
  margin: 4px 0 0;
  padding: 8px 8px 8px 14px;
}

.entites .crm-avec,
.entites .crm-avec__personne,
.entites .crm-reglages,
.entites .crm-puce,
.entites .crm-avec__case small {
  font-size: var(--taille-etiquette);
}

.entites .crm-avec__rond {
  width: 20px;
  height: 20px;
  font-size: var(--taille-etiquette);
}

.entites .crm-avec__menu {
  top: calc(100% + 6px);
  bottom: auto;
}

/* Les entités liées (note 7). */
.entites__liees {
  display: grid;
  align-content: start;
  gap: 8px;
  min-width: 0;
}

.entites__liens-onglets {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
}

.entites__liens {
  padding: 6px;
  border-radius: 14px;
  background: var(--crm-blanc);
}

.entites__parcelles {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 6px;
}

.entites__parcelle {
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  background: var(--crm-blanc);
  box-shadow: 0 0 0 1px var(--color-accent-200);
}

.entites__parcelle > .entites__lien {
  padding: 3px 2px 3px 11px;
  font: 600 var(--taille-etiquette) var(--font-body);
  color: var(--color-accent-500);
  text-decoration: none;
}

.entites__rattacher {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 4px 0 0;
  padding: 8px 6px 4px;
  border-top: 1px solid var(--color-neutral-200);
}

.entites__rattacher .entites__champ-rond {
  flex: none;
  width: 190px;
}

/* Supprimer, à part, et son aperçu en tête de fiche (note 8). */
.entites__pied {
  grid-column: 1 / -1;
  display: flex;
  justify-content: flex-end;
  padding-top: 6px;
}

.entites__confirmation {
  grid-column: 1 / -1;
  display: grid;
  gap: 8px;
  padding: 12px 16px;
  border-radius: 14px;
  background: var(--crm-blanc);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--refus-bord) 35%, var(--crm-blanc));
}

.entites__confirmation h4 {
  margin: 0;
  font: 700 var(--taille-texte) var(--font-body);
  color: var(--refus-bord);
}

.entites__confirmation-phrase {
  margin: 0;
}

.entites__confirmation dl {
  display: grid;
  grid-template-columns: 118px minmax(0, 1fr);
  gap: 4px 12px;
  margin: 0;
}

.entites__confirmation dt {
  padding-top: 1px;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.entites__confirmation dd {
  margin: 0;
}

.entites__confirmation ul {
  display: grid;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.entites__pli summary {
  font-size: var(--taille-etiquette);
  color: var(--color-accent-500);
  cursor: pointer;
}

.entites__bascule {
  justify-self: start;
  margin-left: 0;
  font-size: var(--taille-etiquette);
}

.entites__boutons {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}

.entites__droit {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.entites__note {
  margin: 0;
  font-size: var(--taille-etiquette);
  line-height: 1.4;
  color: var(--color-text-muted);
}

.entites__note--fiche {
  margin: 0 24px 6px;
}

.entites__vide {
  margin: 12px 14px;
  font-size: var(--taille-etiquette);
  font-weight: 500;
  line-height: 1.4;
  color: var(--color-neutral-700);
}

/* Ce qu'on écrit à la place de la fiche quand la lecture a échoué. */
.entites__attente {
  margin: 16px;
  padding: 10px;
  border-radius: 12px;
  font-size: var(--taille-texte);
  color: var(--warn-ink);
  background: var(--warn-bg);
}

@media (max-width: 1200px) {
  .entites__corps-fiche {
    grid-template-columns: minmax(0, 1fr);
  }

  .entites__col-droite {
    order: -1;
  }

  .entites__confirmation {
    order: -2;
  }
}

/* --- Les cases de la table du classeur — motif M6 + M8, ecrit le 2026-09-04 -------------------- */
/* **Trois formes, et une seule a la fois** : ouverte a la saisie, saisissable mais fermee, ou
   fermee pour de bon. La classe dit laquelle ; le composeur a decide. */
.classeur-case {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* **Le lien qui ouvre une case, souligne** : c'est ce qui distingue a l'oeil une case saisissable
   d'une case calculee, et la note au-dessus de la table le dit en toutes lettres.

   **La hauteur minimale n'est pas cosmetique.** Le contenu du lien est la valeur de la case ; une
   case vide donnait un lien vide, donc un bloc de hauteur nulle : rien a cliquer, et rien a voir.
   Or une case vide est precisement celle qu'on vient remplir. Releve en revue le 2026-09-04. */
.classeur-case__ouvrir {
  /* **Pas de `display` ici**, et c'est ce qui rend le pli possible. Cette regle vient plus loin
     dans la feuille que `.classeur-case__texte`, a specificite egale : un `display: block` y
     gagnait, et `-webkit-line-clamp` n'agit que sur `-webkit-box`. Les cases saisissables — dont
     COMPTE_RENDU, la colonne que la demande cite — ne se pliaient pas. Releve en revue le
     2026-09-06. Le lien est de toute facon pose en bloc par `.classeur-case__texte`. */
  min-height: 1.3em;
  color: inherit;
  text-decoration: none;
  text-decoration-style: dotted;
  text-underline-offset: 2px;
}

/* **Le pointille au survol de la ligne seulement** (repasse de la maquette FGF, 2026-09-25) : pose
   sous chaque valeur, il soulignait le tableau entier. La case vide garde son filet. */
.classeur-table tr:hover .classeur-case__ouvrir,
.classeur-case__ouvrir:focus-visible {
  text-decoration-line: underline;
}

/* Une case vide qui se saisit : un filet pointille dit qu'on peut y ecrire. **C'est du dessin, pas
   du contenu** — rien n'est ecrit dans la case, et le filet ne se copie pas avec le texte. */
.classeur-case__ouvrir:empty::after {
  content: "";
  display: inline-block;
  min-width: 4ch;
  border-bottom: 1px dotted currentColor;
  opacity: 0.55;
  vertical-align: middle;
}

/* **Le liseret jaune de la convention M6.** Il tient jusqu'a l'enregistrement du projet : c'est ce
   que « modifie, non sauvegarde » veut dire, et le registre des cellules saisies le fait survivre
   a un changement de page. */
/* **Une barre jaune a gauche, et non un encadre** (Antoine, 2026-09-05) : l'encadre fermait la
   case et se confondait avec la bordure de la table sur une colonne etroite. */
/* Doctrine, regle 12 : un nombre tient sur une ligne, aligne a droite, en chiffres a chasse
   fixe, son en-tete aussi. Plie sur deux lignes, il doublait la hauteur de chaque ligne du
   tableau. La colonne se reconnait au type que le moteur lui donne (`colonnes_de_nombres`). */
.classeur-case--nombre .classeur-case__texte {
  display: block;
  white-space: nowrap;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* **Un texte dans une colonne de nombres s'arrete a 260 px** (Antoine, 2026-10-04) : le moteur
   type la colonne « nombre », mais une case peut porter un texte, et la colonne s'elargissait sans
   fin. Il finit par « … » et se lit au survol, comme un texte. Un vrai nombre ou une date tient
   bien en deca : il ne se coupe pas. */
.classeur-table .classeur-case--nombre .classeur-case__texte {
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* La case choisie d'un clic, avant qu'un second clic ou Entree ne l'ouvre. */
.classeur-case--choisie {
  box-shadow: inset 0 0 0 2px var(--color-accent);
}

.classeur-case--modifiee {
  box-shadow: inset 3px 0 0 var(--ef-sun);
}

/* Choisie et modifiee : les deux marques ensemble, la seconde regle ecrasant la premiere. */
.classeur-case--modifiee.classeur-case--choisie {
  box-shadow: inset 3px 0 0 var(--ef-sun), inset 0 0 0 2px var(--color-accent);
}

/* **Pendant l'ecriture d'une case** (constat 04 §3, maquette du chantier 5) : la case qui s'ecrit
   palit, un trait court sous elle, le curseur attend ; la case cliquee entre-temps garde un cadre
   pointille. Le trait est un fond, et non un `::after` pose en absolu : la premiere colonne est
   collee au defilement, et une position relative l'en decrocherait. */
.classeur-case.classeur-case--en-ecriture {
  color: var(--color-text-muted);
  cursor: progress;
  background-image: linear-gradient(90deg, transparent, var(--color-accent), transparent);
  background-size: 50% 2px;
  background-repeat: no-repeat;
  background-position: -50% 100%;
  animation: classeur-case-qui-s-ecrit 1s linear infinite;
}

@keyframes classeur-case-qui-s-ecrit {
  to {
    background-position: 150% 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .classeur-case.classeur-case--en-ecriture {
    animation: none;
    background-size: 100% 2px;
  }
}

/* **Un pointille d'accent, sans le filet plein de la case choisie** (revue du chantier 5, C3) : le
   pointille en `--color-surface` se perdait sur le fond de la case, et l'attente ressemblait au
   choix dans les deux themes. L'accent sur la surface : 9,53 pour 1 en clair, 4,26 en sombre.
   Deux classes, pour l'emporter sur une case choisie et modifiee ; le liseret jaune d'une case
   modifiee se garde a part. */
.classeur-case.classeur-case--en-attente {
  box-shadow: none;
  outline: 2px dashed var(--color-accent);
  outline-offset: -2px;
  cursor: progress;
}

.classeur-case--modifiee.classeur-case--en-attente {
  box-shadow: inset 3px 0 0 var(--ef-sun);
}

/* La case que la session a acceptee porte une coche ; le liseret jaune, lui, reste jusqu'a
   l'enregistrement du FGF. */
.classeur-case--acceptee .classeur-case__texte::before {
  content: "\2713\00a0";
  color: var(--etat-acquis);
  font-weight: 700;
}

/* Une case que rien ne peut saisir : ni soulignee, ni cliquable. */
.classeur-case--fermee {
  color: inherit;
}

/* La case ouverte : elle deborde volontiers, le temps qu'on tape.

   **La case devient le champ** (option A, validee par Antoine le 2026-09-23) : fond blanc, une
   bordure interieure jaune de deux pixels, et plus de champ encadre a l'interieur. */
.classeur-case--edition {
  max-width: none;
  overflow: visible;
  white-space: normal;
  background: #fff;
  box-shadow: inset 0 0 0 2px var(--ef-sun);
}

.classeur-case__saisie {
  display: flex;
  align-items: center;
  gap: 6px;
}

/* L'unite d'une superficie saisie, a droite du champ : on tape des m2, pas les hectares affiches. */
.classeur-case__unite {
  flex: none;
  padding-left: 4px;
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
}

.classeur-case__champ {
  min-width: 0;
  flex: 1;
  padding: 0;
  border: 0;
  outline: none;
  background: transparent;
  color: inherit;
  font: inherit;
}

.classeur-case__bouton {
  flex: none;
  padding: 3px 8px;
  font-size: var(--taille-etiquette);
}

.classeur-case__abandon {
  flex: none;
  color: var(--color-neutral-700);
  font: 500 var(--taille-etiquette)/1.3 var(--font-body);
}

/* Ce qui se saisit sur l'onglet ouvert, ecrit une fois au-dessus de la table. */
/* **Deux notes, deux classes, et une seule declaration.** La premiere dit ce qui se saisit sur
   l'onglet, la seconde pourquoi un geste n'y est pas offert : un controle garde que la premiere
   disparait quand l'onglet se saisit, et les confondre l'aurait fait rougir sur la seconde. */
.classeur__note-de-saisie,
.classeur__note-du-geste {
  margin: 0 0 8px;
  color: var(--color-neutral-700);
  font-size: var(--taille-etiquette);
  font-weight: 500;
  line-height: 1.4;
}

/* L'adresse ouvre une case absente de la page affichee : la phrase se distingue de la note
   ordinaire, sinon elle passe pour la meme information. */
.classeur__note-de-saisie--alerte {
  color: var(--color-neutral-900);
  border-left: 2px solid var(--ef-sun);
  padding-left: 8px;
  font-weight: 600;
}

/* --- Le filtre par colonne du classeur (2026-09-07, repris le soir meme) ---------------------- */
/*
   **Le motif du tableur** (Antoine) : le filtre vit dans l'en-tete de sa colonne, ouvert par un
   bouton, et la colonne filtree porte un entonnoir. La barre au-dessus de la table a disparu :
   elle demandait de designer la colonne une seconde fois, dans une liste.

   **Ouvert par le navigateur** : c'est un `details`, donc rien a autoriser cote politique de
   securite, et le panneau s'atteint au clavier.
*/

/* La phrase qui decrit la table filtree. Elle voyage avec la table, pas avec la barre du haut. */
.classeur__filtre-etat {
  margin: 0 0 8px;
  font-weight: 600;
}

/* L'en-tete tient son nom et son bouton sur une ligne, le bouton pousse a droite comme dans un
   tableur. `position: relative` porte le panneau, qui se pose dessous. */
.classeur__entete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  /* **Le bouton reste a cote du nom, jamais dessous** (Antoine, 2026-09-07 au soir). Une seconde
     regle portait la meme classe, plus haut dans ce fichier, avec `flex-wrap: wrap` : le bouton
     passait a la ligne des que la colonne se serrait. Elle est partie — un seul gabarit portait
     cette classe —, et les deux proprietes sont reposees ici pour que personne n'ait a le savoir. */
  flex-wrap: nowrap;
  margin: 0;
}

/* La poignee qui elargit une colonne (Antoine, 2026-09-08) : un bord droit qu'on tire.

   **Posee par le script, jamais servie dans la page.** Sans script, il n'y a pas de poignee et le
   tableau garde ses quatre tailles — ce qui reste utilisable, contrairement a une poignee dessinee
   qui ne repondrait pas.

   `col-resize` est le curseur que tout le monde connait des tableurs : c'est le geste qu'Antoine a
   decrit, et le navigateur le dessine lui-meme. */
/* **Elle s'ancre sur l'en-tete sans qu'on ait rien a poser dessus** : un `th` en `position:
   sticky` est deja un bloc conteneur. Une premiere redaction ajoutait `position: relative`, qui
   l'emportait en specificite sur le `sticky` de la maquette — les en-tetes du classeur cessaient
   de tenir en haut du cadre. Releve en revue et mesure au navigateur le 2026-09-08. */
.classeur__poignee-de-largeur {
  position: absolute;
  top: 0;
  right: 0;
  width: 6px;
  height: 100%;
  cursor: col-resize;
  /* Elle ne se dessine pas elle-meme : depuis le 2026-09-21, le bord interieur d'une colonne
     porte un trait, et la poignee se prend dessus. C'est le curseur qui annonce le geste.
     **Sauf sur le bord droit de la derniere colonne**, qui est celui de la table : en lecture
     seule, ou la colonne du « + » n'est pas rendue, la poignee y est posee sans trait.

     **Six pixels, et ils tombent sur la marge interieure de l'en-tete** : mesure au navigateur le
     2026-09-08, le bouton de filtre reste entierement cliquable, sans chevauchement. */
  background: transparent;
  touch-action: none;
}

/* **Le titre compte dans la largeur de sa colonne** (doctrine, regle 12 ; Antoine, 2026-10-04) :
   une colonne est au moins large de son titre, jusqu'a 260 px, ou il se coupe par « … ». */
.classeur__intitule {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* **L'intitule suit ses valeurs** (doctrine, regle 12) : sur une colonne a droite, le menu passe a
   gauche et le titre finit au meme bord que les nombres et les dates. */
.classeur-colonne--nombre .classeur__entete,
.donnees-table__nombre .classeur__entete {
  flex-direction: row-reverse;
}

.classeur-colonne--nombre .classeur__intitule {
  text-align: right;
}

/* Le signe du tri reste colle au titre, de l'autre cote du menu. */
.classeur-colonne--nombre .classeur__signe-du-tri,
.donnees-table__nombre .classeur__signe-du-tri {
  margin-left: auto;
}

/* **Une case ouverte a la saisie garde l'alignement de sa colonne** (doctrine, regle 12). */
.classeur-case--nombre .classeur-case__champ {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.classeur__filtre-colonne {
  position: relative;
  flex: none;
}

/* **Le triangle par defaut de `summary` s'enleve des deux facons** : l'ancienne, propre a
   WebKit, et la moderne. Sans les deux, un triangle noir double le chevron sur Safari. */
.classeur__filtre-bouton {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 3px;
  cursor: pointer;
  color: inherit;
  opacity: 0.75;
}

.classeur__filtre-bouton::-webkit-details-marker {
  display: none;
}

.classeur__filtre-bouton:hover,
.classeur__filtre-bouton:focus-visible {
  opacity: 1;
  background: rgb(255 255 255 / 20%);
}

/* Une colonne filtree se voit sans survol : son entonnoir reste plein. Le panneau ouvert aussi,
   sans quoi le bouton palirait sous le panneau qu'il vient d'ouvrir. */
.classeur__filtre-colonne--actif > .classeur__filtre-bouton,
.classeur__filtre-colonne[open] > .classeur__filtre-bouton {
  opacity: 1;
}

.classeur__signe-du-filtre {
  width: 14px;
  height: 14px;
}

/* --- Ajouter, renommer une colonne (2026-09-17) ---------------------------------------------- */

/* La colonne du « + » : juste la place du bouton, pour ne rien prendre a la donnee. */
.classeur__col-d-ajout {
  width: 40px;
}

.classeur__ajout-de-colonne {
  text-align: center;
}

.classeur__ajout {
  position: relative;
  display: inline-block;
}

/* **Le « + » se lit comme un bouton sans survol** : un signe nu au bout des en-tetes passerait
   pour un reste de mise en page. Meme famille que le bouton du filtre, cadre en plus. */
.classeur__ajout-bouton {
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  /* **La couleur du texte de l'en-tête**, et non un blanc : l'en-tête est clair en theme clair et
     sombre en theme sombre, et un cadre blanc disparaissait sur le premier. */
  border: 1px solid currentColor;
  border-radius: 4px;
  opacity: 0.75;
  font-size: var(--taille-bloc);
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  color: inherit;
}

.classeur__ajout-bouton::-webkit-details-marker {
  display: none;
}

.classeur__ajout-bouton:hover,
.classeur__ajout-bouton:focus-visible,
.classeur__ajout[open] > .classeur__ajout-bouton {
  opacity: 1;
  background: rgb(127 127 127 / 18%);
}

/* Le panneau s'aligne a droite du bouton : la colonne est la derniere, et un panneau ouvert vers
   la droite sortirait du cadre de la table. */
.classeur__ajout-panneau {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 16rem;
  padding: 12px;
  background: var(--color-surface, #fff);
  color: var(--color-text, inherit);
  border: 1px solid var(--color-divider);
  border-radius: 4px;
  box-shadow: 0 6px 18px rgb(0 0 0 / 18%);
  font-weight: 400;
  text-align: left;
  text-transform: none;
  letter-spacing: normal;
  cursor: auto;
}

.classeur__ajout-champ {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.classeur__ajout-libelle {
  font-size: var(--taille-etiquette);
  font-weight: 600;
  color: var(--color-text-muted, inherit);
}

.classeur__ajout-panneau .btn {
  align-self: flex-end;
}

/* La case qui remplace le nom pendant qu'on le renomme : elle prend la place du nom, sans agrandir
   la colonne. */
.classeur__renommage {
  width: 100%;
  min-width: 0;
  padding: 1px 4px;
  font: inherit;
  text-transform: none;
  letter-spacing: normal;
  color: var(--color-text, inherit);
  background: var(--color-surface, #fff);
  border: 1px solid var(--color-accent-300);
  border-radius: 3px;
}

/* Le panneau, pose sous le bouton. **Au-dessus de tout le reste** : la table qui suit porte ses
   propres fonds, et un panneau glisse dessous se lirait a moitie. */
/* **Les trois premieres colonnes ouvrent leur filtre vers la droite** (Antoine, 2026-09-23) : ouvert
   vers la gauche, il sortait de la table, qui defile, et ce qui depassait a gauche etait coupe sans
   defilement possible. */
th:nth-child(-n+3) .classeur__filtre-panneau {
  right: auto;
  left: 0;
}

.classeur__filtre-panneau {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 15rem;
  padding: 10px;
  background: var(--color-surface, #fff);
  color: var(--color-text, inherit);
  border: 1px solid var(--color-divider);
  border-radius: 4px;
  box-shadow: 0 6px 18px rgb(0 0 0 / 18%);
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  cursor: auto;
}

/* **Le champ du filtre a son propre dessin** (Antoine, 2026-10-01 : « blanche avec des ombres et
   pas centrée ») : sans lui, le navigateur posait son champ par défaut, bord en creux et fond
   blanc, et sa largeur comptée hors bordure le faisait déborder à droite du menu. */
.classeur__filtre-valeur {
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  height: 30px;
  padding: 0 8px;
  border: 1px solid var(--color-divider);
  border-radius: 4px;
  background: var(--color-bg);
  box-shadow: none;
  appearance: none;
  color: var(--color-text);
  font: 400 var(--taille-etiquette)/1 var(--font-body);
}

.classeur__filtre-valeur:focus {
  outline: 2px solid var(--color-accent);
  outline-offset: -1px;
  background: var(--color-surface, #fff);
}

/* Ce que le menu d'une colonne a liste dit quand il n'a pas pu lire le code couleur. */
.classeur__filtre-note {
  color: var(--color-text-muted, inherit);
  font-size: var(--taille-etiquette);
  line-height: 1.4;
}

/* --- L'ecran des nouveautes -------------------------------------------------------------------

   Une liste, et rien d'autre. L'ecran dit ce que chaque version a apporte : il n'a pas de geste,
   pas de formulaire, et sa seule exigence de mise en page est qu'on distingue une version de la
   suivante sans avoir a lire les numeros. */
.nouveautes {
  display: flex;
  flex-direction: column;
  gap: 22px;
  max-width: 78ch;
}

/* Le filet separe deux versions. Au-dessus et non en dessous : la derniere version de la liste
   n'en porte pas, et c'est la plus ancienne, celle qu'on ne lit pas. */
.nouveautes__version + .nouveautes__version {
  border-top: 1px solid var(--color-divider);
  padding-top: 18px;
}

.nouveautes__titre {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 10px;
}

.nouveautes__numero {
  font: 800 var(--taille-bloc)/1.1 var(--font-heading);
  letter-spacing: -.02em;
}

.nouveautes__date {
  font: 500 var(--taille-texte)/1.4 var(--font-body);
  color: var(--color-neutral-700);
}

.nouveautes__liste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Une puce ronde devant chaque ligne ; grise pour une correction, qui suit les nouveautes. */
.nouveautes__ligne {
  position: relative;
  padding-left: 16px;
  font: 500 var(--taille-texte)/1.5 var(--font-body);
  color: var(--color-text);
}

.nouveautes__ligne::before {
  content: "";
  position: absolute;
  left: 2px;
  top: .6em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--color-accent-500);
}

.nouveautes__ligne--correction {
  color: var(--color-neutral-700);
}

.nouveautes__ligne--correction::before {
  background: var(--color-neutral-500);
}

/* --- Le pinceau des îlots d'exploitation ---------------------------------------------------

   **Deux colonnes, la carte large et le panneau étroit.** Le geste est un aller-retour entre les
   deux : on choisit un nom à droite, on clique un îlot à gauche. Les éloigner davantage ferait
   parcourir l'écran à chaque lien, et l'outil sert à en poser des dizaines de suite. */

.pinceau {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.pinceau__entete {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-end;
  gap: 12px;
}

.pinceau__titre {
  font: 700 var(--taille-titre)/1.3 var(--font-body);
  color: var(--color-text);
  margin: 0;
}

.pinceau__sous-titre,
.pinceau__note {
  font: 500 var(--taille-texte)/1.5 var(--font-body);
  color: var(--color-text-muted);
  margin: 4px 0 0;
}

.pinceau__compteurs {
  display: flex;
  gap: 16px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.pinceau__compteur {
  font: 500 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-text-muted);
  text-align: center;
}

.pinceau__nombre {
  display: block;
  font: 700 var(--taille-titre)/1.1 var(--font-body);
  color: var(--color-text);
}

/* **La pastille jaune du titre, et ce qu'elle porte au survol** (Antoine, 2026-09-16). La bulle
   s'ouvre au survol comme au focus clavier : sans le second, elle resterait muette sans souris.
   Aucun script : la politique de securite du frontal les interdit dans la page, et le CSS suffit. */
.pinceau__alerte {
  position: relative;
  display: inline-block;
  margin-left: 8px;
  vertical-align: middle;
  cursor: help;
}

.pinceau__alerte-pastille {
  display: block;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--ef-sun);
}

.pinceau__alerte-bulle {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 1000;
  width: max-content;
  max-width: 420px;
  padding: 8px 10px;
  background: var(--warn-bg);
  color: var(--warn-ink);
  border: 1px solid var(--color-divider);
  border-radius: 6px;
  font: 500 var(--taille-texte)/1.5 var(--font-body);
}

.pinceau__alerte:hover .pinceau__alerte-bulle,
.pinceau__alerte:focus .pinceau__alerte-bulle {
  display: block;
}

.pinceau__alerte-ligne {
  display: block;
}

/* L'apercu de la pose des ilots : les memes pieces que le pinceau, en colonne. */
.pose {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.pose__refus {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pose__comptes,
.pose__liste-des-refus {
  list-style: none;
  margin: 0;
  padding: 0;
}

.pose__compte {
  font: 500 var(--taille-texte)/1.8 var(--font-body);
  color: var(--color-text-muted);
}

.pose__compte .pinceau__nombre {
  display: inline-block;
  min-width: 3ch;
  font-size: var(--taille-ecran);
  text-align: right;
}

.pose__defilement {
  max-width: 100%;
  overflow-x: auto;
}

/* La carte prend ce qui reste ; le panneau garde sa largeur quoi qu'il arrive. Une liste de noms
   qui rétrécit devient illisible bien avant que la carte ne gêne. */
.pinceau__corps {
  display: grid;
  grid-template-columns: 1fr 268px;
  gap: 14px;
  align-items: stretch;
  min-height: 560px;
}

.pinceau__carte {
  min-height: 560px;
  border: 1px solid var(--color-divider);
  border-radius: 6px;
  background: var(--color-surface);
}

.pinceau__panneau {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--color-divider);
  border-radius: 6px;
  background: var(--color-neutral-100);
  overflow-y: auto;
  max-height: 640px;
}

.pinceau__charge {
  font: 500 var(--taille-texte)/1.5 var(--font-body);
  color: var(--color-text);
  margin: 0;
}

.pinceau__etiquette {
  display: block;
  font: 600 var(--taille-etiquette)/1.6 var(--font-body);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--color-neutral-700);
}

.pinceau__champ {
  width: 100%;
  padding: 6px 8px;
  font: 500 var(--taille-texte)/1.4 var(--font-body);
  color: var(--color-text);
  background: var(--color-neutral-100);
  border: 1px solid var(--color-neutral-400);
  border-radius: 5px;
}

.pinceau__trouvailles,
.pinceau__valeurs {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.pinceau__trouvaille,
.pinceau__valeur {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 5px 7px;
  font: 500 var(--taille-texte)/1.4 var(--font-body);
  color: var(--color-text);
  text-align: left;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 5px;
  cursor: pointer;
}

.pinceau__trouvaille:hover,
.pinceau__valeur:hover {
  background: var(--color-neutral-200);
}

/* **Le choix se voit au trait, pas à la couleur de fond** : la pastille porte déjà la couleur de
   l'exploitant, et teinter la ligne rendrait les deux indiscernables. */
.pinceau__valeur--choisie {
  border-color: var(--color-accent);
  background: var(--color-accent-100);
}

.pinceau__valeur:disabled {
  color: var(--color-text-muted);
  cursor: default;
}

/* **Une case gris clair derrière chaque pastille** (Antoine, 2026-09-16). Deux lignes de la
   liste n'ont pas de couleur : « sans exploitant » est un carré blanc, « pas d'information » n'a
   aucun remplissage. Sur le panneau blanc, les deux se lisaient comme une absence, et la barre
   semblait n'afficher aucune couleur. Le halo ne change la teinte d'aucune pastille : il met un
   fond derrière elles toutes, si bien qu'un carré blanc se voit comme du blanc. */
.pinceau__pastille {
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
  border: 1px solid var(--color-neutral-600);
  border-radius: 3px;
  background: var(--color-neutral-200);
  box-shadow: 0 0 0 3px var(--color-neutral-200);
}

.pinceau__nom {
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pinceau__compte {
  flex: 0 0 auto;
  font: 600 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-text-muted);
}

.pinceau__refus,
.pinceau__echec {
  padding: 10px 12px;
  font: 500 var(--taille-texte)/1.5 var(--font-body);
  color: var(--refus-ink);
  background: var(--refus-bg);
  border: 1px solid var(--refus-bord);
  border-radius: 6px;
}

@media (max-width: 900px) {
  .pinceau__corps {
    grid-template-columns: 1fr;
  }
}

.pinceau__gestes {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pinceau__recherche {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pinceau__lien {
  color: var(--color-accent);
  text-decoration: underline;
}

/* **`display: flex` bat le `[hidden]` du navigateur**, comme pour le menu de la carte : sans
   cette règle, la liste des personnes trouvées resterait déroulée alors que le script vient de
   la masquer. */
.pinceau__trouvailles[hidden] {
  display: none;
}

/* « Ce qui va changer », sur la page d'enregistrement (2026-09-17) : une table sobre, bornée en
   hauteur, pour que deux cents cases ne repoussent pas les deux gestes hors de l'écran. */
.enregistrement__changements {
  margin: 16px 0;
}

.enregistrement__cases {
  display: block;
  max-height: 320px;
  overflow: auto;
  border-collapse: collapse;
  font: 400 var(--taille-etiquette)/1.4 var(--font-body);
}

.enregistrement__cases th,
.enregistrement__cases td {
  padding: 4px 8px;
  border-bottom: 1px solid var(--color-accent-200);
  text-align: left;
  vertical-align: top;
}

.enregistrement__cases th {
  position: sticky;
  top: 0;
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-weight: 600;
}


/* **La couche du dessus d'un fond compose** (Antoine, « un fond mixte ») : le plan de l'IGN pose
   sur la photographie aerienne. `multiply` efface son papier blanc et ne laisse que ses traits et
   ses noms ; sans lui, le plan cacherait entierement le terrain. La saturation retombe pour que
   ses aplats de couleur ne repeignent pas la photographie. */
/* L'ecran « Editer un rapport d'avancement » (2026-09-18). **Meme charpente que les fiches de
   contact** : des blocs encadres, un formulaire, un bouton. Ce qui change est ce qu'il demande —
   deux bornes de periode et trois cases, la ou les fiches demandent un decoupage et des entites. */
.rapport {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-width: 1100px;
}

.rapport__bloc {
  display: flex;
  flex-direction: column;
  gap: 12px;
  border: 2px solid var(--color-text);
  padding: 16px;
  min-width: 0;
}

.rapport__formulaire {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.rapport__titre {
  margin: 0;
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  letter-spacing: .16em;
  text-transform: uppercase;
}

.rapport__sous-titre-de-bloc {
  margin: 0;
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  letter-spacing: .16em;
  text-transform: uppercase;
}

.rapport__sous-titre {
  margin: 0;
  font: 500 var(--taille-etiquette)/1.3 var(--font-body);
  opacity: .8;
}

.rapport__note {
  margin: 0;
  font: 500 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-text-muted);
}

/* Les deux bornes cote a cote, et qui passent l'une sous l'autre quand la place manque. */
.rapport__bornes {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
}

.rapport__champ {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.rapport__libelle {
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  letter-spacing: .08em;
  text-transform: uppercase;
}

/* Les trois cases. **En colonne** : elles sont trois, et leurs libelles sont des phrases. */
.rapport__sections {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.rapport__section {
  display: flex;
  align-items: center;
  gap: 8px;
  font: 500 var(--taille-etiquette)/1.3 var(--font-body);
  min-width: 0;
}

.rapport__avertissements {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.rapport__actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

/* Meme garde pour un bouton masque : la classe des boutons pose un affichage en ligne, qui bat
   l'attribut. Le bouton « Supprimer » du panneau des dessins est le premier a le porter. */
.btn[hidden] {
  display: none;
}

/* --- Le panneau de saisie d'un dessin (Antoine, 2026-09-16) -------------------------------------

   **A gauche, la ou la legende n'est pas.** Les deux peuvent etre ouverts en meme temps : on
   ecrit la note d'un dessin en lisant la legende de la couche qu'on annote. */
/* **`hidden` seul ne suffit pas contre `display: flex`** : sans cette regle, le panneau reste
   pose sur la carte en permanence, alors que la page le declare masque. */
.carte__dessin[hidden] {
  display: none;
}

/* **L'epingle d'un point dessine.** Le pictogramme est fabrique par le script, qui seul connait
   la couleur des dessins ; la feuille ne pose que le bloc. Sans `display: block`, la ligne de base
   du SVG ajoute quelques pixels sous l'image et la pointe ne designe plus le point clique. */
.carte__epingle {
  background: none;
  border: 0;
}

.carte__epingle svg {
  display: block;
}

/* Le repere d'une photo de terrain (Antoine, 2026-09-30). Notre classe seule, comme l'epingle :
   celle de la bibliotheque poserait un carre blanc borde derriere. */
.carte__photo {
  background: none;
  border: 0;
}

.carte__photo svg {
  display: block;
}

/* Le nom, en blanc cerne de noir, sous le disque. Blanc et noir quel que soit le theme : il se
   lit sur la photographie aerienne, pas sur la page. */
.carte__photo-nom {
  position: absolute;
  top: 64px;
  left: 50%;
  transform: translateX(-50%);
  color: #fff;
  font: 700 var(--taille-etiquette) var(--font-body);
  text-shadow:
    -1px -1px 0 #000, 0 -1px 0 #000, 1px -1px 0 #000,
    -1px 0 0 #000, 1px 0 0 #000,
    -1px 1px 0 #000, 0 1px 0 #000, 1px 1px 0 #000;
  white-space: nowrap;
}

.carte--sans-noms-de-photo .carte__photo-nom {
  display: none;
}

.carte__dessin {
  position: absolute;
  left: 12px;
  /* Meme hauteur que la legende, et pour la meme raison : la mention de source de la bibliotheque
     occupe le bas du cadre et ne se recouvre pas. */
  bottom: 28px;
  /* **Au-dessus des reperes** (fond de plan et echelle, z-index 1000 depuis le 2026-09-25) : ils
     occupent le meme coin, et leur liste des fonds couvrait le bouton « Enregistrer ». */
  z-index: 1001;
  /* **Le cadre de la legende** (Antoine, 2026-10-04 : « a soigner ») : blanc, arrondi, filet fin
     et sans ombre, comme l'encart qu'il cotoie. */
  width: 280px;
  max-width: calc(100% - 24px);
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 4px 12px 12px;
  background: var(--crm-blanc);
  border: 1px solid var(--color-divider);
  border-radius: var(--rayon-cadre);
}

/* L'en-tete : le titre du bloc, et la croix au bout, comme celle de la legende. */
.carte__dessin-tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-right: -8px;
}

.carte__dessin-titre {
  margin: 0;
  font: 600 var(--taille-bloc)/1.3 var(--font-body);
  color: var(--color-text);
}

.carte__dessin-champ {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-text-muted);
}

.carte__dessin-champ input,
.carte__dessin-champ textarea {
  box-sizing: border-box;
  width: 100%;
  font: 400 var(--taille-texte)/1.4 var(--font-body);
  padding: 6px 8px;
  border: 1px solid var(--color-divider);
  border-radius: var(--rayon-bouton);
  background: var(--crm-blanc);
  color: var(--color-text);
  /* Sans cela, la zone de note se redimensionne en largeur et deborde du panneau. */
  resize: vertical;
}

.carte__dessin-champ input:focus-visible,
.carte__dessin-champ textarea:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: -1px;
}

/* **Le refus s'ecrit dans le panneau**, jamais dans une boite du navigateur : une alerte bloque
   la page et fait perdre le trace qu'on vient de faire. */
.carte__dessin-refus {
  margin: 0;
  font: 400 var(--taille-texte)/1.35 var(--font-body);
  color: var(--etat-bloque);
}

.carte__dessin-commandes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

/* Le retrait ne se confond pas avec l'abandon : il est rouge (`.btn-danger`) et se tient au bout
   de la rangee, loin d'« Enregistrer ». */
.carte__dessin-retirer {
  margin-left: auto;
}

/* --- La zone tampon ---------------------------------------------------------------------------

   **L'opacite se regle sur le calque entier, et c'est ce qui fait la bande.** Les pieces qui la
   composent se recouvrent ; posee sur chaque piece, l'opacite assombrirait chaque recouvrement et
   dessinerait la mecanique au lieu du resultat. */
.leaflet-tampon-pane {
  opacity: 0.35;
  /* Au-dessus des couches, sous les marqueurs : la bande se voit sans cacher un reperage. */
  z-index: 450;
  pointer-events: none;
}

.carte__tampon-piece {
  fill: var(--color-primary, #1c7ed6);
}

.carte__tampon-champ {
  display: flex;
  align-items: center;
  gap: 6px;
  font: 400 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-neutral-700);
}

.carte__tampon-champ input {
  width: 72px;
  font: 400 var(--taille-etiquette)/1.4 var(--font-body);
  padding: 2px 6px;
}

/* --- La loupe de la barre du haut de la carte (Antoine, 2026-09-23) ---------------------------
   Un `details` : il s'ouvre et se ferme sans script. Le panneau se pose sous la loupe, au-dessus
   de la carte, et garde sa largeur quelle que soit la longueur des résultats. */
.carte__recherche {
  position: relative;
  flex: none;
}

.carte__recherche-loupe {
  list-style: none;
  cursor: pointer;
}

.carte__icone-loupe {
  width: 13px;
  height: 13px;
  flex: none;
}

.carte__recherche-loupe::-webkit-details-marker {
  display: none;
}

.carte__recherche[open] > .carte__recherche-panneau,
.carte__recherche[open] > .carte__recherche-resultats {
  position: absolute;
  left: 0;
  z-index: 1000;
  box-sizing: border-box;
  width: min(320px, calc(100vw - 32px));
  background: var(--color-bg);
  border: 1px solid var(--color-divider);
}

.carte__recherche[open] > .carte__recherche-panneau {
  top: calc(100% + 4px);
  padding: 6px;
}

.carte__recherche[open] > .carte__recherche-resultats {
  top: calc(100% + 42px);
  max-height: 50vh;
  overflow-y: auto;
}

.carte__recherche-resultats:empty {
  display: none;
}

.carte__recherche-champ {
  width: 100%;
  box-sizing: border-box;
  font: 400 var(--taille-etiquette)/1.3 var(--font-body);
  padding: 4px 6px;
}

.carte__recherche-liste {
  list-style: none;
  margin: 0;
  padding: 4px 0;
}

.carte__recherche-lien {
  display: block;
  padding: 4px 8px;
  font: 400 var(--taille-etiquette)/1.3 var(--font-body);
  color: inherit;
  text-decoration: none;
}

.carte__recherche-lien:hover,
.carte__recherche-lien:focus {
  background: color-mix(in srgb, var(--ef-sun) 25%, transparent);
}

.carte__recherche-phrase {
  margin: 0;
  padding: 6px 8px;
  font: 400 var(--taille-etiquette)/1.3 var(--font-body);
}

/* La fiche au survol d'une parcelle du cadastre national : libelle a gauche, valeur a droite. */
.carte__fiche-du-cadastre.leaflet-tooltip {
  padding: 6px 10px;
  font: 400 var(--taille-etiquette)/1.5 var(--font-body);
}

.carte__fiche-du-cadastre dl {
  display: grid;
  grid-template-columns: auto auto;
  gap: 0 10px;
  margin: 0;
}

.carte__fiche-du-cadastre dt {
  color: var(--color-text-muted);
}

.carte__fiche-du-cadastre dd {
  margin: 0;
  font-weight: 600;
}

/* **Le mode « Cadastre national »** (lot 5, 2026-09-24). Sa barre passe a la ligne plutot que de
   couper ses phrases, et son bilan prend toute la largeur sous les commandes.

   **Les couleurs du cadastre vivent ici, et le code de la carte les lit** : la bibliotheque dessine
   dans un canevas, que la feuille ne peut pas peindre elle-meme. Le trait d'une parcelle, et le
   trait et le fond d'une parcelle choisie — les memes que la selection des parcelles du projet. */
.carte__cadastre {
  --cadastre-trait: #b25b1e;
  --cadastre-trait-choisi: var(--color-accent-500);
  --cadastre-fond-choisi: var(--color-accent-300);
  --cadastre-etiquette: #7a3d12;
  --cadastre-halo: #ffffff;
  flex-wrap: wrap;
  row-gap: 4px;
}

.carte__cadastre-compte {
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-neutral-700);
}

.carte__cadastre-bilan {
  flex-basis: 100%;
  font: 400 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-neutral-700);
}

.carte__cadastre-bilan:empty {
  display: none;
}

/* Les références collées : sous les boutons, sur toute la largeur de la barre. */
.carte__cadastre-collage {
  flex-basis: 100%;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* Repliee sous « Coller des references » : `display: flex` l'emportait sur `hidden`. */
.carte__cadastre-collage[hidden] {
  display: none;
}

.carte__cadastre-collage textarea {
  max-width: 40ch;
  resize: vertical;
}

.carte__cadastre-collage output {
  font: 400 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-neutral-700);
}

.carte__cadastre-collage output:empty {
  display: none;
}

.carte__cadastre-phrase {
  margin: 0;
}

.carte__cadastre-refus {
  margin: 2px 0 0;
  padding-left: 16px;
}

/* **L'echec d'une ecriture de case, dit dans la case** (Antoine, 2026-09-24). Petit et rouge, sous
   le champ : la case reste ouverte avec la valeur tapee, et quitter la case la retente. */
.classeur-case__echec {
  margin: 2px 0 0;
  font: 500 var(--taille-etiquette)/1.3 var(--font-body);
  color: var(--color-danger-600, #b3261e);
}

/* **Le tri d'une colonne du FGF** (Antoine, 2026-09-23). La fleche suit le nom de la colonne ;
   les boutons se rangent sous le filtre, sur une ligne, le sens en cours enfonce. */
.classeur__signe-du-tri {
  margin-left: 4px;
  font-weight: 700;
}

.classeur__tri {
  display: flex;
  align-items: center;
  gap: 4px;
  margin: 0;
  padding: 8px;
  border-bottom: 1px solid var(--color-divider);
}

.classeur__tri-bouton {
  flex: 1;
  white-space: nowrap;
}

.classeur__tri-bouton[aria-pressed="true"] {
  background: var(--color-accent, #2e7d32);
  border-color: var(--color-accent, #2e7d32);
  color: #fff;
}

/* **Le filtre eteint d'une colonne calculee** : le meme bouton, sans reaction, et sa raison au
   survol. */
.classeur__filtre-bouton--eteint {
  cursor: help;
  opacity: 0.35;
}

.classeur__filtre-bouton--eteint:hover {
  background: none;
  opacity: 0.35;
}


/* ==== Ecran FGF : la barre, la recherche, la ligne des filtres (maquette du 2026-09-25) ====
   **Aucun texte sous 12 pixels** : c'est la regle 16 du dossier `docs/refonte_ui`, et ces regles
   sont les premieres ecrites apres elle. */

/* Defaire et refaire un pas : deux formulaires qui ne sont que leur bouton. */
.classeur-barre__pas-groupe {
  display: inline-flex;
  gap: 4px;
}

.classeur-barre__pas {
  display: inline-flex;
  margin: 0;
}

/* La recherche dans l'onglet : un champ avec sa loupe, qui retrecit avant de passer a la ligne. */
.classeur-barre__recherche {
  flex: 0 1 280px;
  min-width: 140px;
  margin: 0;
}

.classeur-barre__recherche-cadre {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 8px;
  border: 1px solid var(--color-divider);
  background: var(--color-bg);
  color: var(--color-text-muted);
}

.classeur-barre__recherche-cadre:focus-within {
  border-color: var(--color-accent-500);
}

.classeur-barre__recherche-loupe {
  width: 14px;
  height: 14px;
  flex: none;
}

.classeur-barre__recherche-champ {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: none;
  padding: 6px 0;
  background: transparent;
  color: var(--color-text);
  font: 400 var(--taille-etiquette)/1.2 var(--font-body);
}

/* Le trait qui separe ce qu'on regarde de ce qui regle l'affichage et sort de l'ecran. */
.classeur-barre__trait {
  width: 1px;
  height: 20px;
  flex: none;
  background: var(--color-divider);
}

/* Un bouton qui n'est qu'une icone : son nom est porte par `aria-label` et son infobulle. */
.bouton-icone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  padding: 5px 7px;
}

.bouton-icone__dessin {
  width: 16px;
  height: 16px;
}

/* La bascule des textes longs : la case reste atteignable au clavier, invisible a l'oeil, et
   l'etiquette dessine le bouton. Cochee, le bouton prend la couleur d'un bouton enfonce. */
.classeur-barre__affichage-etiquette.bouton-icone {
  position: relative;
  border: 1px solid var(--color-divider);
  background: var(--color-surface);
  color: var(--color-text);
  cursor: pointer;
}

.classeur-barre__affichage-etiquette .classeur-barre__affichage {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.classeur-barre__affichage-etiquette:has(.classeur-barre__affichage:checked) {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: #f3f2f2;
}

.classeur-barre__affichage-etiquette:has(.classeur-barre__affichage:focus-visible) {
  outline: 2px solid var(--color-accent-500);
  outline-offset: 2px;
}

/* L'entonnoir d'un onglet qui porte un filtre retenu. */
.classeur__onglet-filtre {
  display: inline-flex;
  align-items: center;
  margin-left: 4px;
  vertical-align: -2px;
}

.classeur__onglet-entonnoir {
  width: 12px;
  height: 12px;
}

/* La ligne des filtres : elle n'existe que si un filtre est pose. Le jaune dit « vous ne voyez
   pas tout », et seulement cela. Une ligne, jamais deux : les puces defilent sur le cote. */
.classeur-filtres {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  padding: 6px 20px;
  background: var(--warn-bg);
  color: var(--warn-ink);
  border-bottom: 1px solid color-mix(in srgb, var(--warn-ink) 25%, transparent);
  font: 400 var(--taille-etiquette)/1.3 var(--font-body);
  white-space: nowrap;
}

.classeur-filtres__titre {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-weight: 800;
  flex: none;
}

.classeur-filtres__entonnoir {
  width: 13px;
  height: 13px;
}

.classeur-filtres__puces {
  display: flex;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
  min-width: 0;
  overflow-x: auto;
}

.classeur-filtres__puce {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: none;
  padding: 2px 4px 2px 8px;
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px solid color-mix(in srgb, var(--warn-ink) 35%, transparent);
}

.classeur-filtres__nom {
  font-weight: 700;
}

.classeur-filtres__retrait {
  display: inline-flex;
  padding: 1px;
  color: var(--color-neutral-700);
}

.classeur-filtres__retrait:hover {
  color: var(--color-text);
}

.classeur-filtres__croix {
  width: 13px;
  height: 13px;
}

.classeur-filtres__tout {
  flex: none;
  color: var(--color-accent-500);
  font-weight: 600;
}

.classeur-filtres__compte {
  margin-left: auto;
  flex: none;
  font-variant-numeric: tabular-nums;
}

/* ==== Ecran FGF : le menu d'une colonne (maquette du 2026-09-25) ====
   Le cadre pose sous l'en-tete porte deux formulaires : trier et filtrer, puis masquer. Les regles
   d'avant visaient le formulaire lui-meme ; elles le laissent a sa place, dans le cadre. */
.classeur__menu-de-colonne {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  width: 16rem;
  background: var(--color-surface, #fff);
  color: var(--color-text, inherit);
  border: 1px solid var(--color-divider);
  border-radius: 4px;
  box-shadow: 0 6px 18px rgb(0 0 0 / 18%);
  font: 400 var(--taille-etiquette)/1.35 var(--font-body);
  text-transform: none;
  letter-spacing: normal;
  cursor: auto;
}

/* Les trois premieres colonnes ouvrent leur menu vers la droite (2026-09-28) : ouvert vers la
   gauche, il sortait du tableau et le cadre le coupait. Trois, comme le filtre du 2026-09-23 :
   des premieres colonnes etroites laissent la troisieme pres du bord. */
th:nth-child(-n+3) .classeur__menu-de-colonne {
  right: auto;
  left: 0;
}

/* Au-dela, le script mesure (signalement 10, 2026-09-30) : une colonne etroite amenee pres du
   bord gauche par le defilement du cadre ouvre son menu vers la droite. */
.classeur__menu-de-colonne--droite {
  right: auto;
  left: 0;
}

.classeur__menu-de-colonne .classeur__filtre-panneau {
  position: static;
  width: auto;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: none;
}

/* **Le menu epure** (maquette du 2026-10-01) : le panneau du filtre n'a plus que son champ, ou
   les valeurs d'une liste. */
.classeur__menu-de-colonne .classeur__filtre-panneau {
  padding: 8px;
}

/* **L'entonnoir barre qui efface le filtre**, au bout de la rangee du tri (Antoine, 2026-10-01) :
   l'entonnoir dans la couleur du filtre, une petite croix rouge sur sa partie basse a gauche. Au
   tableau carto, son formulaire est a part : il se pose dans la rangee par sa position. */
.classeur__effacement {
  position: absolute;
  top: 8px;
  right: 8px;
  margin: 0;
}

.classeur__menu-de-colonne:has(> .classeur__effacement) > .classeur__tri {
  padding-right: 46px;
}

.classeur__effacement-du-filtre {
  position: relative;
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 30px;
  padding: 0;
  border: 1px solid var(--color-divider);
  border-radius: 4px;
  background: var(--color-surface, #fff);
  color: var(--color-accent);
  cursor: pointer;
}

.classeur__effacement-du-filtre:hover,
.classeur__effacement-du-filtre:focus-visible {
  background: var(--color-accent-100);
}

.classeur__effacement-entonnoir {
  width: 18px;
  height: 18px;
}

.classeur__effacement-croix {
  position: absolute;
  left: 5px;
  bottom: 4px;
  width: 10px;
  height: 10px;
  padding: 1px;
  border-radius: 50%;
  background: var(--color-surface, #fff);
  color: var(--color-danger-600, #b3261e);
  stroke-width: 3;
}

/* **Chaque valeur d'une liste est un bouton** : un clic filtre, la retenue porte une coche. */
.classeur__filtre-valeurs {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 15rem;
  overflow-y: auto;
}

.classeur__filtre-choix {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 28px;
  padding: 2px 6px;
  border: 0;
  border-radius: 4px;
  background: none;
  text-align: left;
  cursor: pointer;
}

.classeur__filtre-choix:hover,
.classeur__filtre-choix:focus-visible {
  background: var(--color-accent-50, var(--color-accent-100));
}

.classeur__filtre-choix[aria-pressed="true"] {
  background: var(--color-accent-100);
}

.classeur__filtre-coche {
  visibility: hidden;
  color: var(--color-accent);
  font-weight: 800;
}

.classeur__filtre-choix[aria-pressed="true"] .classeur__filtre-coche {
  visibility: visible;
}

/* **Le menu ouvert passe au-dessus de toute la table** : les en-tetes collants n'avaient pas de
   rang, et les cases positionnees apres eux (colonne figee, case a fleche) se peignaient
   par-dessus le menu. Celui de l'en-tete ouvert passe aussi devant ses voisins. */
.classeur-table .table thead th {
  z-index: 2;
}

.classeur-table .table thead th:has(> .classeur__entete > details[open]),
.donnees-table .table thead th:has(> .classeur__entete > details[open]) {
  z-index: 4;
}

.classeur__filtre-pastille {
  font-size: var(--taille-etiquette);
}

.classeur__masquage {
  margin: 0;
  padding: 6px 10px 8px;
  border-top: 1px solid var(--color-divider);
}

.classeur__masquage-bouton {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 4px 2px;
  border: 0;
  background: none;
  color: var(--color-text);
  font: 500 var(--taille-etiquette)/1.3 var(--font-body);
  text-align: left;
  cursor: pointer;
}

.classeur__masquage-bouton:hover {
  background: var(--color-accent-100);
}

.classeur__masquage-dessin {
  width: 14px;
  height: 14px;
  flex: none;
}

/* Le chevron d'un en-tete ne parait qu'au survol et au clavier : trente-neuf chevrons permanents
   faisaient une rangee de bruit. L'entonnoir d'une colonne filtree reste toujours visible, comme
   le chevron d'un menu ouvert. */
.classeur-table .table th .classeur__filtre-bouton {
  opacity: 0;
}

/* **Le menu colle au bord de sa colonne** (Antoine, 2026-10-04), au FGF comme dans l'ecran
   scinde : il mange la marge interieure de l'en-tete, a droite d'un texte, a gauche d'un nombre. */
.classeur-table .table th .classeur__entete > .classeur__filtre-colonne,
.classeur-table .table th .classeur__entete > .classeur__filtre-bouton--eteint {
  margin-right: -8px;
}

.classeur-table .table th.classeur-colonne--nombre .classeur__entete > .classeur__filtre-colonne,
.classeur-table .table th.classeur-colonne--nombre .classeur__entete > .classeur__filtre-bouton--eteint {
  margin-right: 0;
  margin-left: -8px;
}

.classeur-table .table th:hover .classeur__filtre-bouton,
.classeur-table .table th:focus-within .classeur__filtre-bouton,
.classeur__filtre-colonne[open] > .classeur__filtre-bouton,
.classeur__filtre-colonne--actif > .classeur__filtre-bouton {
  opacity: 0.85;
}

/* La barre de l'ecran ne passe plus a la ligne : le code couleur, dont le panneau s'ouvrait
   dessous, l'a quittee. A l'etroit, le champ de recherche retrecit le premier. */
.classeur > .classeur-barre {
  flex-wrap: nowrap;
  gap: 8px;
  padding: 7px 20px;
}

/* ==== Ecran FGF : le panneau des colonnes (maquette du 2026-09-25) ====
   Pose sur le bord droit de la fenetre, sous la barre du projet, comme le reservoir des couches de
   la carte : la liste d'une trentaine de colonnes defile chez elle, les gestes restent au pied. */
.classeur-barre__bascule.bouton-icone {
  gap: 6px;
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
  color: var(--color-text);
  text-decoration: none;
}

.classeur-barre__bascule-compte {
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--color-neutral-700);
}

@media (max-width: 1399px) {
  .classeur-barre__bascule-libelle {
    display: none;
  }
}

.classeur-colonnes {
  position: fixed;
  top: var(--hauteur-de-la-barre, 52px);
  right: 0;
  bottom: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  width: min(340px, 100vw);
  background: var(--color-bg);
  border-left: 2px solid var(--color-accent);
  box-shadow: -8px 0 24px rgb(0 0 0 / 14%);
  font: 400 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-text);
  cursor: auto;
}

.classeur-colonnes__tete {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  padding: 10px 12px;
  background: var(--color-accent);
  color: #f3f2f2;
}

.classeur-colonnes__titre {
  flex: 1;
  font: 800 var(--taille-etiquette)/1.2 var(--font-body);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.classeur-colonnes__fermer {
  display: inline-flex;
  padding: 2px;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}

.classeur-colonnes__croix {
  width: 16px;
  height: 16px;
}

.classeur-colonnes__chercher {
  flex: none;
  padding: 9px 12px;
  border-bottom: 1px solid var(--color-neutral-300);
}

.classeur-colonnes__recherche {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--color-divider);
  background: var(--color-surface);
  color: var(--color-text);
  font: 400 var(--taille-etiquette)/1.2 var(--font-body);
}

/* Le formulaire prend la hauteur qui reste ; son corps defile, ses boutons restent au pied. */
.classeur-colonnes .classeur-barre__colonnes-formulaire {
  position: static;
  flex: 1 1 auto;
  min-height: 0;
  max-height: none;
  padding: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: none;
}

.classeur-colonnes__corps {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 4px 12px 8px;
}

.classeur-colonnes .classeur-barre__colonnes-liste {
  overflow: visible;
  margin: 0 0 6px;
  font-size: var(--taille-etiquette);
  color: var(--color-text);
}

/* Glisser le long des cases et Maj + clic ne sélectionnent pas le texte des libellés. */
.classeur-colonnes__ligne > label {
  padding: 3px 4px;
  user-select: none;
}

.classeur-colonnes__ligne > label:hover {
  background: var(--color-accent-100);
}

.classeur-colonnes__section {
  display: flex;
  align-items: baseline;
  margin: 10px 0 4px;
  font: 800 var(--taille-etiquette)/1.2 var(--font-body);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-neutral-800);
}

.classeur-colonnes__compte {
  margin-left: auto;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--color-text-muted);
}

.classeur-colonnes .classeur-barre__colonnes-appliquer {
  flex-wrap: wrap;
  padding: 10px 12px;
  border-top: 1px solid var(--color-neutral-300);
  background: var(--color-surface);
}

.classeur-colonnes .classeur-barre__colonnes-note {
  font-size: var(--taille-etiquette);
}

/* « Ajouter une colonne », au pied du panneau : le champ s'ouvre sous son bouton, dans le flux. */
.classeur-colonnes .classeur__ajout {
  display: block;
  flex: none;
  padding: 0 12px 10px;
  background: var(--color-surface);
}

.classeur-colonnes .classeur__ajout-bouton {
  width: auto;
  height: auto;
  padding: 7px 12px;
  opacity: 1;
}

.classeur-colonnes .classeur__ajout-panneau {
  position: static;
  margin-top: 8px;
  box-shadow: none;
}

.classeur-colonnes .classeur__ajout-libelle {
  font-size: var(--taille-etiquette);
}

/* --- La premiere colonne figee et la fiche a cote du tableau (maquette FGF du 2026-09-25) ------ */

/* **La premiere colonne reste en place quand on defile vers la droite**, comme « Figer les volets »
   dans Excel : on sait toujours sur quelle ligne on ecrit. Elle porte un fond, sans quoi les cases
   passeraient a travers, et un filet a droite. L'en-tete colle deja en haut (`.table th`). */
.classeur-table .table tbody td:first-child,
.classeur-table .table thead th:first-child {
  position: sticky;
  left: 0;
  box-shadow: inset -1px 0 0 var(--color-neutral-400);
}

.classeur-table .table tbody td:first-child {
  z-index: 1;
  background: var(--color-bg);
}

.classeur-table .table thead th:first-child {
  z-index: 3;
}

/* L'identifiant d'une ligne qui a une fiche : un lien, souligne au survol. */
.classeur-case__identifiant {
  color: var(--color-accent);
  font-weight: 600;
  text-decoration: none;
}

.classeur-case__identifiant:hover,
.classeur-case__identifiant:focus-visible {
  text-decoration: underline;
}

/* **La fleche d'une case qui designe une entite** ne parait qu'au survol de la case et au
   clavier : cent lignes de fleches permanentes chargeraient le tableau.

   **Posee par-dessus la case, hors du flux** (Antoine, 2026-09-25, « la hauteur de ligne est
   grande ») : en ligne apres un texte pose en bloc, elle ouvrait une ligne a elle seule et
   ajoutait 18 px a chaque ligne du tableau, meme invisible. La case figee est deja positionnee
   (`sticky`) ; les autres le deviennent ici, sans toucher a celle-la. */
.classeur-case:has(> .classeur-case__fiche):not(:first-child) {
  position: relative;
}

.classeur-case__fiche {
  position: absolute;
  top: 6px;
  right: 4px;
  padding: 1px 4px;
  background: var(--color-bg);
  font: 700 var(--taille-etiquette)/1 var(--font-body);
  color: var(--color-accent);
  text-decoration: none;
  opacity: 0;
}

.classeur-case:hover .classeur-case__fiche,
.classeur-case__fiche:focus-visible {
  opacity: 1;
}

/* Le panneau de la fiche, pose a droite comme celui des colonnes. Vide, il n'occupe rien. */
.classeur-fiche:empty {
  display: none;
}

/* Sur la carte, au-dessus des calques de Leaflet, comme la loupe. */
.carte__fiche-laterale .classeur-fiche__cadre {
  z-index: 1000;
}

.classeur-fiche__cadre {
  position: fixed;
  top: var(--hauteur-de-la-barre, 52px);
  right: 0;
  bottom: 0;
  z-index: 55;
  display: flex;
  flex-direction: column;
  width: min(360px, 100vw);
  background: var(--color-bg);
  border-left: 2px solid var(--color-accent);
  box-shadow: -8px 0 24px rgb(0 0 0 / 14%);
  font: 400 var(--taille-etiquette)/1.4 var(--font-body);
  color: var(--color-text);
}

.classeur-fiche__tete {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: none;
  padding: 10px 12px;
  background: var(--color-accent);
  color: #f3f2f2;
}

.classeur-fiche__titre {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
  font: 800 var(--taille-ecran)/1.2 var(--font-body);
}

/* Meme cible que la croix de fermeture voisine : 32 px. */
.classeur-fiche__bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 32px;
  height: 32px;
  box-sizing: border-box;
  padding: 0;
  border: 0;
  border-radius: var(--rayon-bouton);
  background: none;
  color: inherit;
  cursor: pointer;
}

.classeur-fiche__dessin {
  width: 16px;
  height: 16px;
}

.classeur-fiche__corps {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 10px 12px;
}

.classeur-fiche__faits {
  display: grid;
  gap: 6px;
  margin: 0 0 12px;
}

.classeur-fiche__fait {
  display: grid;
  grid-template-columns: 40% 1fr;
  gap: 8px;
}

.classeur-fiche__nom {
  font-weight: 700;
  color: var(--color-neutral-700);
}

.classeur-fiche__valeur {
  margin: 0;
  overflow-wrap: anywhere;
}

.classeur-fiche__valeurs,
/* **Les entites liees en petits encadres cliquables** (Antoine, 2026-09-25) : ils se parcourent
   d'un coup d'oeil et se visent sans viser un mot souligne. */
.classeur-fiche__liste {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
}

.classeur-fiche__puce {
  display: inline-block;
  max-width: 100%;
  padding: 4px 9px;
  border: 1px solid var(--color-accent-200);
  border-radius: 4px;
  background: var(--color-bg);
  color: var(--color-accent-500);
  font: 600 var(--taille-etiquette)/1.3 var(--font-body);
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

a.classeur-fiche__puce:hover,
a.classeur-fiche__puce:focus-visible {
  border-color: var(--color-accent-500);
  background: var(--color-accent-100);
}

.classeur-fiche__puce--muette {
  border-color: var(--color-divider);
  color: var(--color-neutral-700);
}

.classeur-fiche__liens {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--color-divider);
}

.classeur-fiche__groupe {
  display: flex;
  margin: 0 0 4px;
  font: 800 var(--taille-etiquette)/1.2 var(--font-body);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--color-neutral-800);
}

.classeur-fiche__compte {
  margin-left: auto;
  font-weight: 500;
  color: var(--color-text-muted);
}

.classeur-fiche__note,
.classeur-fiche__vide {
  margin: 4px 0;
  color: var(--color-text-muted);
}

.classeur-fiche__pied {
  flex: none;
  padding: 10px 12px;
  border-top: 1px solid var(--color-divider);
}

/* --- Cocher des lignes, puis agir dessus (maquette FGF du 2026-09-25) --------------------------- */

/* **La case d'une ligne parait au survol**, et reste des qu'une ligne est cochee : cent cases
   permanentes chargeraient la colonne figee. */
.classeur-coche-ligne,
.classeur-coche-toutes {
  margin: 0 6px 0 0;
  vertical-align: middle;
  cursor: pointer;
}

/* **Flottante**, pour que l'identifiant garde sa ligne a cote d'elle : le texte d'une case se plie
   en bloc, et une case en ligne le repoussait dessous. */
.classeur-coche-ligne {
  float: left;
  margin-top: 2px;
  opacity: 0;
}

.classeur-table tr:hover .classeur-coche-ligne,
.classeur-coche-ligne:focus-visible,
.classeur-table--coches .classeur-coche-ligne {
  opacity: 1;
}

.classeur-table .table tr.classeur-ligne--cochee td {
  background: var(--color-accent-100);
}

/* **Les cases visees portent le jaune avant qu'on tape**, comme dans l'ecran scinde. */
.classeur-table .table tr.classeur-ligne--visee td {
  box-shadow: inset 0 0 0 1px var(--ef-sun);
}

.classeur-coches {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
}

.classeur-coches[hidden] {
  display: none;
}

.classeur-coches__bascule {
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}

/* Le carre de la case ne se dessine pas, comme dans l'ecran scinde : la pastille qui se colorie
   dit l'etat, et la case garde sa place au clavier. */
.classeur-coches__bascule input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
}

.classeur-coches__bascule-mot {
  padding: 3px 8px;
  border: 1px solid var(--color-neutral-400);
  border-radius: 4px;
}

.classeur-coches__bascule input:focus-visible + .classeur-coches__bascule-mot {
  outline: 2px solid var(--ef-sun);
  outline-offset: 2px;
}

/* **Allumee, elle est jaune**, comme celle de l'ecran scinde : deux tableaux qui font le meme
   travail se comportent pareil. */
.classeur-coches__bascule input:checked + .classeur-coches__bascule-mot {
  background: var(--ef-sun);
  border-color: var(--ef-sun);
  color: var(--color-text);
}

.classeur-coches__compte {
  color: var(--color-text);
  white-space: nowrap;
}

.classeur-coches__carte,
.classeur-coches__edition,
.classeur-coches__decocher {
  white-space: nowrap;
}

/* --- L'ecran scinde redessine (maquette de la carte, 2026-09-25) -------------------------------- */

/* **La portee est un segment** (voir `.tiroir__lignes`) : celui qui s'applique est allume. */
.tiroir__portee {
  padding: 2px 10px;
  border: 0;
  background: transparent;
  color: inherit;
  font: var(--taille-etiquette)/1.6 var(--font-body);
  cursor: pointer;
}

/* Le compte de l'onglet ouvert : les lignes que le tiroir montre. Comme le compteur d'un onglet
   du FGF, a l'encre discrete. */
.tiroir__compte-d-onglet {
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* **Le tiroir n'a plus de pied** (Antoine, 2026-09-26) : l'ecriture multiligne est revenue dans
   la ligne des onglets. **Allumee, elle reste jaune**, comme la case ou la valeur va atterrir. */
.tiroir__barre .tiroir__bascule input:checked + .tiroir__bascule-mot {
  background: var(--ef-sun);
  border-color: var(--ef-sun);
  color: var(--color-text);
  font-weight: 600;
}

.tiroir:has(.tiroir__bascule input:checked) .classeur-case--edition {
  background: var(--ef-sun);
}

/* --- La barre du haut de la carte en deux moities (maquette de la carte, 2026-09-25) ------------ */

/* **Une seule rangee, deux moitiees.** Le fragment des barres s'efface de la mise en page
   (`display: contents`) : ses barres deviennent des elements de cette rangee, a cote du groupe
   de droite, et la barre d'un outil passe dessous, sur toute la largeur. */
.carte__haut {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-divider);
}

#carte-barres {
  display: contents;
}

.carte__haut > #carte-barres > .carte__barre--haut {
  order: 0;
  border-bottom: 0;
}

.carte__barre--droite {
  order: 1;
  flex: 1 1 auto;
  padding: 8px 14px 8px 0;
}

.carte__haut > #carte-barres > .carte__barre--mode,
.carte__haut > #carte-barres > .carte__cadastre {
  order: 2;
  flex: 1 0 100%;
  /* **Rembourrage compris dans la largeur** (Antoine, 2026-09-26) : sans lui, la barre d'un outil
     debordait de ses 28 pixels de rembourrage et recouvrait le filet gris qui la separe des
     couches. */
  box-sizing: border-box;
  min-width: 0;
}

/* Le trait qui separe le contenu de la carte de la fenetre et des sorties. */
.carte__trait {
  align-self: stretch;
  width: 1px;
  background: var(--color-divider);
}

/* **A droite du trait, l'icone seule** : l'etat se lit a la couleur du bouton, le mot au survol.
   **Taille nulle et non position absolue** : dans un bouton, Chrome compte encore un mot sorti du
   flux dans la largeur, et le bouton gardait la place du mot. Le mot reste lu par les lecteurs
   d'ecran. */
.carte__barre--droite .carte__commande:not([data-ouvrir-la-legende]) {
  gap: 0;
  /* Une commande reduite a son icone garde une cible de 32 px (chantier 2, 2026-10-02). */
  min-width: 32px;
  min-height: 32px;
  justify-content: center;
  box-sizing: border-box;
}

.carte__barre--droite .carte__commande:not([data-ouvrir-la-legende]) .carte__libelle-commande {
  font-size: 0;
  line-height: 0;
}

.carte__commande[aria-pressed="true"] {
  background: var(--color-accent);
  color: var(--color-bg);
}

/* **La palette des outils** : une icone par outil, le nom du seul outil actif. **En pilule, a la
   charte d'« Echanges »** (maquette « Carte, seconde lecture », 2026-10-03) : fond gris, l'outil
   actif en vert plein. Le segment des trois mesures prend le meme dessin. Le gris 300 et non 200 :
   sur le gris de la barre, le 200 ne se distinguait pas (captures du 2026-10-04). */
.carte__palette,
.tiroir__lignes,
.carte__segment-de-mesure {
  gap: 2px;
  padding: 3px;
  border: 0;
  border-radius: var(--rayon-pilule);
  background: var(--color-neutral-300);
}

.carte__palette .segment,
.carte__segment-de-mesure .segment,
.tiroir__lignes .tiroir__portee {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-right: 0;
  border-radius: var(--rayon-pilule);
  color: var(--color-neutral-800);
}

/* **Le nom de l'outil actif se lit aussi sous la souris.** `a:hover` pose le vert du produit sur
   le texte et l'emportait sur `.segment--actif` : l'outil qu'on venait de choisir, encore sous le
   pointeur, devenait un pave vert sans nom (defaut du 2026-10-03). */
.carte__palette .segment--actif,
.carte__palette .segment--actif:hover,
.carte__segment-de-mesure .segment[aria-pressed="true"],
.tiroir__lignes .tiroir__portee[aria-pressed="true"] {
  background: var(--bouton-principal);
  color: var(--bouton-principal-encre);
}

.carte__palette .segment:not(.segment--actif):hover,
.carte__segment-de-mesure .segment:not([aria-pressed="true"]):not([disabled]):hover,
.tiroir__lignes .tiroir__portee:not([aria-pressed="true"]):hover {
  color: var(--color-accent);
}

.carte__palette .segment:not(.segment--actif) .carte__libelle-d-outil {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.carte__libelle-d-outil {
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
}

/* « ZE » : deux lettres a la place d'une icone, a la taille d'une icone. */
.carte__monogramme {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 16px;
  height: 16px;
  font: 800 var(--taille-etiquette)/1 var(--font-body);
  letter-spacing: -.02em;
}

/* **Le fond de plan et l'echelle, deux reperes discrets en bas a gauche**, chacun dans sa propre
   pastille (Antoine, 2026-09-25) : un cadre commun disait qu'ils vont ensemble, et ils n'ont rien a
   voir l'un avec l'autre. Au-dessus des calques de la bibliotheque, qui montent a 1000. */
.carte__reperes {
  position: absolute;
  left: 8px;
  bottom: 8px;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 6px;
}

/* Arrondis à la charte d'« Échanges » (maquette « Carte, seconde lecture », 2026-10-03) :
   l'échelle en bouton, le fond de plan en pilule. */
.carte__reperes .carte__fond,
.carte__reperes .carte__echelle {
  padding: 2px 6px;
  border: 1px solid var(--color-neutral-300);
  border-radius: var(--rayon-bouton);
  background: rgb(255 255 255 / 88%);
  color: var(--color-neutral-700);
}

/* **Toute la pilule se clique** (Antoine, 2026-10-05) : le retrait est porté par la liste et non
   par la pilule, dont le bord laissait une marge où le clic tombait à côté. */
.carte__reperes .carte__fond {
  order: -1;
  padding: 0;
  border-radius: var(--rayon-pilule);
  overflow: hidden;
}

/* Les intitules restent pour qui ecoute : le choix du fond et le nombre de l'echelle se lisent
   d'eux-memes. */
.carte__reperes .carte__fond-titre,
.carte__reperes .carte__echelle-titre {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.carte__reperes .carte__fond-choix {
  width: 100%;
  height: auto;
  padding: 3px 12px;
  cursor: pointer;
  border: 0;
  background: transparent;
  color: inherit;
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
}


/* --- Le panneau des couches affichees (maquette de la carte, 2026-09-25) ------------------------ */

.couches-affichees {
  display: flex;
  flex-direction: column;
  gap: 5px;
  padding: 9px 11px;
}

.couches-affichees__vide {
  margin: 0;
  color: var(--color-neutral-700);
  font-size: var(--taille-etiquette);
}

.couches-affichees__liste {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Une couche, un encadre : sa tete, puis ses reglages quand on les deplie. */
.couches-affichees__ligne {
  border: 1px solid var(--color-neutral-300);
  border-radius: var(--rayon-bouton);
  background: var(--color-bg);
}

.couches-affichees__ligne--saisie {
  opacity: .5;
}

/* **Une couche masquee garde sa ligne** (Antoine, 2026-09-26) : l'oeil barre le dit, et le nom
   s'estompe. */
.couches-affichees__ligne--masquee .couches-affichees__nom,
.couches-affichees__ligne--masquee .couches-affichees__compte {
  opacity: .5;
}

.couches-affichees__bouton[aria-pressed="true"] .couches-affichees__oeil-ouvert,
.couches-affichees__bouton:not([aria-pressed="true"]) .couches-affichees__oeil-barre {
  display: none;
}

.couches-affichees__ligne--visee-dessus {
  box-shadow: 0 -2px 0 var(--color-accent-500);
}

.couches-affichees__ligne--visee-dessous {
  box-shadow: 0 2px 0 var(--color-accent-500);
}

.couches-affichees__tete {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 8px;
}

/* **La poignee se tire au pointeur**, et `touch-action` la retire au defilement du doigt. */
.couches-affichees__poignee {
  display: flex;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-text-muted);
  cursor: grab;
  touch-action: none;
}

/* **La poignee ne se montre qu'au survol de sa rangee, ou au clavier** (maquette « Carte, seconde
   lecture », 2026-10-03). Transparente et non retiree : elle garde sa place et se saisit encore. */
.couches-affichees__ligne:not(:hover):not(:focus-within) .couches-affichees__poignee {
  opacity: 0;
}

/* Les menus des reglages, arrondis comme les champs (doctrine, regle 3). */
.couches-affichees__reglages select {
  border-radius: var(--rayon-bouton);
}

/* Un segment de mesure eteint se voit eteint, malgre le gris de la palette pose apres. */
.carte__segment-de-mesure .segment[disabled] {
  color: var(--color-text-muted);
}

.couches-affichees__nom {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  font-size: var(--taille-etiquette);
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.couches-affichees__compte {
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
  font-variant-numeric: tabular-nums;
}

.couches-affichees__bouton {
  display: flex;
  padding: 3px;
  border: 0;
  background: transparent;
  color: var(--color-accent-500);
  cursor: pointer;
}

.couches-affichees__bouton:hover {
  color: var(--color-accent);
}

.couches-affichees__dessin {
  width: 14px;
  height: 14px;
}

.couches-affichees__chevron .couches-affichees__dessin {
  transition: transform .12s;
}

.couches-affichees__chevron[aria-expanded="true"] .couches-affichees__dessin {
  transform: rotate(180deg);
}

/* **Les trois reglages en grille**, l'intitule a gauche : le style et l'etiquette viennent de la
   rangee de la couche, deplaces ici le temps qu'on les regarde ; leurs conteneurs s'effacent
   (`display: contents`) pour que leurs intitules et leurs menus tombent dans la grille. */
.couches-affichees__reglages {
  display: grid;
  grid-template-columns: 62px minmax(0, 1fr);
  gap: 8px;
  align-items: center;
  padding: 9px 9px 10px;
  border-top: 1px solid var(--color-neutral-200);
  background: var(--color-neutral-100);
  border-radius: 0 0 var(--rayon-bouton) var(--rayon-bouton);
}

.couches-affichees__reglages[hidden] {
  display: none;
}

.couches-affichees__reglages .couches__detail,
.couches-affichees__reglages .couches__detail > label:not([hidden]),
.couches-affichees__opacite {
  display: contents;
}

/* **Un menu caché emporte son intitulé** : sans le préfixe de l'encart, la règle perdait contre
   `display: contents` ci-dessus, et le mot « Style » restait seul dans une case de la grille,
   décalant tout le reste (zonages environnementaux, relevé le 2026-09-28). */
.couches__stylage:has(> select[hidden]),
.couches-affichees__reglages .couches__detail > label:has(> select[hidden]) {
  display: none;
}

.couches-affichees__reglages .couches__detail > label > span,
.couches-affichees__intitule {
  color: var(--color-neutral-700);
  font: 600 var(--taille-etiquette)/1.2 var(--font-body);
}

.couches-affichees__reglages .couches__detail select {
  width: 100%;
  max-width: none;
  margin: 0;
}

.couches-affichees__reglages .couches__detail > p {
  grid-column: 1 / -1;
  margin: 0;
}

.couches-affichees__curseur {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}

/* Le curseur de l'opacite en vert clair (Antoine, 2026-09-25). */
.couches-affichees__curseur input {
  flex: 1;
  min-width: 0;
  accent-color: var(--ef-leaf);
}

.couches-affichees__valeur {
  width: 34px;
  color: var(--color-neutral-700);
  font-size: var(--taille-etiquette);
  font-variant-numeric: tabular-nums;
  text-align: right;
}

/* **« Plus de couches… » sous la derniere couche, en pointille** : un bouton qui ajoute, pas une
   couche de plus. */
.couches-affichees__reservoir:not([hidden]) {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  margin-top: 2px;
  padding: 8px;
  border-style: dashed;
  background: transparent;
}

.couches-affichees__disponibles {
  color: var(--color-text-muted);
  font-weight: 500;
}

/* **Le reservoir se pose par-dessus les panneaux**, avec son titre et sa croix. La classe vient du
   script : sans lui, le reservoir reste en place, ouvert. */
.couches__reservoir--par-dessus:not([hidden]) {
  position: absolute;
  inset: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  border-left: 2px solid var(--color-accent);
  background: var(--color-bg);
}

.couches__reservoir--par-dessus .couches__poignee,
.couches__reservoir--par-dessus .couches__ouvrir {
  display: none;
}

.couches__reservoir-tete {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 11px;
  background: var(--color-accent);
  color: #fff;
}

.couches__reservoir-tete[hidden] {
  display: none;
}

.couches__reservoir-titre {
  flex: 1;
  margin: 0;
  font: 800 var(--taille-bloc)/1.2 var(--font-body);
}

.couches__reservoir-croix {
  display: flex;
  padding: 2px;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
}

.couches__reservoir[hidden] {
  display: none;
}

.couches__recherche {
  display: block;
  width: calc(100% - 28px);
  margin: 8px 14px;
  padding: 5px 8px;
  border: 1px solid var(--color-divider);
  background: var(--color-bg);
  color: var(--color-text);
  font-size: var(--taille-etiquette);
}

.couches__recherche[hidden] {
  display: none;
}

/* **Les affichages enregistres, une icone sous le titre** : le mot reste pour qui ecoute. */
.couches__vues-mot {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Ouverts, ils se posent par-dessus les panneaux, comme le reservoir des couches. */
.couches__vues[open] > .couches__vues-corps {
  position: absolute;
  inset: 0;
  z-index: 20;
  overflow-y: auto;
  padding: 0 0 12px;
  border-left: 2px solid var(--color-accent);
  background: var(--color-bg);
}

.couches__vues[open] > .couches__vues-corps > * {
  flex: none;
}

.couches__vues[open] > .couches__vues-corps > :not(.couches__reservoir-tete) {
  margin-right: 14px;
  margin-left: 14px;
}

.couches__vues-corps .couches__vues-saisie,
.couches__vues-corps .couches__vues-menu {
  box-sizing: border-box;
}

.couches__vues-avertissement {
  margin: 0;
  padding: 6px 8px;
  background: var(--warn-bg);
  color: var(--warn-ink);
  font-size: var(--taille-etiquette);
}

/* --- Le panneau Parcelle sans selection (maquette de la carte, 2026-09-25) --------------------- */

/* Replié par le gabarit et le script ; ouvert à la main, il ne montre pas cinq lignes à « ? ». */
.panneau--parcelle--vide .panneau__renseignements {
  display: none;
}

/* Le dessin du bouton des colonnes de l'ecran scinde, a la taille du texte. */
.tiroir__dessin {
  width: 14px;
  height: 14px;
  vertical-align: -2px;
}

.couches__vues-dessin {
  width: 16px;
  height: 16px;
}

/* **« Ajouter une colonne » au pied du panneau des colonnes** : un bouton comme son voisin, et non
   plus le « + » de 24 px qu'il etait au bout de l'en-tete (repasse de la maquette FGF,
   2026-09-25). */
.classeur-barre__colonnes-appliquer .classeur__ajout-bouton {
  width: 100%;
  height: auto;
  border-color: var(--color-neutral-400);
  opacity: 1;
  font-size: var(--taille-etiquette);
}

/* Sans affichage enregistre, le menu est cache : son intitule part avec lui. */
.couches__vues-champ:has(> select[hidden]) {
  display: none;
}

/* ------------------------------------------------------ editer des contrats */

/* **L'ecran « Editer des contrats »** : contenu de la maquette validee le 2026-09-25, mise en page
   du design epure valide par Antoine le 2026-09-26 (`docs/refonte_ui/editer_un_contrat_epure.html`).
   Deux colonnes sans cadre ni lettre de repere, des lignes-resumes separees d'un filet fin, une
   barre d'action en bas. Style sobre et arrondi du CRM en fil. */
.contrats-edition {
  min-width: 0;
  margin: 14px 18px;
  background: var(--color-bg);
  border-radius: 14px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .06);
  overflow: hidden;
}

.contrats-edition__colonnes {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: 0 34px;
  padding: 14px 26px 0;
}

.contrats-edition__colonne {
  min-width: 0;
}

.contrats-edition__titre {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 8px 0 10px;
  font: 700 var(--taille-ecran)/1.3 var(--font-body);
}

.contrats-edition__compte {
  font-size: var(--taille-etiquette);
  font-weight: 500;
  color: var(--color-text-muted);
}

.contrats-edition__alerte {
  margin: 0 0 8px;
  padding: 7px 10px;
  border-radius: 10px;
  background: var(--message-refus-bg);
  color: var(--message-refus-ink);
  font-size: var(--taille-etiquette);
}

.contrats-edition__recherche {
  width: 100%;
  box-sizing: border-box;
  padding: 8px 14px;
  border: 0;
  border-radius: 999px;
  background: var(--color-neutral-100);
  color: var(--color-text);
  font: 400 var(--taille-texte)/1.3 var(--font-body);
}

.contrats-edition__filtres {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 10px 0 8px;
}

.contrats-edition__filtre {
  padding: 3px 10px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--color-neutral-700);
  font: 400 var(--taille-etiquette)/1.4 var(--font-body);
  white-space: nowrap;
  cursor: pointer;
}

.contrats-edition__filtre[aria-pressed="true"] {
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-weight: 600;
}

/* **La liste prend la hauteur de la fenetre**, moins la barre de titre, les bandeaux, les filtres
   et la barre d'action : eprouvee sur Grosne (494 contrats), une hauteur fixe n'en montrait que
   cinq et laissait vide la moitie basse de l'ecran. */
.contrats-edition__liste {
  min-height: 240px;
  max-height: calc(100vh - 380px);
  overflow: auto;
}

.contrats-edition__contrat {
  display: grid;
  grid-template-columns: 22px 1fr auto;
  align-items: center;
  gap: 0 10px;
  padding: 9px 10px;
  border-radius: 10px;
  cursor: pointer;
}

/* **Un `display: grid` l'emporterait sur `hidden`** : sans cette regle, un contrat filtre resterait
   a l'ecran. */
.contrats-edition__contrat[hidden] {
  display: none;
}

.contrats-edition__contrat:hover {
  background: var(--color-neutral-100);
}

.contrats-edition__contrat--cochee {
  background: var(--color-accent-100);
}

.contrats-edition__contrat input {
  margin: 0;
  accent-color: var(--color-accent);
}

.contrats-edition__nom {
  min-width: 0;
  font-size: var(--taille-texte);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.contrats-edition__detail {
  grid-column: 2;
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

/* La couleur de l'etat vient du classeur, posee par `contrats.js` depuis `data-fond` et
   `data-encre` : la politique de securite refuse tout style ecrit dans la page. */
.contrats-edition__pastille {
  grid-row: span 2;
  padding: 1px 9px;
  border-radius: 999px;
  background: var(--color-neutral-200);
  font: 600 var(--taille-etiquette)/1.5 var(--font-body);
  white-space: nowrap;
}

/* Les lignes-resumes : libelle a gauche, valeur au milieu, lien a droite. */
.contrats-edition__ligne {
  display: grid;
  grid-template-columns: 110px 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 11px 0;
  border-bottom: 1px solid var(--color-neutral-200);
}

.contrats-edition__depliable > summary {
  list-style: none;
  cursor: pointer;
}

.contrats-edition__depliable > summary::-webkit-details-marker {
  display: none;
}

/* Ouverte, la ligne montre ses menus et n'a plus besoin de « Modifier ». */
.contrats-edition__depliable[open] .contrats-edition__modifier {
  visibility: hidden;
}

.contrats-edition__depliable[open] > .contrats-edition__grille {
  padding: 8px 0 12px;
  border-bottom: 1px solid var(--color-neutral-200);
}

.contrats-edition__libelle {
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}

.contrats-edition__valeur {
  min-width: 0;
  overflow-wrap: anywhere;
}

.contrats-edition__sous {
  display: block;
  font-size: var(--taille-etiquette);
  font-weight: 400;
  color: var(--color-text-muted);
}

.contrats-edition__ok {
  color: var(--ok-ink);
}

.contrats-edition__ko {
  color: var(--message-refus-ink);
}

.contrats-edition__envoi-du-modele[hidden] {
  display: none;
}

.contrats-edition__fichier {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
}

.contrats-edition__icone {
  display: grid;
  place-items: center;
  flex: none;
  width: 24px;
  height: 28px;
  border-radius: 4px;
  background: #2b579a;
  color: #ffffff;
  font: 800 var(--taille-etiquette)/1 var(--font-body);
}

.contrats-edition__icone--paquet {
  background: var(--warn-ink);
}

.contrats-edition__champs {
  margin-top: 4px;
  font-size: var(--taille-etiquette);
  color: var(--color-neutral-700);
}

.contrats-edition__champs summary {
  cursor: pointer;
  color: var(--color-accent-500);
}

.contrats-edition__liste-des-champs {
  margin: 6px 0 0;
  padding-left: 16px;
}

.contrats-edition__grille {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: 8px 10px;
  align-items: center;
}

.contrats-edition__saisie {
  width: 100%;
  box-sizing: border-box;
  padding: 6px 10px;
  border: 1px solid var(--color-neutral-300);
  border-radius: 8px;
  background: var(--color-bg);
  color: var(--color-text);
  font: 400 var(--taille-texte)/1.3 var(--font-body);
}

/* La verification, et les documents de l'etat 5 : une carte arrondie par contrat. */
.contrats-edition__verification {
  display: grid;
  gap: 2px;
}

.contrats-edition__verdict-d-un-contrat {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 0 10px;
  padding: 8px 10px;
  border-radius: 10px;
  background: var(--color-neutral-100);
}

.contrats-edition__verdict-d-un-contrat .contrats-edition__detail {
  grid-column: 1;
}

.contrats-edition__verdict {
  grid-row: span 2;
  align-self: center;
  padding: 1px 9px;
  border-radius: 999px;
  font: 600 var(--taille-etiquette)/1.5 var(--font-body);
  white-space: nowrap;
}

.contrats-edition__verdict--ok {
  background: var(--ok-bg);
  color: var(--ok-ink);
}

.contrats-edition__verdict--a-completer {
  background: var(--warn-bg);
  color: var(--warn-ink);
}

.contrats-edition__verdict--impossible {
  background: var(--message-refus-bg);
  color: var(--message-refus-ink);
}

/* La barre d'action : le bilan a gauche, les deux gestes a droite. */
.contrats-edition__pied {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 18px;
  padding: 14px 26px;
  border-top: 1px solid var(--color-neutral-200);
  background: var(--color-neutral-100);
}

.contrats-edition__resume {
  font-size: var(--taille-texte);
  color: var(--color-neutral-700);
}

.contrats-edition__resume b {
  color: var(--color-text);
}

.contrats-edition__espace {
  margin-left: auto;
}

/* Les gestes en pilules. `.btn` garde la couleur, le survol et l'etat eteint. */
.contrats-edition__geste {
  padding: 8px 16px;
  border-radius: 999px;
  font-size: var(--taille-texte);
}

/* L'etat 5 : les documents produits. */
.contrats-documents {
  display: grid;
  gap: 12px;
  max-width: 760px;
  padding: 18px 26px;
}

/* Les contrats ecartes, en texte simple : ni fond ni cadre (revue de conformite du 2026-09-26). */
.contrats-documents__ecartes {
  margin: 0;
  font-size: var(--taille-texte);
  color: var(--color-neutral-700);
}

/* Le livrable : le fichier a gauche, « Telecharger » a droite, un filet dessous. */
.contrats-documents__livrable {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 0;
  border-bottom: 1px solid var(--color-neutral-200);
}

/* ------------------------------------------ rattacher a un compte-proprietaire
   L'ecran scinde, maquette validee le 2026-09-25 (proposition 1 + 2) : le selecteur sous la case
   COMPTE_PROPRIETAIRE, la barre jaune du pied, l'onglet Droits groupe par compte. Recopie de
   docs/refonte_ui/rattacher_dans_l_ecran_scinde.html. */

.classeur-case--edition:has(.rattachement-selecteur) {
  position: relative;
}

/* **Sous la case, et non dedans** : la case garde sa largeur, le selecteur deborde. Deux classes
   pour l'emporter sur la mise en ligne de toute saisie.

   **Pose sur la fenetre, hors du cadre de la table** (epreuve sur Grosne, 2026-09-26) : dans la
   table, le bas du cadre de l'ecran scinde le coupait. Le script donne sa place et la hauteur
   dont il dispose ; au-dela, c'est lui qui defile. 1100 : au-dessus des commandes de la carte. */
.classeur-case__saisie.rattachement-selecteur {
  position: fixed;
  left: var(--selecteur-gauche, 8px);
  top: var(--selecteur-haut, auto);
  z-index: 1100;
  display: grid;
  align-content: start;
  gap: 6px;
  box-sizing: border-box;
  width: 330px;
  max-height: var(--selecteur-place, 60vh);
  overflow-y: auto;
  padding: 8px;
  border: 1px solid var(--color-accent-500);
  background: #fff;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .18);
  white-space: normal;
  font-weight: 400;
  text-align: left;
}

/* Vers le haut quand la place manque sous la case (le script en decide a l'ouverture). */
.classeur-case__saisie.rattachement-selecteur--haut {
  top: auto;
  bottom: var(--selecteur-bas, auto);
}

.rattachement-selecteur__corps {
  display: grid;
  gap: 6px;
}

.rattachement-champ {
  box-sizing: border-box;
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--color-neutral-400);
  background: #fff;
  color: var(--color-text);
  font: inherit;
  font-size: var(--taille-texte);
}

.rattachement-titre {
  color: var(--color-neutral-700);
  font-size: var(--taille-etiquette);
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.rattachement-choix,
.rattachement-choix__trouves,
.rattachement-personnes {
  display: grid;
  gap: 3px;
}

.rattachement-choix__bouton {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 1px 8px;
  padding: 6px 8px;
  border: 1px solid var(--color-neutral-300);
  background: #fff;
  color: var(--color-accent-500);
  font: inherit;
  font-size: var(--taille-etiquette);
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.rattachement-choix__bouton:hover,
.rattachement-choix__bouton:focus-visible {
  border-color: var(--color-accent-500);
  background: var(--color-accent-100);
}

.rattachement-choix__bouton small {
  grid-column: 1 / -1;
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
  font-weight: 500;
}

.rattachement-choix__bouton em {
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
  font-style: normal;
  font-weight: 500;
}

.rattachement-choix__bouton--creer {
  border-style: dashed;
  color: var(--color-text);
}

.rattachement-ayant {
  display: grid;
  grid-template-columns: 1fr 120px 16px;
  gap: 6px;
  align-items: center;
  padding: 5px 7px;
  border: 1px solid var(--color-neutral-300);
  background: #fff;
  font-size: var(--taille-etiquette);
  font-weight: 600;
}

.rattachement-ayant small {
  display: block;
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
  font-weight: 500;
}

.rattachement-ayant select {
  min-width: 0;
  padding: 3px 4px;
  border: 1px solid var(--color-neutral-400);
  font-size: var(--taille-etiquette);
}

.rattachement-ayant--neuf {
  border-style: dashed;
}

/* Une cible de 24 px (revue du 2026-10-02, 06 §5) : la croix de 12 px se ratait a la souris. Les
   marges negatives la gardent dans la hauteur de la puce. */
.rattachement-ayant__retirer {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 24px;
  height: 24px;
  margin: -6px -6px -6px 0;
  padding: 0;
  border: 0;
  border-radius: var(--rayon-bouton);
  background: transparent;
  color: var(--color-neutral-700);
  font: inherit;
  cursor: pointer;
}

.rattachement-ayant__retirer:hover:not(:disabled) {
  background: var(--color-neutral-200);
}

.rattachement-avert {
  display: grid;
  gap: 6px;
  padding: 7px 9px;
  background: var(--warn-bg);
  color: #4d3c00;
  font-size: var(--taille-etiquette);
}

.rattachement-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.rattachement-actions button small {
  display: block;
  font-size: var(--taille-etiquette);
  font-weight: 500;
}

/* « l'ajouter au FGF d'abord » : un geste dans une phrase du bilan. */
.rattachement-lien {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-accent-500);
  font: inherit;
  font-weight: 600;
  text-decoration: underline;
  cursor: pointer;
}

/* **La barre jaune du pied**, entre la table et le pied du tiroir.

   **Resserree, et bornee aux deux cinquiemes du tiroir** (epreuve sur Grosne, 2026-09-26) : a
   son apparition, le tableau ne gardait la place que d'une ligne sur quatre. Au-dela, c'est la
   barre qui defile, et le tableau garde ses lignes. */
.rattachement-barre {
  display: grid;
  flex: 0 1 auto;
  gap: 3px;
  min-height: 0;
  max-height: 40%;
  overflow-y: auto;
  padding: 5px 12px;
  border-top: 2px solid var(--ef-sun);
  background: var(--warn-bg);
  color: #4d3c00;
  font-size: var(--taille-etiquette);
}

.rattachement-barre[hidden] {
  display: none;
}

/* **L'apercu dans le tableau, avant d'ecrire** (Antoine, 2026-09-26) : « ancien -> nouveau » en
   gris a la place de la valeur de la case, pose et retire par le code de la carte. */
.rattachement-case--apercu > .classeur-case__texte {
  display: none;
}

.rattachement-apercu {
  color: var(--color-text-muted);
}

.rattachement-barre ul {
  margin: 0;
  padding-left: 18px;
}

.rattachement-aide {
  margin: 0;
  color: var(--color-neutral-700);
  font-size: var(--taille-etiquette);
}

/* **Les autres cases de la colonne, visees par l'ecriture multiligne** pendant que le selecteur est
   ouvert (etat a). */
.tiroir:has(.tiroir__bascule input:checked):has(.rattachement-selecteur) .classeur-case[data-colonne="COMPTE_PROPRIETAIRE"]:not(.classeur-case--edition) {
  background: var(--warn-bg);
  box-shadow: inset 0 0 0 1.5px var(--ef-sun);
}

/* L'onglet Droits groupe par compte (etat d). */
.rattachement-droits {
  overflow: auto;
  flex: 1;
  min-height: 0;
}

.rattachement-droits__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--taille-etiquette);
}

.rattachement-droits__table th {
  padding: 7px 8px;
  border-right: 1px solid var(--color-neutral-200);
  border-bottom: 1px solid var(--color-neutral-300);
  background: var(--color-neutral-100);
  font-size: var(--taille-etiquette);
  font-weight: 800;
  letter-spacing: .06em;
  text-align: left;
  text-transform: uppercase;
  white-space: nowrap;
}

.rattachement-droits__table td {
  position: relative;
  padding: 6px 8px;
  border-right: 1px solid var(--color-neutral-200);
  border-bottom: 1px solid var(--color-neutral-200);
}

.rattachement-droits__groupe td {
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-size: var(--taille-etiquette);
  font-weight: 700;
}

.rattachement-droits__groupe small {
  margin-left: 8px;
  color: var(--color-neutral-700);
  font-weight: 500;
}

.rattachement-droits__neuve td {
  background: var(--ok-bg);
}

.rattachement-droits__edition {
  box-shadow: inset 0 0 0 2px var(--ef-sun);
}

.rattachement-droits__table td.rattachement-droits__edition {
  background: #fff;
  white-space: normal;
}

.rattachement-droits__droit select {
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}

.rattachement-droits__retrait {
  width: 1%;
  text-align: right;
  white-space: nowrap;
}

/* Une cible de 32 px au moins (chantier 1, 2026-10-02) : la croix de 24 px se touchait en visant
   le menu du droit voisin. */
.rattachement-droits__retirer {
  min-height: 32px;
}

.rattachement-droits__ajout td {
  border-bottom-color: var(--color-neutral-300);
}

.rattachement-droits__ajouter {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-accent-500);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.rattachement-droits__edition .rattachement-personnes {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 10;
  width: 280px;
}

/* La fiche du compte a cote du tableau (proposition 3, etats f a h). */
.rattachement-tiroir {
  display: flex;
  flex: 1;
  min-height: 0;
}

.rattachement-tiroir__principal {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

/* **Le tableau garde trois lignes entieres, la barre jaune cede la place** (seconde epreuve sur
   Grosne, 2026-09-26) : la barre prenait la hauteur et coupait la deuxieme ligne par le milieu.
   216 px : l'en-tete, trois lignes pliees sur deux (53 px chacune) et la rangee de pagination.
   Au-dela, la barre retrecit et defile.

   **Vise par l'identifiant de la table** : `#classeur-table`, qui pose `min-height: 0`, l'emporte
   sur toute regle de classes, et la hauteur gardee ne prenait pas (troisieme epreuve, mesuree).

   **Seulement quand la barre est ouverte** (Antoine, 2026-10-04) : gardee toujours, elle faisait
   sortir le bas du tableau, et sa barre de defilement, d'un tiroir moins haut que 216 px. */
.rattachement-tiroir__principal:has(> .rattachement-barre:not([hidden])) > #classeur-table,
.rattachement-tiroir__principal:has(> .rattachement-barre:not([hidden])) > .rattachement-droits {
  min-height: 216px;
}

/* **La barre ouverte, le tiroir prend un peu plus de la moitie de l'ecran** (troisieme epreuve
   sur Grosne, mesuree a 1440 x 900) : au partage ordinaire, trois lignes et le pied ne laissaient
   a la barre que 12 px. Une hauteur reglee a la poignee l'emporte, et la barre defile alors. */
.carte--scinde:has(.rattachement-barre:not([hidden])) {
  grid-template-rows: minmax(0, 1fr) minmax(0, 1.15fr);
}

.rattachement-fiche__chiffres {
  color: var(--color-neutral-800);
  font-size: var(--taille-etiquette);
}

.rattachement-fiche__chiffres strong {
  font-size: var(--taille-ecran);
}

.rattachement-portee {
  display: flex;
  align-items: flex-start;
  gap: 7px;
  padding: 6px 8px;
  border: 1px solid var(--color-neutral-300);
  background: #fff;
  font-size: var(--taille-etiquette);
}

.rattachement-portee small {
  display: block;
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
}

.rattachement-puces {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}

.rattachement-puce {
  padding: 3px 8px;
  border: 1px solid var(--color-accent-200);
  background: #fff;
  color: var(--color-accent-500);
  font-size: var(--taille-etiquette);
  font-weight: 600;
}

.rattachement-puce--choisie {
  border-color: var(--color-accent-500);
  background: var(--color-accent-100);
}

/* La fleche d'une case COMPTE_PROPRIETAIRE, qui ouvre la fiche : placee comme celle de l'ecran du
   FGF (`.classeur-case__fiche`), en haut a droite de la case, visible au survol. */
.classeur-case:has(> .rattachement-fleche) {
  position: relative;
}

.rattachement-fleche {
  position: absolute;
  top: 6px;
  right: 4px;
  padding: 1px 4px;
  border: 0;
  background: var(--color-bg);
  color: var(--color-accent);
  font: 700 var(--taille-etiquette)/1 var(--font-body);
  cursor: pointer;
  opacity: 0;
}

.classeur-case:hover .rattachement-fleche,
.rattachement-fleche:focus-visible {
  opacity: 1;
}

[data-theme="sombre"] .rattachement-portee,
[data-theme="sombre"] .rattachement-puce,
[data-theme="sombre"] .classeur-case__saisie.rattachement-selecteur,
[data-theme="sombre"] .rattachement-champ,
[data-theme="sombre"] .rattachement-choix__bouton,
[data-theme="sombre"] .rattachement-ayant,
[data-theme="sombre"] .rattachement-droits__table td.rattachement-droits__edition {
  background: var(--color-surface);
  color: var(--color-text);
}

[data-theme="sombre"] .rattachement-avert,
[data-theme="sombre"] .rattachement-barre {
  color: var(--warn-ink);
}

/* --- La fenetre d'export de la carte (maquette validee par Antoine le 2026-09-26) ------------- */

.carte-export {
  width: min(1180px, 96vw);
  max-width: none;
  max-height: 94vh;
  padding: 0;
  border: 1px solid var(--color-neutral-300);
  border-radius: 8px;
  background: var(--color-bg);
  color: var(--color-text);
}

.carte-export::backdrop {
  background: rgb(0 0 0 / 45%);
}

.carte-export__corps {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  max-height: 94vh;
  margin: 0;
}

.carte-export__apercu {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 0;
  padding: 24px;
  background: var(--color-surface);
  overflow: hidden;
}

/* L'apercu est la page entiere, a sa definition d'impression, reduite pour tenir. */
.carte-export__page {
  display: block;
  max-width: 100%;
  max-height: calc(94vh - 48px);
  background: #fff;
  box-shadow: 0 2px 10px rgb(0 0 0 / 20%);
  /* **On fait glisser l'apercu pour centrer la carte** (Antoine, 2026-09-26). */
  cursor: grab;
  touch-action: none;
}

.carte-export__page:active {
  cursor: grabbing;
}

/* **Blanc, comme la maquette** : le gris du fond de l'application ternissait les segments et le
   champ du titre. Le theme sombre garde son fond (plus bas). */
.carte-export__reglages {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 18px;
  border-left: 1px solid var(--color-neutral-300);
  background: #fff;
  overflow: auto;
  font: 400 var(--taille-texte)/1.3 var(--font-body);
}

.carte-export__reglages .input {
  background: #fff;
  border: 1px solid var(--color-neutral-300);
}

.carte-export__reglages input[type="checkbox"] {
  accent-color: var(--color-accent-700);
  width: 15px;
  height: 15px;
  margin: 0;
}

[data-theme="sombre"] .carte-export__reglages,
[data-theme="sombre"] .carte-export__reglages .input {
  background: var(--color-bg);
}

/* Le titre de la fenetre et sa croix de fermeture (Antoine, 2026-09-26). */
.carte-export__entete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}



.carte-export__titre {
  margin: 0;
  font: 700 var(--taille-bloc)/1.2 var(--font-heading);
  color: var(--color-accent-700);
}

.carte-export__groupe {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.carte-export__intitule {
  padding: 0;
  font: 700 var(--taille-etiquette)/1.2 var(--font-body);
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* Une bascule : des boutons radio caches, dont l'etiquette se dessine en segment. */
.carte-export__bascule {
  display: flex;
  border: 1px solid var(--color-accent-700);
  border-radius: 3px;
  overflow: hidden;
}

.carte-export__bascule > label {
  flex: 1;
  display: flex;
}

.carte-export__bascule > label + label {
  border-left: 1px solid var(--color-accent-700);
}

.carte-export__bascule input,
.carte-export__coins input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.carte-export__bascule span {
  flex: 1;
  padding: 5px 4px;
  text-align: center;
  font-size: var(--taille-etiquette);
  color: var(--color-accent-700);
  cursor: pointer;
}

.carte-export__bascule input:checked + span {
  background: var(--color-accent-700);
  color: #fff;
  font-weight: 600;
}

.carte-export__bascule input:focus-visible + span,
.carte-export__coins input:focus-visible + span {
  outline: 2px solid var(--color-accent-500);
  outline-offset: -2px;
}

.carte-export__bascule input:disabled + span {
  color: var(--color-neutral-400);
  cursor: not-allowed;
}

.carte-export__element {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  min-height: 20px;
}

.carte-export__element > label,
.carte-export__cases > label {
  display: flex;
  align-items: center;
  gap: 10px;
}

.carte-export__cases {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Le curseur de la taille de la légende, sous sa case (Antoine, 2026-09-28). */
.carte-export__taille {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 10px;
  padding-left: 24px;
}

.carte-export__taille input {
  width: 100%;
  accent-color: var(--color-accent);
}

/* La barre et la flèche : deux cases, un seul choix de coin, centre sur les deux. */
.carte-export__element--double {
  align-items: center;
}

/* Les quatre coins de la carte, en petite grille : on clique celui ou poser l'element. */
.carte-export__coins {
  display: grid;
  grid-template-columns: 11px 11px;
  gap: 2px;
}

.carte-export__coins span {
  display: block;
  width: 11px;
  height: 8px;
  border: 1px solid var(--color-neutral-400);
  border-radius: 1px;
  cursor: pointer;
}

.carte-export__coins input:checked + span {
  background: var(--color-accent-700);
  border-color: var(--color-accent-700);
}

.carte-export__coins input:disabled + span {
  background: var(--color-neutral-200);
  cursor: not-allowed;
}

/* Le porteur du bouton de telechargement : un bouton eteint ne montre pas son infobulle, son
   porteur si (regle des boutons eteints, raison au survol). */
.carte-export__telechargement {
  display: inline-flex;
}

.carte-export__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 6px;
}


@media (max-width: 900px) {
  .carte-export__corps {
    grid-template-columns: 1fr;
  }

  .carte-export__reglages {
    border-left: 0;
    border-top: 1px solid var(--color-neutral-300);
  }
}

/* ---- Le compte client (Antoine, 2026-10-01 ; maquette docs/refonte_ui/interface_client.html) ----
   Une barre sombre a la place du rail, puis les onglets du projet. `application--client` retire
   ce que la lecture seule ne fait que griser : un client ne voit pas les gestes qu'il n'a pas. */
.barre-du-client {
  display: flex;
  align-items: center;
  gap: 14px;
  height: 52px;
  padding: 0 18px;
  background: var(--color-accent);
  color: #fff;
}
.barre-du-client__marque {
  display: flex;
  align-items: center;
  gap: 9px;
  color: inherit;
  text-decoration: none;
}
.barre-du-client__logo {
  width: 26px;
  height: 26px;
  object-fit: contain;
  background: #fff;
  padding: 2px;
  border-radius: 6px;
}
.barre-du-client__nom {
  font-weight: 700;
  font-size: var(--taille-ecran);
}
.barre-du-client__espace {
  flex: 1;
}

.barre-du-client .barre-de-titre__projet {
  color: rgba(255, 255, 255, 0.85);
}
.barre-du-client__compte {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 12px 4px 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  font-weight: 600;
  font-size: var(--taille-texte);
  text-decoration: none;
}
.barre-du-client__initiales {
  position: relative;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--ef-sun);
  color: var(--color-accent);
  font-size: var(--taille-etiquette);
  font-weight: 700;
}
/* Les onglets, dans la barre verte (Antoine, 2026-10-05) : le soleil souligne l'actif. */
.onglets-du-client {
  display: flex;
  align-self: stretch;
  gap: 4px;
  margin-left: 18px;
}
.onglets-du-client__onglet {
  display: flex;
  align-items: center;
  padding: 3px 12px 0;
  border-bottom: 3px solid transparent;
  color: inherit;
  opacity: 0.75;
  font-weight: 600;
  font-size: var(--taille-texte);
  text-decoration: none;
  white-space: nowrap;
}
.onglets-du-client__onglet:hover {
  opacity: 1;
}
.onglets-du-client__onglet--actif {
  opacity: 1;
  font-weight: 800;
  border-bottom-color: var(--ef-sun);
}
/* Un geste que la lecture seule eteint disparait pour un client : il ne l'a pas, et un bouton
   grise lui poserait une question qu'il n'a pas a se poser. Les actions d'un ecran vide aussi :
   charger un FGF ou ouvrir la bibliotheque menent a des ecrans qui ne lui sont pas ouverts. */
.application--client button:disabled,
.application--client [data-reserve-a-l-equipe],
.application--client .etat-vide:not(.etat-vide--illisible) .etat-vide__actions {
  display: none !important;
}
.accueil-du-client {
  max-width: 880px;
}
/* La société a gauche, l'equipe a droite : les pieces de la Bibliotheque. */
.accueil-du-client__qui {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
  font-size: var(--taille-texte);
}
.accueil-du-client__projets > li {
  min-width: 0;
}
.accueil-du-client__qui .bibliotheque__equipe {
  flex-wrap: wrap;
  row-gap: 3px;
}
.accueil-du-client__projets {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
  margin: 0;
  padding: 0;
  list-style: none;
}
/* **Boîte bordée et largeur minimale nulle** (Antoine, 2026-10-05) : une carte en lien ajoutait
   ses marges à sa pleine largeur, et une longue équipe l'élargissait ; elle chevauchait sa voisine. */
.accueil-du-client__carte {
  display: flex;
  flex-direction: column;
  gap: 6px;
  box-sizing: border-box;
  width: 100%;
  min-width: 0;
  overflow-wrap: anywhere;
  padding: 16px;
  border: 1px solid var(--color-divider);
  border-radius: 10px;
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.accueil-du-client__carte:hover {
  border-color: var(--color-accent);
}
.accueil-du-client__nom {
  font-weight: 700;
  font-size: var(--taille-ecran);
}
.accueil-du-client__date {
  font-size: var(--taille-etiquette);
  color: var(--color-text-muted);
}
.accueil-du-client__cause {
  color: var(--message-refus-ink);
}
/* Les pastilles d'etat d'un client restent lisibles mais ne menent plus a combler un manque :
   le calcul et le depot ne lui sont pas ouverts. */
.application--client .pastille__lien {
  pointer-events: none;
  text-decoration: none;
  color: inherit;
}
.application--client .cartouche__geste,
.application--client .retour-au-travail {
  display: none !important;
}
/* **L'etat du projet ne se montre pas au client** (Antoine, 2026-10-04) : ni les pastilles FGF,
   Carto et Ecart, ni leur detail, ni « Lecture seule ». Caches et non retires : le detail porte la
   version vue, que les ecritures emportent, et les remplacements hors bande doivent les trouver. */
.application--client #pastilles-d-etat,
.application--client #barre-de-statut {
  display: none !important;
}
/* **Pas de poignee de largeur pour un client** : le serveur refuse son tirage, et la largeur
   tiree reviendrait au rechargement. */
.application--client .classeur__poignee-de-largeur {
  display: none !important;
}
/* La fleche vers la fiche d'un compte mene aux gestes de rattachement : rien a y lire pour un
   client que la ligne ne dise deja. */
.application--client .rattachement-fleche {
  display: none !important;
}

/* La page des jetons d'acces : trois blocs empiles, dans le cadre des encarts du compte. */
.jetons {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 960px;
}

.jetons__nouveau,
.jetons__liste,
.jetons__creation {
  border: 2px solid var(--color-text);
  background: var(--color-surface);
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
  overflow-x: auto;
}

.jetons__texte {
  font: 400 var(--taille-texte)/1.4 ui-monospace, "Cascadia Mono", Consolas, monospace;
  word-break: break-all;
  user-select: all;
}

/* --- Statut et technologie d'un projet (2026-10-01) -------------------------------------------
   Maquette `docs/refonte_ui/carte_des_projets.html`, version 3. Le statut prend les couleurs
   d'état ; la technologie, la teinte de sa famille d'énergie et son pictogramme. */
.pictogrammes {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.statut {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--taille-etiquette);
  font-weight: 600;
  white-space: nowrap;
}

.statut__point {
  width: 8px;
  height: 8px;
  border-radius: var(--rayon-pilule);
  background: var(--etat-neutre);
}

.statut--en-cours .statut__point { background: var(--etat-en-cours); }
.statut--termine .statut__point { background: var(--etat-acquis); }

.techno--pv { --techno: var(--techno-pv); --techno-encre: var(--encre-sur-clair); }
.techno--agri-pv { --techno: var(--techno-agri-pv); --techno-encre: var(--encre-sur-clair); }
.techno--eolien { --techno: var(--techno-eolien); --techno-encre: var(--encre-sur-fonce); }
.techno--repowering { --techno: var(--techno-repowering); --techno-encre: var(--encre-sur-fonce); }
.techno--convoi { --techno: var(--techno-convoi); --techno-encre: var(--encre-sur-fonce); }
.techno--ecologie { --techno: var(--techno-ecologie); --techno-encre: var(--encre-sur-fonce); }
.techno--bess { --techno: var(--techno-bess); --techno-encre: var(--encre-sur-fonce); }
.techno--raccordement {
  --techno: var(--techno-raccordement);
  --techno-encre: var(--encre-sur-fonce);
}

.techno {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 1px 9px 1px 2px;
  border: 1px solid var(--color-neutral-400);
  border-radius: var(--rayon-pilule);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--taille-etiquette);
  font-weight: 600;
  white-space: nowrap;
}

.techno__disque {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: var(--rayon-pilule);
  background: var(--techno, var(--etat-neutre));
  color: var(--techno-encre, var(--encre-sur-fonce));
}

.techno__picto {
  width: 13px;
  height: 13px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.technos {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 4px;
}

/* --- Carte des projets ------------------------------------------------------------------------ */
.carte-des-projets {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr);
  height: 100%;
  min-height: 0;
  border-top: 1px solid var(--color-neutral-200);
}

.carte-des-projets__panneau {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  padding: 12px;
  overflow: auto;
  border-right: 1px solid var(--color-neutral-200);
  background: var(--color-surface);
}

.carte-des-projets__recherche {
  padding: 5px 12px;
  border: 1px solid var(--color-neutral-400);
  border-radius: var(--rayon-pilule);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--taille-texte);
}

/* Les deux filtres, l'un sous l'autre : côte à côte, ils coupaient leur texte. */
/* Les filtres en puces (maquette 3.7, 2026-10-03) : le bouton radio se cache, son libelle
   porte la puce, son focus reste visible. */
.carte-des-projets__puces {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
}

.carte-des-projets__puce input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.carte-des-projets__puce span {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--rayon-pilule);
  color: var(--color-neutral-700);
  font-size: var(--taille-etiquette);
  cursor: pointer;
}

.carte-des-projets__puce input:checked + span {
  background: var(--color-accent-100);
  color: var(--color-accent);
  font-weight: 600;
}

/* En theme sombre, le vert sur le fond de la puce cochee reste sous 4,5 pour 1 : l'encre du
   texte, la graisse 600 garde le second signe. */
[data-theme="sombre"] .carte-des-projets__puce input:checked + span {
  color: var(--color-text);
}

/* Les technologies, la liste à cocher de Général (2026-10-04) : ouverte, elle se déplie dans le
   volet au lieu de flotter, pour ne pas être coupée par son défilement. */
.carte-des-projets__technologies > .general__resume {
  display: flex;
}

.carte-des-projets__technologies > .general__technologies {
  flex-direction: column;
  align-items: flex-start;
  padding: 8px 0 0;
}

/* **Ouverte, la liste montre les technologies une seule fois** (Antoine, 2026-10-04) : le resume
   des cochees se cache, il les doublait. */
.carte-des-projets__technologies[open] [data-resume-technologies] {
  display: none;
}

/* Sans disque, la pastille reprend son retrait de gauche. */
.carte-des-projets__sans-technologie {
  padding-left: 9px;
}

.carte-des-projets__puce input:focus-visible + span {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}

/* Les calques, dans un bouton en haut à droite de la carte. */
.carte-des-projets__calques {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  border: 0;
}

.carte-des-projets__bouton-calques {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--color-neutral-400);
  border-radius: var(--rayon-bouton);
  background: var(--color-surface);
  color: var(--color-text);
  cursor: pointer;
}

.carte-des-projets__bouton-calques .techno__picto {
  width: 18px;
  height: 18px;
}

.carte-des-projets__menu-calques {
  padding: 8px 12px;
  border: 1px solid var(--color-neutral-400);
  border-radius: var(--rayon-cadre);
  background: var(--color-surface);
  color: var(--color-text);
}

.carte-des-projets__menu-calques label {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 3px 0;
  font-size: var(--taille-texte);
  white-space: nowrap;
}

.carte-des-projets__menu-calques input {
  margin: 0;
  accent-color: var(--color-accent);
}

.carte-des-projets__refus {
  margin: 0;
  font-size: var(--taille-texte);
}

.carte-des-projets__liste {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Une ligne par projet : la petite épingle et le nom. */
.carte-des-projets__projet {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 32px;
  padding: 5px 8px;
  border-radius: var(--rayon-bouton);
  cursor: pointer;
}

/* Une ligne écartée par un filtre : sans cette règle, `display: flex` la laisserait visible. */
.carte-des-projets__projet[hidden] {
  display: none;
}

.carte-des-projets__projet .epingle {
  flex: none;
  width: 18px;
  height: 23px;
}

.carte-des-projets__projet:hover,
.carte-des-projets__projet[aria-current="true"] {
  background: var(--color-accent-100);
}

.carte-des-projets__nom {
  overflow: hidden;
  font-size: var(--taille-texte);
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.carte-des-projets__vue {
  min-height: 0;
}

/* L'épingle : la teinte dit la technologie, le remplissage le statut. */
.epingle {
  width: 30px;
  height: 38px;
  overflow: visible;
}

.epingle__goutte {
  fill: var(--techno, var(--etat-neutre));
  stroke: var(--color-text);
  stroke-opacity: 0.45;
  stroke-width: 1.5;
}

.epingle__picto {
  color: var(--techno-encre, var(--encre-sur-fonce));
}

.epingle--previsionnel .epingle__goutte {
  fill: var(--color-surface);
  stroke: var(--techno, var(--etat-neutre));
  stroke-opacity: 1;
  stroke-width: 2.5;
}

.epingle--previsionnel .epingle__picto {
  color: var(--color-text);
}

.epingle__coche {
  display: none;
}

.epingle--termine .epingle__coche {
  display: inline;
}

.epingle__coche circle {
  fill: var(--etat-acquis);
  stroke: var(--color-surface);
  stroke-width: 1.5;
}

.epingle__coche path {
  fill: none;
  stroke: var(--encre-sur-fonce);
  stroke-width: 1.6;
}

.carte-des-projets__zone {
  fill: var(--techno, var(--etat-neutre));
  fill-opacity: 0.22;
  stroke: var(--techno, var(--etat-neutre));
  stroke-width: 2;
}

/* L'exclusivité : hachurée en cours, pointillée à venir, pâle échue. **En cours, le remplissage
   n'est pas fixé ici** : il vient du motif de sa technologie, que le script pose sur la forme. */
.carte-des-projets__exclusivite {
  stroke: var(--techno, var(--etat-neutre));
  stroke-width: 2;
}

.carte-des-projets__exclusivite--active {
  fill-opacity: 1;
}

.carte-des-projets__exclusivite--a-venir {
  fill: none;
  stroke-dasharray: 6 4;
}

.carte-des-projets__exclusivite--echue {
  fill: var(--techno, var(--etat-neutre));
  fill-opacity: 0.05;
  stroke-opacity: 0.5;
}

.carte-des-projets__fond-hachure {
  fill: var(--techno, var(--etat-neutre));
  fill-opacity: 0.12;
}

.carte-des-projets__hachure {
  stroke: var(--techno, var(--etat-neutre));
  stroke-width: 2;
  stroke-opacity: 0.6;
}

.carte-des-projets__lien {
  fill: none;
  stroke: var(--techno, var(--etat-neutre));
  stroke-width: 2;
  stroke-dasharray: 3 3;
}

.carte-des-projets__bulle {
  display: grid;
  gap: 6px;
  font-size: var(--taille-texte);
}

.carte-des-projets__bulle h3 {
  margin: 0;
  font-size: var(--taille-bloc);
}

.carte-des-projets__faits {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 4px 10px;
  margin: 0;
}

.carte-des-projets__faits dt {
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
}

.carte-des-projets__faits dd {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 0;
}

/* --- La mission du projet, sur Général (2026-10-01) ------------------------------------------- */
.general__mission {
  display: contents;
}

.general__segment {
  display: inline-flex;
  padding: 2px;
  border: 1px solid var(--color-neutral-400);
  border-radius: var(--rayon-pilule);
}

.general__segment-choix {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 3px 12px;
  border-radius: var(--rayon-pilule);
  color: var(--color-text-muted);
  font-size: var(--taille-etiquette);
  font-weight: 600;
  cursor: pointer;
}

.general__segment-choix input,
.general__technologie input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.general__segment-choix:has(input:checked) {
  background: var(--color-accent-100);
  box-shadow: inset 0 0 0 1px var(--color-accent);
  color: var(--color-text);
}

/* Un choix éteint se voit éteint ; sa raison se lit au survol (« Communes », 2026-10-03). */
.general__segment-choix:has(input:disabled:not(:checked)) {
  opacity: 0.45;
  cursor: not-allowed;
}

.general__segment-choix:has(input:focus-visible),
.general__technologie:has(input:focus-visible) {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.general__technologies {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.general__technologie {
  position: relative;
  cursor: pointer;
}

.general__technologie:has(input:not(:checked)) .techno {
  border-style: dashed;
  color: var(--color-text-muted);
}

.general__technologie:has(input:not(:checked)) .techno__disque {
  border: 1px dashed var(--color-neutral-400);
  background: transparent;
  color: var(--color-text-muted);
}

.general__champ {
  padding: 4px 8px;
  border: 1px solid var(--color-neutral-400);
  border-radius: var(--rayon-bouton);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--taille-texte);
}

.general__champ--court {
  flex: none;
  width: 64px;
  min-width: 0;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.general__exclusivite {
  flex-direction: column;
  align-items: stretch;
}

.general__exclusivite-reglages {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

/* Les plis de la mission (2026-10-03) : technologies en liste, exclusivité repliée. Fermés, ils
   montrent leur résumé : les pastilles cochées, l'état de l'exclusivité. */
.general__deroulant {
  position: relative;
}

.general__resume {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  border: 1px solid var(--color-neutral-400);
  border-radius: var(--rayon-bouton);
  font-size: var(--taille-texte);
  list-style: none;
  cursor: pointer;
}

.general__resume::-webkit-details-marker {
  display: none;
}

.general__resume:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.general__chevron::after {
  content: "\25BE";
  color: var(--color-text-muted);
}

details[open] > .general__resume .general__chevron::after {
  content: "\25B4";
}

.general__deroulant > .general__technologies {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 3;
  flex-direction: column;
  align-items: flex-start;
  flex-wrap: nowrap;
  padding: 8px;
  border: 1px solid var(--color-neutral-400);
  border-radius: var(--rayon-cadre);
  background: var(--color-surface);
}

.general__pliage > :not(summary) {
  margin-top: 8px;
}

/* `isolation` enferme les volets de Leaflet (z-index 400 à 1000) dans la petite carte : sans
   elle, ils passaient au-dessus de la liste des technologies ouverte. */
.general__dessin {
  height: 240px;
  border: 1px solid var(--color-neutral-400);
  border-radius: var(--rayon-cadre);
  isolation: isolate;
}

.general__zone-du-dessin {
  fill: none;
  stroke: var(--color-text-muted);
  stroke-width: 1.5;
  stroke-dasharray: 4 3;
}

.general__forme-du-dessin {
  fill: var(--color-accent);
  fill-opacity: 0.15;
  stroke: var(--color-accent);
  stroke-width: 2;
}

/* L'exclusivité par communes (2026-10-03) : recherche, étiquettes, petite carte. */
.general__communes {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.general__ligne-des-communes {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

.general__recherche-de-commune {
  position: relative;
}

.general__suggestions {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  min-width: 100%;
  padding: 4px 0;
  border: 1px solid var(--color-neutral-400);
  border-radius: var(--rayon-bouton);
  background: var(--color-surface);
}

.general__suggestions[hidden] {
  display: none;
}

.general__suggestion {
  padding: 4px 10px;
  border: 0;
  background: transparent;
  color: var(--color-text);
  font-size: var(--taille-texte);
  text-align: left;
  cursor: pointer;
}

.general__suggestion:hover,
.general__suggestion:focus-visible {
  background: var(--color-accent-100);
}

.general__limitrophes {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.general__communes-choisies {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.general__commune-choisie {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 1px 4px 1px 10px;
  border: 1px solid var(--color-neutral-400);
  border-radius: var(--rayon-cadre);
  font-size: var(--taille-etiquette);
  font-weight: 600;
}

.general__retrait-de-commune {
  border: 0;
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
}

.general__commune-de-l-exclusivite {
  fill: var(--color-accent);
  fill-opacity: 0.25;
  stroke: var(--color-accent);
  stroke-width: 2;
}

.general__commune-limitrophe {
  fill: var(--color-accent);
  fill-opacity: 0.08;
  stroke: var(--color-accent);
  stroke-width: 1;
  stroke-dasharray: 3 3;
}

.cellule-du-statut {
  display: inline-flex;
  align-items: center;
  min-width: 0;
}

/* **Un lien dessiné en bouton principal garde son encre** dans une bibliothèque qui colore tous
   ses liens (Leaflet : `.leaflet-container a`, chargé après cette feuille). Écrit pour tout
   l'écran et non pour la bulle de la carte des projets : le contrôle des rôles refuse qu'un
   écran redessine un bouton (chantier 2, 2026-10-02). */
a.btn.btn-primary {
  color: var(--bouton-principal-encre);
}

/* La légende, repliée par défaut : un petit bouton « Légende » en bas à gauche. */
.carte-des-projets__legende {
  padding: 4px 10px;
  border: 1px solid var(--color-neutral-400);
  border-radius: var(--rayon-cadre);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--taille-etiquette);
}

.carte-des-projets__legende summary {
  color: var(--color-text-muted);
  font-weight: 600;
  cursor: pointer;
}

.carte-des-projets__legende-rangs {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin-top: 6px;
}

.carte-des-projets__echantillon {
  width: 18px;
  height: 12px;
}

.carte-des-projets__legende-rang {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.carte-des-projets__legende .epingle {
  width: 18px;
  height: 23px;
}

/* La bulle d'un projet suit le thème : Leaflet la pose en blanc. */
.carte-des-projets .leaflet-popup-content-wrapper,
.carte-des-projets .leaflet-popup-tip {
  background: var(--color-surface);
  color: var(--color-text);
}

/* Le rendez-vous client (Antoine, 2026-10-03) : le bouton du menu, la liste des projets montrés,
   et la pastille et le menu des initiales dans la barre du client. */
.rail__rendez-vous {
  margin-bottom: 6px;
  text-decoration: none;
}
.barre-du-client__menu {
  position: relative;
}
.barre-du-client__menu > summary {
  list-style: none;
  cursor: pointer;
}
.barre-du-client__menu > summary::-webkit-details-marker {
  display: none;
}
.rendez-vous-client__projets {
  margin: 0;
  padding-left: 18px;
}
.barre-du-client__pastille {
  position: absolute;
  right: -2px;
  bottom: -2px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--ef-leaf);
  border: 2px solid var(--rail);
}
.barre-du-client__choix {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 20;
  min-width: 220px;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  border: 1px solid var(--color-divider);
}
.barre-du-client__choix a {
  padding: 8px 12px;
  color: var(--color-text);
  font-weight: 600;
  text-decoration: none;
}
.barre-du-client__choix a:hover {
  background: var(--color-surface);
}

/* --- Ce que la base du FGF garde a cote de lui (moteur 4247095b, 2026-10-04) ----------------- */
.controles-du-fgf-a-venir {
  flex: none;
}
.controles-du-fgf {
  position: relative;
  flex: none;
  display: flex;
  align-items: center;
  gap: 6px;
}
.controles-du-fgf__anomalies > summary {
  list-style: none;
}
.controles-du-fgf__compte {
  color: var(--etat-a-surveiller);
  font-weight: 600;
}
.controles-du-fgf__liste {
  position: absolute;
  right: 0;
  z-index: 20;
  width: 360px;
  max-height: 320px;
  overflow-y: auto;
  margin: 4px 0 0;
  padding: 10px 12px;
  list-style: none;
  border: 1px solid var(--color-divider);
  border-radius: var(--rayon-cadre);
  background: var(--color-bg);
  font: 400 var(--taille-texte)/1.5 var(--font-body);
  color: var(--color-text);
}
.controles-du-fgf__liste li + li {
  margin-top: 6px;
}
.historique-du-fgf__quand {
  white-space: nowrap;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
