@import url('polices.css');
/* Polideo — feuille de style commune.
   Composants partagés : en-tête, cartes, tags, boutons, formulaires, états.
   Police système uniquement, aucun service de polices externe.

   Identité Polideo, violet et menthe (lot 9B, 15 septembre 2026), décidée par
   Adam : docs/branding/polideo/. Blanc dominant, anthracite pour le texte,
   violet de marque, violet plus foncé pour les actions et petits liens (contraste
   suffisant sous un libellé blanc), menthe en petite touche décorative seulement.
   Une teinte violette très légère reste ponctuelle : la une de l'accueil, les
   survols. Toujours sans ombres décoratives ni bordures gauches épaisses ; la
   séparation vient de l'espace et de traits fins. Les outils et l'administration
   héritent de ces jetons : ils ne portent pas de couleur propre. */

/* ---------- Jetons ---------- */
:root {
  /*
   * Le socle du portail : un jeton par décision, et une décision par emploi.
   *
   * Il a compté 17 tailles de texte sur l'accueil (12,5 · 13,33 · 13,5 · 25,5 px…),
   * 7 rayons de coin, 26 valeurs d'espacement dont 17 hors d'une grille de 4, et deux
   * gris séparés de onze points — invisibles l'un de l'autre, mais tous deux à tenir.
   * Rien de cela n'était un choix : c'était l'absence de choix, répétée 363 fois.
   *
   * La règle qui empêche d'y revenir : une valeur n'entre ici que si son emploi se
   * nomme. Pas d'emploi, pas de jeton ; pas de jeton, pas de valeur dans une règle.
   */

  /* ---- Typographie : trois rôles, jamais plus ---- */
  /*
   * Le portail n'avait pas d'écriture : il empruntait celle de l'appareil, et changeait
   * donc d'apparence d'un lecteur à l'autre. Les trois familles sont servies par Polideo
   * (assets/css/polices.css) et non par un tiers — voir assets/css/fonts/LICENCES.md.
   */
  --police: 'Instrument Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
    'Helvetica Neue', Arial, 'Noto Sans', sans-serif;
  --police-titre: 'Instrument Serif', Georgia, 'Times New Roman', serif;
  /* L'apparat de preuve : chiffres, dates, versions, identifiants de source,
     qualifications. La chasse fixe aligne les nombres en colonne et sépare à l'œil
     ce que Polideo a relevé de ce que Polideo écrit. */
  --police-apparat: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* ---- Échelle de texte : neuf valeurs, contre vingt-trois ---- */
  --t-12: 12px;   /* qualification, version, date, identifiant — toujours en apparat */
  --t-13: 13px;   /* légende, réserve, note de bas de carte */
  --t-15: 15px;   /* corps d'interface : outils, listes, formulaires */
  --t-17: 17px;   /* corps d'article et de dossier */
  --t-21: 21px;   /* intertitre, chapô */
  --t-27: 27px;   /* titre de bloc */
  --t-34: 34px;   /* titre de section */
  --t-44: 44px;   /* titre de page */
  --t-56: 56px;   /* titre d'article ou de dossier */

  /* ---- Espacement : grille de 4 ---- */
  /* ---- L'en-tête mobile — jetons nommés, défaut `AB7`, lot P2-62 ----
   *
   * `P2-63` redéfinira ces valeurs ; il ne doit pas avoir à redéfinir la **structure**. Une
   * seule valeur écrite en dur dans la rangée créerait exactement la reprise que ce lot existe
   * pour éviter, et c'est le genre de dette qu'on ne voit qu'au lot suivant.
   *
   * `--entete-seuil-compact` est la largeur sous laquelle la recherche cède sa place à la
   * navigation. Elle vaut 430 px parce que c'est **déjà** le seuil où le mot-symbole s'efface :
   * deux seuils voisins feraient deux ruptures visibles à deux pixels près. Un seuil ne peut
   * pas vivre dans une variable CSS — `@media` ne lit pas les variables —, donc il est **écrit
   * ici et repris littéralement dans la requête**, avec ce commentaire pour lien.
   */
  --entete-hauteur: 52px;
  --entete-recherche-repliee: 36px;   /* la largeur du bouton seul : le champ s'ouvre à la saisie */
  --entete-recherche-ouverte: min(58vw, 240px);
  --entete-lien-touche: 44px;         /* la plus petite cible tactile admise */

  --e-1: 4px;
  --e-2: 8px;
  --e-3: 12px;
  --e-4: 16px;
  --e-6: 24px;
  --e-8: 32px;
  --e-12: 48px;
  --e-16: 64px;

  /* ---- Rayons : trois, plus la pastille ---- */
  --r-s: 6px;
  --r-m: 6px;
  --r-l: 12px;
  --r-pilule: 999px;   /* réservé à la qualification ; c'est la pastille pleine qui datait le plus l'interface */

  /* ---- Couleur : l'identité, puis l'information ---- */
  --blanc: #ffffff;
  --anthracite: #141519;
  --marque: #635bff;        /* le symbole et les repères de marque ; pas pour le petit texte */
  --action: #4f46d6;        /* l'action seule : boutons, liens, sélection. 6,6:1 sur blanc */
  --action-survol: #3a32b0;
  --menthe: #9ce8cd;        /* touche décorative, jamais porteuse d’information */
  --teinte: #f4f3ff;
  /* ---- `AB8` : le fond de réserve passe du crème au froid ----
   * Il valait #fbf6ec, un crème. Adam a refusé les fonds chauds, et ce qu'il portait — « ceci
   * limite l'affirmation » — n'est **pas porté par la couleur** : la feuille pose le mot
   * « Réserve » quand le balisage ne le porte pas, et ce commentaire existait déjà avant ce lot.
   * Le porteur de sens est donc le **mot**, et il reste ; la couleur n'était qu'un rappel.
   * Texte anthracite sur ce fond : 16,11:1, mesuré. */
  --reserve-fond: #eef1f6;

  --fond: var(--blanc);
  --surface: #f6f6f8;
  --texte: var(--anthracite);
  --texte-doux: #5e616c;    /* 6,2:1 sur blanc — le seul gris */
  /* Il y avait un second gris, #676977, à onze points du premier : personne ne les
     distinguait, et les deux étaient à maintenir. Le nom survit, la valeur non. */
  --texte-tenu: var(--texte-doux);
  --trait: rgba(20, 21, 25, 0.10);
  /* **Ce jeton portait un contraste faux, et c'est le lot `P2-63` qui l'a calculé.** Son
   * commentaire annonçait « 3,0:1 » ; #9ea1ad vaut **2,58:1** sur blanc, sous le seuil de 3:1
   * des éléments d'interface. C'est exactement ce que le parti pris 5 interdit — *un contraste
   * déclaré n'est pas un contraste calculé* —, et la valeur est corrigée plutôt que le
   * commentaire : #8a8d99 vaut **3,31:1**, mesuré, et tient le seuil. */
  --trait-forte: #8a8d99;
  --controle: #6e7180;      /* contour des champs : **4,84:1** mesuré — le commentaire annonçait 4,3:1, il sous-estimait */
  --survol: var(--surface);
  --accent: var(--action);
  --accent-sombre: var(--action-survol);
  --attention: #8a5a12;
  --erreur: #a12222;

  /* ---- Mesure : trois largeurs, et tout s'y range ----
   *
   * La page d'actualité faisait défiler **onze largeurs de colonne** différentes, de 39 à
   * 148 caractères par ligne, dont une seule dans la bande lisible de 60 à 75. Ce n'était
   * pas une mise en page : c'était un conteneur de 1120 px dans lequel des blocs avaient
   * été lâchés, chacun prenant la largeur que son composant lui donnait.
   *
   * Désormais tout ce qui se lit tient dans `--l-texte`. Ce qui en sort — une figure, un
   * tableau, une grille de cartes — en sort **délibérément**, par `--l-appui` ou par la
   * pleine largeur, jamais par accident.
   */
  /* ---- Les couleurs de sens — une couleur, un sens, partout ----
   *
   * Parti pris 3 de la direction artistique, repris de GOV.UK : « don't assign new meanings to
   * colours ». Ces quatre-là qualifient **une relation entre une pièce et une affirmation**, et
   * rien d'autre. Chacune porte son rapport de contraste sur blanc, **calculé** par
   * « verifier-systeme-visuel » et non déclaré ici de mémoire.
   *
   * **La couleur n'est jamais le seul porteur** : le type de la relation est écrit en toutes
   * lettres dans la page — « <p class="relation__etat">Étaye</p> » —, et c'est ce qui permet de
   * changer l'ambre sans rien perdre. Mesuré : 35 pages servies portent « relation--contextualise ».
   */
  --sens-etaye: #2f7d4f;            /* 5,04:1 — la pièce appuie l'affirmation */
  --sens-fragilise: #b4452a;        /* 5,49:1 — la pièce l'affaiblit */
  --sens-contextualise: #2b6a8f;    /* 5,90:1 — `AB8` : remplace l'ambre #8a6d1f (4,90:1), plus froid ET plus contrasté */
  --sens-indetermine: #6e7180;      /* 4,84:1 — la pièce ne permet pas de conclure */
  --sens-absence: #9ea1ad;          /* le gris d'un maillon absent ; jamais porteur seul */

  --l-texte: 66ch;          /* la colonne de lecture : ~62 à 68 signes par ligne */
  --l-appui: 860px;         /* le cran au-dessus : figures, tableaux, cartes */
  --l-page: 1120px;         /* la pleine largeur du conteneur */
  --largeur: var(--l-page);
  --mesure: var(--l-texte);
  --marge-page: clamp(16px, 4vw, 32px);
  --pile-s: var(--e-2);
  --pile-m: var(--e-4);
  --pile-l: var(--e-6);
  --pile-xl: var(--e-12);
}

/*
 * L'apparat de preuve. Une seule classe, employée partout où le portail montre
 * ce qu'il a relevé : un chiffre, une date, une version, un identifiant de source,
 * une qualification. Les chiffres y ont une chasse fixe et s'alignent en colonne.
 */
.apparat {
  font-family: var(--police-apparat);
  font-size: var(--t-12);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}
.apparat--majuscules {
  text-transform: uppercase;
  font-weight: 600;
  letter-spacing: 0.08em;
}


/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--police);
  font-size: var(--t-17);
  line-height: 1.55;
  color: var(--texte);
  background: var(--fond);
  -webkit-font-smoothing: antialiased;
  overflow-wrap: break-word;
}

/*
 * Deux voix, une seule écriture.
 *
 * Le document parle en serif : titres d'articles, de dossiers et de sections — ce qui se
 * lit. L'instrument parle en sans : libellés, commandes, tableaux — ce qui s'actionne.
 * La distinction n'est pas décorative : elle dit au lecteur, avant qu'il lise, s'il a
 * devant lui un texte ou un outil.
 */
h1, h2, h3, h4 { margin: 0; }
h1, h2 {
  font-family: var(--police-titre);
  font-weight: 400;
  line-height: 1.06;
  letter-spacing: -0.01em;
}
h3, h4 { line-height: 1.2; letter-spacing: -0.01em; font-weight: 600; }

/* ================= Les classes de titre partagées =================
 *
 * Elles vivaient dans `dossier.css`, et **cinq pages d'outil les emploient sans
 * charger cette feuille** : la section « Comprendre les mots de cet outil » de
 * `budgets.html`, `lois.html`, `promesses.html` et deux autres. Leur taille y
 * venait donc du navigateur — un `h2` sans règle rend 1,5 em, soit 25,5 px, qui
 * n'est aucun jeton de l'échelle.
 *
 * Le piège s'est refermé **trois fois** pendant ce chantier, sur trois classes
 * différentes, et chaque fois pour la même raison : une classe partagée
 * déclarée dans une feuille qui ne l'est pas. Elles sont donc ici, dans la
 * feuille que **toutes** les pages chargent, et non recopiées d'une feuille à
 * l'autre. `dossier.css` garde ce qui lui appartient vraiment.
 *
 * Le palier est celui de D14 : un jeton de chaque côté de 960 px, jamais une
 * valeur intermédiaire.
 */
.dossier__h2 { font-size: var(--t-21); letter-spacing: -0.01em; }
.dossier__h3 { font-size: var(--t-17); letter-spacing: -0.01em; }
.dossier__legende { margin-top: var(--e-2); font-size: var(--t-15); color: var(--texte-tenu); }
@media (min-width: 960px) {
  .dossier__h2 { font-size: var(--t-27); }
  .dossier__h3 { font-size: var(--t-21); }
}

/* ================= D8 — les lignes de lien =================
 *
 * Mesuré le 5 octobre 2026 : `pieces.html` servait 1 184 liens, tous soulignés,
 * `dossiers.html` 81 sur 81. Quatre-vingt-un soulignements d'affilée ne
 * distinguent plus rien.
 *
 * La règle générale ne bouge pas : **un lien dans une phrase se souligne**,
 * c'est ce qui le signale à qui ne distingue pas la couleur d'accent. Seules
 * les **lignes de lien** perdent le trait — un lien qui occupe à lui seul sa
 * ligne n'a pas besoin d'être souligné pour être reconnu.
 *
 * Et aucune ne le perd sans recevoir autre chose : la flèche sortante que
 * `.piece__original` portait déjà dans son texte, une flèche de retour, un
 * chevron de titre. Les repères ajoutés portent un texte de remplacement vide,
 * pour qu'un lecteur d'écran ne les annonce pas — un ornement n'est pas un mot.
 * Le trait revient au survol comme au focus.
 */
.piece__original a, .piece-retour a, .dossier__index-titre a { text-decoration: none; }
.piece__original a:hover, .piece-retour a:hover, .dossier__index-titre a:hover,
.piece__original a:focus-visible, .piece-retour a:focus-visible, .dossier__index-titre a:focus-visible {
  text-decoration: underline;
  text-decoration-color: currentColor;
}
.piece-retour a::before { content: "← " / ""; }
.dossier__index-titre a::after { content: " ›" / ""; }

/*
 * Les deux index du portail — dossiers et actualités — partagent ces classes,
 * et l'un des deux ne charge pas `dossier.css`. Quatrième fois que le même
 * piège se referme dans ce chantier : la liste des actualités servait ses
 * puces de navigateur, parce que le « list-style: none » était dans la feuille
 * que cette page ne charge pas.
 */
/*
 * D7 — une entrée d'index n'est ni une réserve ni une qualification.
 *
 * Les dix entrées de `dossiers.html` étaient dix cadres arrondis, et c'est le
 * fond du défaut : quand tout est encadré, l'encadrement ne distingue plus
 * rien. Le modèle que le dépôt réserve au cadre est ailleurs — le bloc
 * « Période / Portée / Limite » d'une page de dossier, qui porte une
 * qualification. Un index se compose par l'espace et le filet.
 *
 * Les deux index y gagnent la même apparence : `actualites.html` n'avait
 * aucun cadre parce qu'il ne charge pas `dossier.css`, et c'était une
 * incohérence, pas une décision.
 */
.dossier__index { list-style: none; margin: 0; padding: 0; display: grid; }
.dossier__index-fiche { padding: var(--e-6) 0; border-bottom: 1px solid var(--trait); }
.dossier__index-fiche:last-child { border-bottom: 0; }
p { margin: 0; }
img { max-width: 100%; height: auto; }

/*
 * Un lien de corps de texte se souligne — c'est ce qui le rend repérable sans la couleur,
 * donc lisible par qui ne distingue pas le violet. Mais le trait plein et sombre d'un
 * navigateur par défaut hache la ligne : il est posé à 35 %, et se referme au survol.
 */
a { color: var(--accent); text-decoration-color: color-mix(in srgb, var(--accent) 35%, transparent); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--accent-sombre); text-decoration-color: currentColor; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: var(--r-s);
}

.lien-evitement {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--texte);
  color: var(--blanc);
  padding: var(--e-3) var(--e-4);
  border-radius: 0 0 var(--r-s) 0;
  font-weight: 600;
}
.lien-evitement:focus { left: 0; color: var(--blanc); }

.enveloppe {
  width: 100%;
  max-width: var(--largeur);
  margin-inline: auto;
  padding-inline: var(--marge-page);
}

.visuellement-cache {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- En-tête ---------- */
.entete {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255, 255, 255, .9);
  backdrop-filter: saturate(180%) blur(16px);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  border-bottom: 1px solid var(--trait);
}

/*
 * Une seule rangée, à toutes les largeurs.
 *
 * L'en-tête se repliait : 68 px sur ordinateur, et **194 px sur téléphone** — 23 % du
 * premier écran avant le premier mot, à force d'empiler l'identité, la recherche, la
 * navigation sur deux lignes et un bouton isolé. Il grossissait quand l'écran
 * rétrécissait, c'est-à-dire exactement à l'envers.
 *
 * La navigation défile désormais à l'horizontale quand elle ne tient pas, ce qui tient
 * en une rangée sans rien cacher et sans demander de JavaScript — donc y compris sur les
 * quarante-deux versions figées, dont le balisage ne se réécrit pas.
 */
.entete__rangee {
  display: flex;
  align-items: center;
  gap: var(--pile-m);
  min-height: 60px;
  flex-wrap: nowrap;
  /* `nowrap` ici aussi : c'est le repli de cette rangée qui fabriquait les cinq étages. */
  padding-block: var(--e-2);
}

/* Marque : symbole en tracés SVG et nom en texte, police système. Le mot-symbole
   SVG du kit contient lui aussi du texte : l'écrire en HTML garde le même rendu
   de repli, reste lisible par tous et ne dépend d'aucune police téléchargée. */
.marque {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  font-weight: 700;
  font-size: var(--t-27);
  line-height: 1;
  color: var(--texte);
  text-decoration: none;
  letter-spacing: -0.055em;
  white-space: nowrap;
}
.marque:hover { color: var(--texte); }
.marque__symbole { width: 31px; height: 32px; flex: none; }
.marque__nom { translate: 0 -1px; }
/* Précision discrète après le nom (administration). */
.marque__mention { margin-inline-start: var(--e-1); font-size: var(--t-13); font-weight: 500; letter-spacing: 0; color: var(--texte-tenu); }
.marque:focus-visible { outline-offset: 4px; }

.navigation { margin-inline-start: auto; }
/*
 * Une rangée, de 320 à 1920, et cette fois c'est mesuré.
 *
 * La règle précédente ne s'appliquait que sous 700 px — et la feuille se félicitait en
 * commentaire d'une « seule rangée à toutes les largeurs » qui n'existait nulle part :
 * deux rangées à 1440, **cinq à 768**, trois à 390. Un commentaire n'est pas une règle.
 * La navigation ne se replie plus jamais : elle défile, à toutes les largeurs.
 */
.navigation { min-width: 0; overflow-x: auto; scrollbar-width: none;
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
  mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent); }
.navigation::-webkit-scrollbar { display: none; }
.navigation__liste {
  display: flex;
  align-items: center;
  gap: var(--e-1);
  list-style: none;
  margin: 0;
  padding: 0;
  flex-wrap: nowrap;
}
/*
 * La page courante se marque par un trait, non par une pastille violette pleine.
 *
 * La pastille datait l'interface à elle seule, et elle employait la couleur d'action pour
 * dire un état : le violet désignait alors cinq choses à la fois — la page courante, les
 * liens, les flèches, les boutons et les chiffres —, donc plus aucune. L'état se lit
 * toujours autrement que par la couleur seule : ici le poids du trait et la graisse.
 */
.navigation__lien {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: var(--e-2) var(--e-1);
  margin-inline: var(--e-2);
  color: var(--texte-doux);
  text-decoration: none;
  font-size: var(--t-15);
  border-radius: 0;
  border-bottom: 2px solid transparent;
  white-space: nowrap;
}
.navigation__lien:hover { color: var(--texte); background: none; border-bottom-color: var(--trait-forte); }
.navigation__lien[aria-current="page"] { color: var(--texte); font-weight: 600; border-bottom-color: var(--texte); }
.navigation__lien[aria-current="page"]:hover { border-bottom-color: var(--texte); }

.recherche { display: flex; align-items: center; gap: var(--e-2); }
.recherche__champ {
  font: inherit;
  font-size: var(--t-15);
  padding: var(--e-2) var(--e-4);
  min-height: 38px;
  min-width: 0;
  width: clamp(140px, 22vw, 240px);
  border: 1px solid var(--controle);
  border-radius: var(--r-s);
  background: var(--fond);
  color: var(--texte);
}
.recherche__champ::placeholder { color: var(--texte-tenu); }
.recherche__champ:focus { border-color: var(--action); }
/*
 * Le bouton de recherche de l'en-tête — défaut D4 du registre.
 *
 * Il portait « visuellement-cache » : 1 × 1 px, rogné par `clip:rect(0,0,0,0)`, et
 * **focusable**. La tabulation s'y arrêtait sans que rien ne se voie, et mesuré le
 * 2 octobre 2026 sur `polideo.fr` il faisait bien 1 × 1 px avec son rognage.
 *
 * Il est désormais visible à toutes les largeurs. Son contour n'a pas été retiré :
 * c'est la taille qui était le défaut, pas le repère de focus. Le nom accessible reste
 * un **mot**, porté par un texte caché à l'intérieur du bouton : une loupe seule ne se
 * lit pas, et le bouton, lui, se voit.
 */
.recherche__bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 38px;
  min-height: 38px;
  padding: 0;
  border: 1px solid var(--controle);
  border-radius: var(--r-s);
  background: var(--fond);
  color: var(--texte-doux);
  cursor: pointer;
}
.recherche__bouton:hover { color: var(--texte); border-color: var(--trait-forte); }
.recherche__loupe { display: block; }

/* ---------- Boutons ---------- */
.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-2);
  font: inherit;
  font-size: var(--t-15);
  font-weight: 500;
  min-height: 44px;
  padding: var(--e-2) var(--e-4);
  /* La pastille entièrement arrondie est ce qui datait le plus l'interface. Elle ne
     reste que sur la qualification, où la forme porte une information. */
  border-radius: var(--r-s);
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: background-color .12s ease, border-color .12s ease, color .12s ease;
}
.bouton--principal { background: var(--accent); color: var(--blanc); }
.bouton--principal:hover { background: var(--accent-sombre); color: var(--blanc); }
.bouton--secondaire { background: var(--fond); color: var(--texte); border-color: var(--trait-forte); }
.bouton--secondaire:hover { background: var(--survol); color: var(--texte); }
.bouton--discret { background: transparent; color: var(--accent); padding-inline: var(--e-2); }
.bouton--discret:hover { background: var(--survol); }
.bouton[disabled], .bouton[aria-disabled="true"] {
  background: var(--fond);
  color: var(--texte-tenu);
  border-color: var(--trait);
  cursor: not-allowed;
}

/* ---------- Sections ---------- */
.section { padding-block: var(--pile-xl); }
.section--doux { border-top: 1px solid var(--trait); }
.section--serre { padding-block: var(--e-8); }

.section__entete {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--pile-m);
  flex-wrap: wrap;
  margin-bottom: var(--pile-l);
}
/* Les clamp() en vw produisaient 25,5 px et 51,84 px — deux tailles qui n'existent
   dans aucune échelle, et cinq vitesses de croissance différentes selon le niveau. */
.section__titre { font-size: var(--t-27); }
.section__intro {
  margin-top: var(--e-1);
  color: var(--texte-doux);
  font-size: var(--t-17);
  max-width: 62ch;
}

/* Un fil qui n'a pas bougé depuis plus de deux semaines le dit, et se lit.
   La couleur ne porte pas seule l'information : la phrase donne la date et
   le nombre de jours, et reste compréhensible sans voir la nuance. */
.section__intro--alerte {
  color: var(--texte);
  font-weight: 500;
}

/* ---------- Bandeau d'ouverture ---------- */
.ouverture { padding-block: var(--e-8) 0; }
.section--une { padding-block: var(--e-6) var(--e-12); }
.ouverture__titre {
  font-size: var(--t-44);
  letter-spacing: -0.05em;
  font-weight: 650;
}
.ouverture__texte {
  margin-top: var(--e-2);
  color: var(--texte-doux);
  font-size: var(--t-15);
  max-width: 64ch;
}

/* ---------- Mentions et étiquettes ----------
   Étiquettes de statut : texte discret cerné d'un trait fin, sans remplissage
   de couleur. Une couleur de texte peut porter un sens (attention, erreur) sans
   devenir une surface. */
.mention {
  display: inline-flex;
  align-items: center;
  font-size: var(--t-12);
  line-height: 1.3;
  padding: var(--e-1) var(--e-2);
  border-radius: var(--r-s);
  border: 1px solid var(--trait);
  background: var(--fond);
  color: var(--texte-doux);
  white-space: nowrap;
}
.mention--attention { color: var(--attention); border-color: var(--attention); }
.mention--erreur { color: var(--erreur); border-color: var(--erreur); }

.encart {
  border: 1px solid var(--trait);
  background: var(--fond);
  border-radius: var(--r-m);
  padding: var(--e-3) var(--e-4);
  font-size: var(--t-15);
  color: var(--texte-doux);
}
.encart__titre { font-weight: 600; color: var(--texte); display: block; margin-bottom: var(--e-1); font-size: var(--t-15); }
.encart__note { display: block; margin-top: var(--e-2); font-size: var(--t-15); color: var(--attention); }
/* Un relevé périmé n'est pas une alerte sur les sources : il ne dit plus rien
   d'elles. Il garde la taille de la note et perd la couleur d'attention, pour
   ne pas signaler un danger que les données n'établissent pas. */
.encart__note--perime { color: var(--texte-doux); }

/* ---------- Les trois horloges du fil, servies dans le document ---------- */
/*
 * Elles ne s'affichaient que sur l'accueil, et qu'avec JavaScript. Elles sont
 * désormais servies sur les deux pages où le fil se lit, et le bloc est lisible
 * sans script : il porte les trois dates et la date depuis laquelle le fil est
 * en retard. Le nombre de jours, lui, est ajouté à l'ouverture — gravé dans un
 * octet servi, il serait juste un jour et faux le lendemain.
 *
 * Aucune couleur ne porte seule l'information : la phrase du retard nomme son
 * maillon et donne sa date, et se lit sans distinguer la nuance.
 */
.horloges { margin-block: var(--e-4); }
.horloges__retard { margin: 0; font-weight: 600; color: var(--texte); font-size: var(--t-15); }
.horloges__retard--alerte { font-weight: 600; color: var(--texte); text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 3px; }
.horloges__liste { list-style: none; margin: var(--e-2) 0 0; padding: 0; display: grid; gap: var(--e-1); }
.horloges__liste li { font-size: var(--t-15); color: var(--texte); min-width: 0; overflow-wrap: anywhere; }
/* La glose dit de quoi la date est la date : elle est tenue, jamais retirée. */
.horloges__quoi { display: block; font-size: var(--t-13); color: var(--texte-doux); }
/* L’écart entre la date servie et celle du fil vivant : dit, jamais substitué — BE8. */
.horloges__ecart { display: block; font-size: var(--t-13); color: var(--texte-doux); font-style: italic; }
.horloges__regle { margin: var(--e-2) 0 0; font-size: var(--t-15); color: var(--texte-doux); max-width: var(--l-texte); }

/* ---------- Cartes d'actualité ---------- */
/*
 * Le trou de neuf cents pixels.
 *
 * La une faisait 451 px de haut, sa colonne voisine 1 362 : avec « align-items: start »,
 * la moitié gauche de l'écran restait blanche sur plus de neuf cents pixels pendant que
 * la droite continuait. Ce n'est pas une respiration, c'est une colonne qui s'arrête, et
 * l'œil lit « page cassée ». Les deux colonnes s'étirent désormais ensemble, et la une
 * répartit son contenu sur la hauteur qu'elle occupe.
 */
.une {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
  gap: var(--e-12);
  align-items: stretch;
}
.carte--une { display: flex; flex-direction: column; justify-content: space-between; }

/* D7 du registre, corrigé le 5 octobre 2026 — une carte du fil n'est pas une réserve.
 *
 * Chaque article du fil était enfermé dans un cadre complet. Quand tout est
 * encadré, le cadre ne distingue plus rien : la réserve éditoriale que la carte
 * contient (« carte__reserve ») portait le même contour que la carte entière.
 * La règle retenue, celle de l'annuaire livré au chantier 5 : un filet sépare,
 * un cadre qualifie. La carte se compose maintenant par l'espace et le filet ;
 * le cadre reste aux réserves, aux encarts et aux panneaux.
 *
 * Le contour portait aussi deux fonctions qu'il faut rendre autrement, sinon la
 * composition s'améliore en cassant l'usage : le survol (« border-color »
 * renforcée) et le repère de focus clavier. Le survol passe par le soulignement
 * du titre, déjà en place sur « carte__lien » ; le focus par un « outline »,
 * qui se voit sans bordure — c'est l'idiome de « annuaire-territoire__titre ».
 */
.carte {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  background: var(--fond);
  border: 0;
  border-bottom: 1px solid var(--trait);
  border-radius: 0;
  padding: var(--e-4) 0;
}
.carte:hover { border-bottom-color: var(--trait-forte); }
/* Un filet ferme une liste sans la clore : sous la dernière carte il ne sépare
   plus rien, il souligne le vide. Même geste que « budget-carte:last-child ». */
.fil .carte:last-child { border-bottom: 0; }
.carte:has(.carte__lien:focus-visible),
.carte--une:has(.carte__lien:focus-visible) { outline: 2px solid var(--accent); outline-offset: 3px; }

/* La une seule reçoit la teinte légère de Polideo, sans contour : le reste du
   contenu reste sur blanc. */
.carte--une { padding: clamp(22px, 3vw, 32px); background: var(--teinte); border: 0; border-radius: var(--r-l); }
.carte--une:hover { border-color: transparent; }
.carte--une .carte__titre { font-size: var(--t-27); letter-spacing: -0.01em; line-height: 1.06; }
.carte--une .carte__resume { font-size: var(--t-17); }

.carte__meta {
  display: flex;
  align-items: center;
  gap: var(--e-1);
  flex-wrap: wrap;
  font-size: var(--t-13);
  color: var(--texte-tenu);
}
.carte__point { color: var(--trait-forte); }

.carte__titre { font-size: var(--t-21); letter-spacing: -0.015em; }
.carte__lien { color: inherit; text-decoration: none; }
.carte__lien:hover { color: var(--accent-sombre); text-decoration: underline; }
.carte__lien::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
/*
 * **Défaut D5 du registre.** Ce lien s'étire sur toute la carte, et il recouvrait donc les
 * commandes qu'une carte porte. Sur `budgets.html`, carte « Enseignement scolaire »,
 * mesuré sur `polideo.fr` le 2 octobre 2026 : au centre du bouton « Comparer »,
 * `document.elementFromPoint` rendait `A.carte__lien` et non le bouton. Conséquence, plus
 * large que ce que le registre annonçait — **la souris et le doigt** ouvraient
 * `?mission=enseignement-scolaire`, la fiche, quand la touche Entrée sur le même bouton
 * ouvrait `?comparer=enseignement-scolaire`. Une commande faisait deux choses selon le
 * dispositif.
 *
 * **Pourquoi certaines cartes n'étaient pas touchées, et pourquoi c'est le vrai défaut.**
 * Les puces de thème de l'accueil sont, elles, atteignables — mais seulement parce
 * qu'elles viennent **après** le lien dans le document, donc se peignent au-dessus à
 * égalité d'empilement. Le comportement dépendait de l'ordre du balisage, ce que rien
 * n'écrit ni ne vérifie : le bouton des budgets vient avant son lien, et il disparaissait.
 *
 * Le remède tient en deux déclarations, et il ne dépend plus d'aucun ordre. La carte forme
 * son propre contexte d'empilement, pour qu'aucun `z-index` posé ici ne déborde sur la
 * page ; **toute** commande d'une carte passe au-dessus du lien étendu, qu'elle soit
 * écrite avant ou après lui. Les cartes gardent donc leur surface cliquable, et les
 * commandes restent atteignables aux trois dispositifs.
 *
 * Ce que cette règle ne garantit pas à elle seule : qu'une commande d'un genre non prévu
 * ici reste atteignable. C'est pourquoi `recette-navigateur-cartes.mjs` **mesure**, sur
 * chaque carte de chaque page servie, que le centre de chaque commande touche bien la
 * commande, et que le coin de la carte touche bien le lien. Une carte qui gagnera demain
 * un contrôle d'un autre genre fera échouer cette recette au lieu de rejouer D5 en silence.
 */
.carte { isolation: isolate; }
.carte__lien::after { z-index: 0; }
.carte :is(button, input, select, textarea, label, [role="button"], a:not(.carte__lien)) {
  position: relative;
  z-index: 1;
}

.carte__resume { color: var(--texte-doux); font-size: var(--t-15); }

/* Réserves et notes : texte simple sur fond blanc, sans encart ni trait
   vertical d'accent — la clarté vient de la ponctuation et de l'espacement. */
.carte__reserve { font-size: var(--t-15); color: var(--texte-doux); }
.carte__reserve--attention { color: var(--attention); }
.carte__fiabilite { font-size: var(--t-13); color: var(--texte-tenu); }

/* Les détails doivent recevoir les clics au-dessus du lien étendu de la carte. */
.carte__details { position: relative; z-index: 1; font-size: var(--t-13); }
.carte__details summary {
  cursor: pointer;
  color: var(--texte-tenu);
  list-style: none;
}
.carte__details summary::-webkit-details-marker { display: none; }
.carte__details summary::before { content: "Afficher — "; }
.carte__details[open] summary::before { content: "Masquer — "; }
.carte__details summary:hover { color: var(--texte-doux); }
.carte__details p { margin-top: var(--e-1); color: var(--texte-doux); }

.carte__bas {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-3);
  flex-wrap: wrap;
  margin-top: auto;
  padding-top: var(--e-1);
}

.carte__destination {
  font-size: var(--t-13);
  color: var(--texte-tenu);
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  min-width: 0;
}
.carte__domaine {
  font-variant-numeric: tabular-nums;
  color: var(--texte-doux);
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Les tags restent cliquables au-dessus de la zone de lien de la carte.
   Contrôles compacts : texte 13 px, faible padding, rayon réduit — la sélection
   se lit au trait et au poids du texte, jamais à un remplissage de couleur. */
.tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-2);
  position: relative;
  z-index: 1;
}
.tag {
  font: inherit;
  font-size: var(--t-13);
  line-height: 1.3;
  padding: var(--e-1) var(--e-2);
  border-radius: var(--r-s);
  border: 1px solid var(--trait);
  background: var(--fond);
  color: var(--texte-doux);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color .12s ease, color .12s ease;
}
.tag:hover { border-color: var(--texte-tenu); color: var(--texte); }
.tag[aria-pressed="true"] {
  border-color: var(--action);
  color: var(--action);
  font-weight: 600;
}

/* ---------- Barre de filtres ---------- */
.filtres {
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
  padding: var(--e-4);
  border: 1px solid var(--trait);
  border-radius: var(--r-l);
  background: var(--fond);
}
.filtres__groupe { display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap; }
.filtres__intitule {
  font-size: var(--t-13);
  font-weight: 600;
  color: var(--texte-tenu);
  text-transform: uppercase;
  letter-spacing: .06em;
  min-width: 86px;
}
.filtres__barre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-3);
  flex-wrap: wrap;
  border-top: 1px solid var(--trait);
  padding-top: var(--e-3);
}
.filtres__compte { font-size: var(--t-15); color: var(--texte-doux); }
/* Le champ de recherche du fil : il filtre le fil, et seulement lui. */
.filtres__recherche { display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap; }
.filtres__recherche .champ { min-height: 38px; width: clamp(140px, 24vw, 240px); }

.jeton {
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  font-size: var(--t-13);
  padding: var(--e-1) var(--e-1) var(--e-1) var(--e-2);
  border-radius: var(--r-s);
  background: var(--fond);
  color: var(--texte);
  border: 1px solid var(--trait);
}
.jeton__retrait {
  font: inherit;
  line-height: 1;
  border: 0;
  background: transparent;
  color: var(--texte-doux);
  cursor: pointer;
  padding: var(--e-1) var(--e-1);
  border-radius: var(--r-s);
  font-size: var(--t-15);
}
.jeton__retrait:hover { background: var(--survol); color: var(--texte); }

/* ---------- Fil ---------- */
.fil {
  display: grid;
  gap: var(--pile-m);
  margin-top: var(--pile-l);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
}

.etat {
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--fond);
  padding: var(--e-6);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e-2);
  margin-top: var(--pile-l);
}
.etat--erreur { border-color: var(--erreur); }
.etat--erreur .etat__titre { color: var(--erreur); }
.etat__titre { font-size: var(--t-21); }
.etat__texte { color: var(--texte-doux); font-size: var(--t-15); max-width: 56ch; }
.etat__detail {
  font-size: var(--t-13);
  color: var(--texte-tenu);
  font-family: var(--police-apparat);
  word-break: break-word;
}

.bandeau-apercu {
  background: var(--fond);
  border-bottom: 1px solid var(--trait);
  color: var(--texte);
  font-size: var(--t-15);
}
.bandeau-apercu__rangee {
  display: flex;
  align-items: center;
  gap: var(--e-3);
  flex-wrap: wrap;
  padding-block: var(--e-2);
}

/* ---------- Grilles de services ---------- */
.grille {
  display: grid;
  gap: var(--pile-m);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
}

.service {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--e-2);
  padding: var(--e-4);
  border: 1px solid var(--trait);
  border-radius: var(--r-l);
  background: var(--fond);
}
.service:hover { border-color: var(--trait-forte); }
.service__titre { font-size: var(--t-17); }
.service__lien { color: inherit; text-decoration: none; }
.service__lien:hover { color: var(--accent-sombre); }
.service__lien::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.service__texte { color: var(--texte-doux); font-size: var(--t-15); }
.service__limite {
  font-size: var(--t-13);
  color: var(--texte-tenu);
  border-top: 1px solid var(--trait);
  padding-top: var(--e-2);
  margin-top: auto;
}
.service__haut { display: flex; align-items: center; gap: var(--e-2); flex-wrap: wrap; }

/* ---------- Colonnes bas de page ---------- */
.colonnes {
  display: grid;
  gap: var(--pile-l);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  align-items: start;
}

.panneau {
  border: 1px solid var(--trait);
  border-radius: var(--r-l);
  background: var(--fond);
  padding: var(--e-6);
  display: flex;
  flex-direction: column;
  gap: var(--e-3);
}
.panneau__titre { font-size: var(--t-21); }
.panneau__texte { color: var(--texte-doux); font-size: var(--t-15); }

/* ---------- FAQ ---------- */
/* D7 — une question de la FAQ est une entrée de liste, pas une réserve.
 * Même conversion que la carte : le cadre complet devient un filet de
 * séparation, et le texte s'aligne sur la colonne de lecture au lieu d'être
 * retiré de 24 px par le rembourrage du cadre. Le pliage se lit déjà au
 * « + » / « − » ; l'état ouvert se marque par le filet renforcé. */
.faq { display: grid; }
.faq__entree {
  border: 0;
  border-bottom: 1px solid var(--trait);
  background: var(--fond);
}
.faq__entree[open] { border-bottom-color: var(--trait-forte); }
.faq__question {
  cursor: pointer;
  padding: var(--e-3) 0;
  font-weight: 600;
  font-size: var(--t-17);
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e-3);
}
.faq__question::-webkit-details-marker { display: none; }
.faq__question::after {
  content: "+";
  font-size: var(--t-21);
  font-weight: 400;
  color: var(--texte-tenu);
  line-height: 1;
}
.faq__entree[open] .faq__question::after { content: "\2212"; }
.faq__reponse { padding: 0 0 var(--e-4); color: var(--texte-doux); font-size: var(--t-15); }
.faq__reponse p + p { margin-top: var(--e-2); }

/* ---------- Formulaire non connecté ---------- */
.formulaire { display: flex; flex-direction: column; gap: var(--e-2); }
.formulaire__rangee { display: flex; gap: var(--e-2); flex-wrap: wrap; }
.champ {
  font: inherit;
  font-size: var(--t-15);
  flex: 1 1 220px;
  min-width: 0;
  padding: var(--e-2) var(--e-3);
  border: 1px solid var(--controle);
  border-radius: var(--r-m);
  background: var(--fond);
  color: var(--texte);
}
.champ[disabled] { color: var(--texte-tenu); cursor: not-allowed; background: var(--survol); }
/* D15 : l'aide d'un formulaire explique pourquoi un champ est désactivé — une
   phrase à lire au moment où l'on bute, pas une note de bas de carte. */
.formulaire__aide { font-size: var(--t-15); color: var(--texte-tenu); }

/* ---------- Liste de faits ---------- */
.liste-faits { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--e-2); }
.liste-faits li {
  display: flex;
  gap: var(--e-2);
  align-items: baseline;
  font-size: var(--t-15);
  color: var(--texte-doux);
}
.liste-faits li::before { content: "\2014"; color: var(--trait-forte); flex: none; }
/* Une adresse longue et insécable élargissait la ligne au-delà de la fenêtre sur
   mobile, et faisait défiler toute la page de côté. Un élément flex ne se réduit
   pas sous sa largeur de contenu tant que « min-width » vaut « auto ». */
.liste-faits li, .liste-faits li > * { min-width: 0; overflow-wrap: anywhere; }

/* ---------- Pied de page ---------- */
.pied__marque { margin-bottom: var(--pile-l); font-size: var(--t-21); }
.pied__marque .marque__symbole { width: 27px; height: 28px; }
.pied {
  border-top: 1px solid var(--trait);
  padding-block: var(--e-8) var(--e-8);
  font-size: var(--t-15);
  color: var(--texte-doux);
}
/*
 * Le pied tient ses colonnes sur une rangée. D9, puis `AP1`.
 *
 * **L'histoire de ce bloc est celle d'un nombre qu'on rattrape.** La grille a
 * demandé 200 px au minimum par colonne, ce qui faisait entrer quatre colonnes
 * dans les 1 056 px de l'enveloppe ; le regroupement en a créé cinq, et la
 * cinquième tombait sur une seconde rangée. On a baissé le minimum à 168 px,
 * « le minimum qui laisse entrer cinq colonnes ». Puis `P2-65` a ajouté l'Agora,
 * et le sixième groupe est retombé sur une seconde rangée — mesuré le 16 octobre
 * 2026 dans un navigateur, à 1100, 1430, 1440 et 1920 px : **5 pistes de 188 ou
 * 192 px pour 6 groupes et 31 entrées**, donc deux rangées et quatre cases vides.
 * C'est `AP1`.
 *
 * **Baisser le minimum une troisième fois aurait été la même faute.** La cause
 * n'est pas la valeur : c'est qu'`auto-fit` choisit son nombre de pistes d'après
 * la largeur disponible **sans jamais regarder combien de groupes il doit
 * tenir**. Un nombre figé qui marche pour six ne marche pas pour sept, et rien
 * ne le dirait — c'est la famille `N15`.
 *
 * **Le nombre de colonnes vient donc du nombre d'enfants, et il n'est écrit
 * nulle part.** `grid-auto-flow: column` crée une piste implicite par groupe et
 * les range sur une rangée ; `grid-auto-columns: minmax(0, 1fr)` les fait égales.
 * Il n'y a plus de nombre à tenir à jour : un septième groupe produit une
 * septième colonne sans que personne y pense.
 *
 * *Une première écriture passait ce compte par un `style="--pied-groupes: 6"` sur
 * la grille. `verifier-coque` l'a refusée sur les **312 pages servies** : la
 * politique de sécurité du portail interdit l'attribut `style`. Le garde-fou
 * avait raison, et la réparation qu'il a forcée est meilleure que celle qu'il a
 * refusée — elle ne compte plus rien du tout.*
 *
 * Deux états seulement, et c'est délibéré : autant de colonnes que de groupes sur
 * une rangée au-dessus du seuil, **une** colonne en dessous. Aucun palier
 * intermédiaire, donc aucune rangée incomplète possible à aucune largeur — un
 * palier à cinq colonnes pour six groupes était exactement le défaut. Mesuré à
 * 700 px avant ce lot : trois pistes pour six groupes, soit deux rangées pleines
 * par chance arithmétique, et un trou dès qu'un septième groupe arriverait.
 *
 * Le seuil est à 1 024 px parce que c'est la largeur sous laquelle la grille se
 * repliait déjà d'elle-même, et parce que les trois largeurs de la recette —
 * 1100, 1440, 1920 — sont toutes au-dessus. À 1 024 px, six pistes font 140 px :
 * `overflow-wrap` est donc posé sur les entrées, pour que l'adresse de contact,
 * qui n'offre aucune coupure naturelle, ne déborde pas de sa colonne.
 */
.pied__grille {
  display: grid;
  gap: var(--pile-l);
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
}
@media (max-width: 1023px) {
  .pied__grille { grid-auto-flow: row; grid-auto-columns: auto; }
}
.pied__titre {
  font-size: var(--t-13);
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--texte-tenu);
  margin-bottom: var(--e-2);
}
.pied__liste { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--e-2); }
/* Une colonne de 140 px doit pouvoir porter une adresse de courriel, qui n'offre
 * aucune coupure naturelle : sans cette ligne, elle sortirait de sa colonne. */
.pied__liste li { overflow-wrap: anywhere; }
.pied__liste a { color: var(--texte-doux); text-decoration: none; }
.pied__liste a:hover { color: var(--accent-sombre); text-decoration: underline; }
.pied__bas {
  margin-top: var(--pile-l);
  padding-top: var(--e-4);
  border-top: 1px solid var(--trait);
  display: flex;
  justify-content: space-between;
  gap: var(--pile-m);
  flex-wrap: wrap;
  font-size: var(--t-13);
  color: var(--texte-tenu);
}

/* ---------- Adaptations ---------- */
@media (max-width: 860px) {
  .une { grid-template-columns: 1fr; }
}

@media (max-width: 700px) {
  body { font-size: var(--t-17); }
  /*
   * Une rangée, et la navigation défile.
   *
   * Elle passait pleine largeur sous la marque, puis se repliait encore : quatre rangées,
   * 194 px. Ici elle tient sur la même ligne et défile horizontalement si elle déborde —
   * rien n'est caché, rien ne demande de JavaScript, et les versions figées en profitent
   * sans que leur balisage change. Le dégradé de droite dit qu'il reste à voir.
   */
  /*
   * Une seule rangée, et c'est non négociable.
   *
   * Elle en a compté quatre — 194 px, 23 % du premier écran —, puis deux, ce qui n'était
   * pas mieux : une barre de navigation qui prend deux étages sur un téléphone prend la
   * place de ce qu'on est venu lire. Ici tout tient sur 52 px. La navigation occupe la
   * largeur restante et défile à l'horizontale ; ce qui informe sans faire naviguer —
   * l'étiquette de bêta, le bouton d'avis — sort de la rangée, et le portail le dit
   * ailleurs. Aucun JavaScript, donc les quarante-deux versions figées en profitent
   * aussi, sans que leur balisage change.
   */
  .entete__rangee { min-height: var(--entete-hauteur); gap: var(--e-3); flex-wrap: nowrap; }
  .marque { font-size: var(--t-17); flex: 0 0 auto; gap: var(--e-2); }
  .marque__symbole { width: 22px; height: 23px; }
  /* « .entete » devant, parce que retours.css est chargée après cette feuille et
     redéclare l'étiquette : à spécificité égale, c'est la dernière qui gagne. */
  .entete .etiquette-beta, .entete .bouton-avis { display: none; }
  .navigation {
    margin-inline-start: 0;
    flex: 1 1 auto;
    min-width: 0;
    overflow-x: auto;
    overscroll-behavior-inline: contain;
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
  }
  .navigation::-webkit-scrollbar { display: none; }
  .navigation__liste { gap: 0; flex-wrap: nowrap; }
  .navigation__lien { min-height: var(--entete-lien-touche); padding: var(--e-2) 0; margin-inline: var(--e-3); font-size: var(--t-15); }
  .navigation__liste > li:first-child .navigation__lien { margin-inline-start: 0; }
  /*
   * La recherche se réduit à sa plus petite taille utile et s'ouvre à la saisie : elle
   * reste atteignable sans manger la rangée. Ce n'est pas une icône décorative — le champ
   * est toujours là, et son étiquette aussi.
   */
  .recherche { flex: 0 0 auto; }
  .recherche__champ { width: 92px; transition: width .14s ease, opacity .14s ease; }
  .recherche__champ:focus { width: var(--entete-recherche-ouverte); }
  /* Le bouton ne rétrécit pas avec le champ : une cible tactile de 1 px n'était
     pas un défaut de style mais le défaut D4 lui-même. */
  .recherche__bouton { width: var(--entete-recherche-repliee); }
  /* Sous 430 px, le mot-symbole cède la place au symbole seul : le lien garde son
     libellé accessible, et la navigation récupère 86 px. */
  @media (max-width: 430px) {
    .marque__nom { display: none; }
    /*
     * **La recherche se replie sur son bouton** — défaut `AB7`, et c'est une mesure qui l'a
     * décidé. Rendu à 320 px avant ce lot : **un seul** des six liens de navigation était
     * visible, les cinq autres demandant de faire glisser une piste dont le seul indice est un
     * dégradé de 24 px. Ils n'étaient pas inatteignables — la piste défile, et c'est un choix
     * assumé — mais une destination sur six, c'est une navigation qu'on ne lit plus.
     *
     * Le champ occupait 29 % de la largeur en permanence pour une recherche qu'on ne fait pas à
     * chaque visite. Replié sur son bouton, il rend cette place à la navigation et **s'ouvre au
     * focus** : il reste atteignable au doigt comme au clavier, son étiquette ne bouge pas, et
     * aucune fonction ne disparaît. La cible tactile du bouton reste entière.
     */
    .recherche__champ {
      width: 0;
      min-width: 0;
      padding-inline: 0;
      border-width: 0;
      opacity: 0;
    }
    .recherche__champ:focus {
      width: var(--entete-recherche-ouverte);
      padding-inline: var(--e-3);
      border-width: 1px;
      opacity: 1;
    }
    /* Le bouton ne se replie pas : c'est lui qui ouvre le champ, et une cible de 1 px était
       le défaut `D4` lui-même. */
    .recherche__bouton { width: var(--entete-recherche-repliee); flex: 0 0 auto; }
  }
  .section { padding-block: var(--e-8); }
  .filtres__intitule { min-width: 100%; }
  .carte { padding: var(--e-4); }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

@media print {
  .entete, .filtres, .recherche { display: none; }
  .carte, .service, .panneau { break-inside: avoid; }
}

/* ---------- Compléments ---------- */
.une__secondaires { display: grid; gap: 0; align-content: start; }
/* Pile secondaire de la une : séparée par des traits fins, sans cadres, pour que
   l'article principal reste la seule surface marquée. */
.une__secondaires .carte { border: 0; border-radius: 0; padding: 0 0 var(--e-6); }
.une__secondaires .carte + .carte { border-top: 1px solid var(--trait); padding-top: var(--e-6); }
.une__secondaires .carte:hover { border-color: var(--trait); }
.une__secondaires .carte:has(.carte__lien:focus-visible) { outline: 2px solid var(--accent); outline-offset: 6px; border-radius: var(--r-s); }
/* « À la une » : intitulé discret ; la une elle-même porte la hiérarchie. */
.section--une .section__entete { margin-bottom: var(--e-4); }
/* « À la une » était rendu en 13 px — un titre de section plus petit que le corps de
   texte qu'il introduit, donc invisible. C'est une étiquette : elle en prend la forme,
   avec son filet, au lieu d'être un titre rapetissé. */
.section--une .section__titre {
  font-family: var(--police-apparat); font-size: var(--t-12); font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--texte-doux);
  padding-top: var(--e-3); border-top: 1px solid var(--texte);
}
.section--une .section__intro { font-size: var(--t-15); margin-top: var(--e-1); }

/* Un lien signalé indisponible n'ouvre plus toute la surface de la carte :
   la lecture reste possible, mais volontairement. */
.carte--indisponible { border-color: var(--erreur); }
.carte--indisponible .carte__lien::after { content: none; }

.espace-haut { margin-top: var(--pile-m); }
.a-droite { margin-inline-start: auto; }
.pagination { margin-top: var(--pile-l); display: flex; justify-content: center; }
.titre-bloc { margin-bottom: var(--pile-m); }

/* ---------- Accueil Polideo : les outils d'abord (lot 11C) ----------
   Décision d'Adam du 17 septembre 2026 : montrer d'abord ce que l'on peut faire,
   l'actualité suit. Les huit accès sont de simples liens écrits dans le HTML,
   utilisables sans JavaScript et sans le fil. Liste compacte séparée par des
   traits fins : ni cartes en relief, ni bordure verticale. La limite de chaque
   corpus est posée sous l'action, en petit texte tenu, pour ne rien promettre de
   plus que ce qui est livré. */
.accueil-outils { padding-block: var(--e-8) var(--e-8); }
.accueil-outils__titre {
  font-size: var(--t-34);
  letter-spacing: -0.035em;
  font-weight: 650;
}
.accueil-outils__intro {
  margin-top: var(--e-2);
  color: var(--texte-doux);
  font-size: var(--t-17);
  max-width: 62ch;
}

/*
 * Quatre colonnes de 243 px donnaient 32 signes par ligne — sous le seuil lisible —, et
 * « gap: 28px » ne portait aucun écart de rangée : les deux rangées ne se séparaient que
 * par la bordure de chaque cellule. Trois colonnes donnent 45 signes, et les bas de
 * cellule s'alignent au lieu de pendre selon la longueur de leur étiquette.
 */
.acces-outils {
  list-style: none;
  margin: var(--e-6) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: var(--e-8);
  row-gap: 0;
  border-top: 1px solid var(--trait);
}
.acces-outil {
  position: relative;
  display: grid;
  align-content: start;
  gap: var(--e-1);
  padding: var(--e-4) 0 var(--e-4);
  border-bottom: 1px solid var(--trait);
}
.acces-outil__lien {
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  min-height: 32px;
  font-size: var(--t-17);
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--texte);
  text-decoration: none;
}
/*
 * Un intitulé portait deux décorations : une pastille menthe à gauche et une flèche
 * violette à droite. L'une des deux est de trop, et c'est la pastille — elle ne porte
 * aucune information, et la menthe est réservée au décor précisément pour cela.
 * La flèche, elle, dit où mène le lien : elle part au bord droit de la cellule.
 */
.acces-outil__lien::after {
  content: "\2192"; color: var(--action); font-weight: 500; margin-inline-start: auto;
}
.acces-outil__lien:hover { color: var(--action-survol); }
.acces-outil:has(.acces-outil__lien:hover) .acces-outil__texte { color: var(--texte); }
.acces-outil__lien:focus-visible { outline-offset: 2px; }
.acces-outil__texte { font-size: var(--t-15); color: var(--texte-doux); line-height: 1.45; }
/*
 * La pastille encadrée était ce qui datait le plus cette grille. Le périmètre d'un outil
 * est un relevé : il se lit dans l'apparat, sous un filet, aligné au bas de la cellule —
 * et les bas de cellule s'alignent entre eux au lieu de pendre selon la longueur du texte.
 */
.acces-outil {
  align-content: space-between;
  padding-block: var(--e-6);
  border-bottom: 1px solid var(--trait);
}
.acces-outil__limite {
  justify-self: stretch;
  margin-top: var(--e-4);
  padding-top: var(--e-2);
  border-top: 1px solid var(--trait);
  font-family: var(--police-apparat); font-variant-numeric: tabular-nums;
  font-size: var(--t-12);
  line-height: 1.4;
  color: var(--texte-doux);
}

/*
 * Le souligné appartient au lien pris dans une phrase. Employé sur chaque entrée d'une
 * liste, il n'identifie plus rien et hache le bloc : six liens bleus soulignés sur deux
 * rangées en dents de scie. Ici le lien se tient en encre, et le souligné arrive au
 * survol et au focus — là où il répond à une intention.
 */
.accueil-outils__plus {
  color: var(--texte); font-weight: 500; text-decoration: none;
}
.accueil-outils__plus:hover, .accueil-outils__plus:focus-visible {
  color: var(--action-survol); text-decoration: underline; text-underline-offset: 3px;
}
.accueil-outils__pied {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e-1) var(--e-4);
  margin-top: var(--e-4);
  font-size: var(--t-15);
}
.accueil-outils__plus { display: inline-flex; align-items: center; min-height: 32px; }

/*
 * Repère de nouveautés (lot 12B). Il vit ici plutôt que dans suivis.css : seul
 * l'accueil le porte, et il ne justifie pas d'y charger une feuille entière.
 * La couleur ne porte pas l'information — le compte est écrit, et le nom
 * accessible du lien l'énonce. Le repère ne s'affiche jamais à zéro.
 */
.suivis-alerte {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; margin-left: var(--e-1); padding: 0 var(--e-1);
  border-radius: var(--r-l); background: var(--action); color: var(--blanc);
  font-size: var(--t-12); font-weight: 600; line-height: 1;
}
.suivis-alerte[hidden] { display: none; }

/* Bloc Actualités, désormais second : titre de section, plus d'ouverture de page. */
.ouverture--actualites { padding-top: var(--e-8); border-top: 1px solid var(--trait); }
.ouverture--actualites .ouverture__titre { font-size: var(--t-34); letter-spacing: -0.01em; }
#actualites, #outils { scroll-margin-top: var(--e-16); }

.accueil-fil { min-width: 0; max-width: 820px; }
.accueil-fil .fil { grid-template-columns: 1fr; }

@media (max-width: 960px) {
  .acces-outils { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 560px) {
  .accueil-outils { padding-block: var(--e-4) var(--e-6); }
  .accueil-outils__intro { font-size: var(--t-15); margin-top: var(--e-2); }
  .acces-outils { grid-template-columns: 1fr; margin-top: var(--e-4); }
  .acces-outil { padding: var(--e-2) 0 var(--e-3); gap: var(--e-1); }
  .acces-outil__lien { font-size: var(--t-17); }
  .acces-outil__texte { font-size: var(--t-13); }
  #actualites, #outils { scroll-margin-top: var(--e-16); }
}

/* ---------- Copie du lien de la page (lot 11C) ----------
   Action discrète : un lien-bouton, pas un appel coloré. Le repli montre
   l'adresse dans un champ en lecture seule quand le presse-papiers est refusé. */
.partage { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--e-1) var(--e-3); padding-top: var(--e-3); font-size: var(--t-15); }
.partage__bouton {
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  min-height: 32px;
  padding: var(--e-1) var(--e-2);
  font: inherit;
  font-size: var(--t-15);
  color: var(--action);
  background: transparent;
  border: 1px solid var(--trait-forte);
  border-radius: var(--r-pilule);
  cursor: pointer;
}
.partage__bouton::before {
  content: "";
  width: 12px; height: 12px;
  flex: none;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 9.5l3-3M7 4.5l1.3-1.3a2.6 2.6 0 0 1 3.7 3.7L10.7 8.2M9 11.5l-1.3 1.3A2.6 2.6 0 0 1 4 9.1l1.3-1.3' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 9.5l3-3M7 4.5l1.3-1.3a2.6 2.6 0 0 1 3.7 3.7L10.7 8.2M9 11.5l-1.3 1.3A2.6 2.6 0 0 1 4 9.1l1.3-1.3' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E") center / contain no-repeat;
}
.partage__bouton:hover { background: var(--survol); color: var(--action-survol); }
.partage__annonce { font-size: var(--t-15); color: var(--texte-doux); }
.partage__annonce:empty { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.partage__repli { flex: 1 1 100%; display: grid; gap: var(--e-1); max-width: 560px; }
.partage .partage__repli { margin-inline-start: auto; }
.partage__repli-libelle { font-size: var(--t-13); color: var(--texte-doux); }
.partage__champ { font-size: var(--t-15); width: 100%; }
/* `hidden` doit primer sur les règles display ci-dessus : les pages d'outils ne
   chargent pas espaces.css et sa règle [hidden] générale (défaut déjà vu en 9B). */
.partage__bouton[hidden], .partage__repli[hidden] { display: none; }
.accueil-outils__pied .partage__bouton { margin-inline-start: auto; }
@media (max-width: 560px) {
  .accueil-outils__pied .partage__bouton { margin-inline-start: 0; }
}
