/*--------------------------------------------------------------
# Fonts (self-hosted)
--------------------------------------------------------------*/

@font-face {
  font-family: "Jost";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/jost/jost-500.a3c2438bfe16.woff2") format("woff2");
}

@font-face {
  font-family: "Libre Caslon Display";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/libre-caslon-display/libre-caslon-display-400.3b6d3d56e4eb.woff2")
    format("woff2");
}

@font-face {
  font-family: "Libre Caslon Text";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/libre-caslon-text/libre-caslon-text-400.6564df5cd887.woff2")
    format("woff2");
}

@font-face {
  font-family: "Libre Caslon Text";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/libre-caslon-text/libre-caslon-text-700.882609d7e89f.woff2")
    format("woff2");
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/ibm-plex-sans/ibm-plex-sans-400.77bc02670657.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/ibm-plex-sans/ibm-plex-sans-500.f7016cd446d2.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/ibm-plex-sans/ibm-plex-sans-600.196e3cbc5fee.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/ibm-plex-sans/ibm-plex-sans-700.c277d7b83f8a.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono/ibm-plex-mono-400.79936b18df9f.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/ibm-plex-mono/ibm-plex-mono-500.b1c8a895f5fd.woff2") format("woff2");
}

/*--------------------------------------------------------------
# Design tokens

Direction : un registre juridique, pas un site vitrine. Une seule
couleur d'identité (le bleu, hérité de la marque), déclinée en deux
rôles distincts plutôt que complétée par une teinte décorative
concurrente. Toute nouvelle règle de couleur doit utiliser un des
tokens ci-dessous — jamais un hex brut — pour rester auditable.

Couleurs — rôles :
  --color-navy       texte de marque sur fond clair (titres de
                      section, sidebar, éléments de contenu) — jamais
                      comme fond d'une grande surface
  --color-navy-deep  texte de marque le plus appuyé (logo, titres de
                      groupe de la sidebar) et seule couleur de fond
                      des grandes surfaces sombres — le footer. Une
                      seule teinte partout : aucun élément ne change de
                      teinte au défilement
  --color-header     fond de la barre du haut, et rien d'autre. Un
                      jeton à part plutôt que --color-paper : ce
                      dernier est une teinte d'ÉTAT, celui-ci est un
                      fond STRUCTURANT, et confondre les deux ferait
                      dériver l'un vers l'autre au premier ajustement
  --color-accent     interactif sur fond clair : liens, bordures,
                      remplissage des boutons pleins
  --color-accent-rgb même couleur que --color-accent, en composantes
                      r,g,b — pour un rgba() avec transparence (ex. un
                      fond d'état actif), CSS ne sait pas extraire les
                      composantes d'une couleur hexadécimale
  --color-accent-hover état hover des boutons pleins (assombri)
  --color-ink        texte principal
  --color-ink-soft   texte secondaire
  --color-paper      teinte d'état interactif (survol/actif d'une
                      ligne) — jamais un fond structurant. Deux zones
                      fonctionnelles voisines (ex. sidebar/contenu) ne
                      se séparent JAMAIS par une différence de fond
                      (ça se lit comme une erreur, pas une séparation
                      intentionnelle) : soit leur contenu contraste
                      déjà assez pour ne nécessiter aucun trait, soit
                      un simple filet --color-line/--color-line-soft en
                      bordure quand ce n'est pas le cas (ex. le footer,
                      séparé du contenu par border-top plutôt qu'un
                      bloc de couleur ; ex. la sidebar, qui défile
                      indépendamment du contenu au-dessus de 768px et
                      dont le bord doit donc se voir)
  --color-line       filets visibles (bordure d'un encadré/cadre)
  --color-line-soft  filets discrets entre éléments d'une même liste
                      (plus doux que --color-line, jamais pour un cadre)

Typographie — rôles (Jost réservé au seul logo, contrainte de marque) :
  --font-logo     Jost — uniquement #header .logo, jamais ailleurs
  --font-display  Libre Caslon Display — grands titres éditoriaux
  --font-heading  Libre Caslon Text — h1-h6 du contenu
  --font-body     IBM Plex Sans — interface, texte courant
  --font-mono     IBM Plex Mono — références de décision (juridiction,
                  date, numéro) et toute donnée chiffrée tabulaire ;
                  jamais pour du texte courant

Règle d'interaction (boutons) :
  - Un bouton plein (fond --color-accent) s'assombrit au survol
    (--color-accent-hover). Ex. : « S'inscrire » sur l'accueil.
  - Un bouton contour se remplit de SA PROPRE couleur de bordure au
    survol (jamais une couleur tierce). Le degré de remplissage suit
    le contexte : à côté d'un bouton plein, il reste discret pour ne
    pas lui faire concurrence ; seul dans son contexte (header), il
    peut se remplir pleinement.

L'en-tête est sur fond clair : ses liens suivent donc la règle
commune et changent de couleur au survol. Un fond sombre imposerait
une couleur d'accentuation propre, éclaircie — ne pas en introduire
une sans ramener aussi ce fond.
--------------------------------------------------------------*/

:root {
  --color-navy: #1f3f66;
  --color-navy-deep: #152a45;
  --color-accent: #2f5fc4;
  --color-accent-rgb: 47, 95, 196;
  --color-accent-hover: #254b9c;
  --color-header: #f1f3f6;
  --color-ink: #16213a;
  --color-ink-rgb: 22, 33, 58;
  --color-ink-soft: #4a5670;
  --color-paper: #eef1f4;
  --color-line: #d6dce3;
  --color-line-soft: #e4e8ec;

  --font-logo: "Jost", sans-serif;
  --font-display: "Libre Caslon Display", serif;
  --font-heading: "Libre Caslon Text", serif;
  --font-body: "IBM Plex Sans", sans-serif;
  --font-mono: "IBM Plex Mono", monospace;

  /* Hauteur de #header.fixed-top, IMPOSÉE et non mesurée : 14px de padding
     haut et bas, 44px de hauteur minimale imposée au conteneur, 1px de filet.
     C'est ce qui la rend indépendante de son contenu : sans cela elle suit le
     plus haut de ses éléments, et change donc selon l'état de connexion. La
     barre latérale s'y adosse au pixel près, et un écart la ferait passer
     sous l'en-tête.

     Toute modification du padding ou de cette hauteur minimale doit être
     reportée ici. */
  --header-height: 73px;

  /* Bootstrap 5 bumped its shared corner radius from Bootstrap 4's
     0.25rem to 0.375rem (buttons, form controls, alerts, pagination
     all read this one variable) — restore the original 4px. */
  --bs-border-radius: 0.25rem;
}

/*--------------------------------------------------------------
# General
--------------------------------------------------------------*/

html {
  scroll-behavior: smooth;
}

/* Bootstrap 5 added an xxl breakpoint (>=1400px, .container maxing out at
   1320px) that Bootstrap 4 never had (capped at 1140px from 1200px up).
   Pin it back to the original width the site was designed at. */
@media (min-width: 1400px) {
  .container {
    max-width: 1140px;
  }
}

/* Bootstrap 5 also shrank the container's own side padding (12px, from
   --bs-gutter-x: 1.5rem) versus Bootstrap 4's 15px. Restore the original
   gutter at every breakpoint. */
.container {
  padding-right: 15px;
  padding-left: 15px;
}

/*
  --color-ink plutôt que --color-ink-soft : 16:1 de contraste sur blanc au lieu
  de 7,4:1. Le gris-bleu adouci se voulait reposant, il rendait surtout le texte
  courant plus pâle que le reste de l'interface — les liens, les titres, les
  boutons —, ce qui inverse la hiérarchie de lecture.

  Le pied de page conserve --color-ink-soft par ses propres règles : lui doit
  rester en retrait.
*/
body {
  font-family: var(--font-body);
  color: var(--color-ink);
}

a {
  color: var(--color-accent);
  text-decoration: none;
}

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

h1,
h2,
h3,
h4,
h5,
h6 {
  font-family: var(--font-heading);
  color: var(--color-ink);
}

/*--------------------------------------------------------------
  # Back to top button

  `position: fixed` est indispensable et n'a pas d'équivalent ailleurs :
  sans elle l'ancre retombe dans le flux, sous le pied de page.
  --------------------------------------------------------------*/

.back-to-top {
  position: fixed;
  display: none;
  right: 15px;
  bottom: 15px;
  z-index: 99999;
}

.back-to-top i {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  width: 40px;
  height: 40px;
  border-radius: 50px;
  background: var(--color-accent);
  color: #fff;
  transition: all 0.4s;
}

.back-to-top i:hover {
  background: var(--color-accent-hover);
  color: #fff;
}

/*--------------------------------------------------------------
  # Header
  --------------------------------------------------------------*/

/* Fond clair : un registre juridique, pas une dalle de couleur en tête de
   chaque page. Le filet du bas fait tout le travail de séparation d'avec le
   blanc du contenu — un fond gris sans trait laisse une frontière molle. */
#header {
  transition: all 0.5s;
  z-index: 997;
  padding: 14px 0;
  background: var(--color-header);
  border-bottom: 1px solid var(--color-line);
}

/* Hauteur imposée plutôt que subie. Sans elle, la barre prend celle de son
   plus haut élément — les liens du menu à 42,5px connecté, le bouton de
   connexion à 39px sinon —, et l'en-tête change de hauteur d'un état à
   l'autre. Le contenu tient sous 44px dans tous les cas, y compris entre 769
   et 1199px où le menu cède la place au hamburger.

   C'est cette valeur, avec le padding et le filet ci-dessus, qui définit
   --header-height : les trois vont ensemble. */
#header .container {
  min-height: 44px;
}

#header .logo {
  font-family: var(--font-logo);
  font-size: 30px;
  margin: 0;
  padding: 0;
  line-height: 1;
  /* Graisse 500 obligatoire, et pas un cran de plus : Jost n'est auto-hébergée
     qu'en 500 (voir @font-face en tête de fichier). Toute valeur supérieure
     ferait engraisser le glyphe par le navigateur — un faux gras, visible sur
     un logo en capitales espacées. Le texte marine pèse un peu moins que le
     blanc sur fond sombre qu'il remplace ; c'est l'espacement, pas la graisse,
     qui compense. */
  font-weight: 500;
  letter-spacing: 2px;
  text-transform: uppercase;
}

#header .logo a {
  color: var(--color-navy-deep);
}

#header .logo img {
  max-height: 40px;
}

/*--------------------------------------------------------------
  # Navigation Menu
  --------------------------------------------------------------*/

/* Desktop Navigation */

.nav-menu ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.nav-menu > ul {
  display: flex;
}

.nav-menu > ul > li {
  position: relative;
  white-space: nowrap;
  padding: 10px 0 10px 28px;
}

.nav-menu a {
  display: block;
  position: relative;
  color: var(--color-navy);
  transition: 0.3s;
  font-size: 15px;
  letter-spacing: 0.5px;
  font-weight: 500;
  font-family: var(--font-body);
}

/*
  Toute icône placée dans un lien du menu. En inline, le glyphe s'aligne sur la
  ligne de base et les métriques verticales de la police d'icônes débordent la
  boîte : le lien mesure alors 24px là où un lien texte en fait 22,5, et le
  menu prend un pixel et demi de plus. En block, la boîte vaut exactement
  l'interligne, sans alignement sur la ligne de base.

  Ni taille ni interligne ici : hérités du lien, ils suivent .nav-menu a plutôt
  que d'en figer une copie qui se désynchroniserait.
*/
.nav-menu a > i {
  display: block;
}

/* Absolutely positioned so it never adds to the link's own box height —
   a border-bottom/padding-bottom here would shift the text a couple px
   off the vertical center shared with the logo and the header button.

   « Mon compte » n'a pas de traitement à part : ni triangle Bootstrap, ni
   chevron maison — les deux ont été essayés et jugés datés ou superflus.
   Il se comporte comme n'importe quel autre lien du menu, cette barre
   comprise ; ce qui ouvre un menu plutôt qu'une page ne se signale pas
   autrement ici.

   border/margin réinitialisés : sans ça, .dropdown-toggle garde les bordures
   du triangle par défaut de Bootstrap (transparentes sur les côtés, pleines
   en haut) en plus des propriétés définies ici — les deux jeux de règles se
   cumulent sur ce même ::after au lieu de s'exclure, ce qui dessinait un
   ruban aux bords en pointe, visible même hors survol. */
.nav-menu a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -6px;
  border: none;
  margin: 0;
  height: 2px;
  background: transparent;
  transition: background-color 0.3s;
}

.nav-menu a:hover::after,
.nav-menu .active > a::after,
.nav-menu li:hover > a::after {
  background: var(--color-accent);
}

.nav-menu a:hover,
.nav-menu .active > a {
  color: var(--color-accent);
}

/* Le menu du compte, à la manière de GitHub : réglages, administration et
   déconnexion regroupés sous une seule entrée. */

.nav-menu .dropdown-menu {
  border: 1px solid var(--color-line);
  border-radius: 4px;
  box-shadow: 0 6px 20px rgba(var(--color-ink-rgb), 0.1);
  padding: 6px;
  min-width: 200px;
}

/* text-decoration explicite, sur les deux règles : « Paramètres » et « Admin »
   sont des <a>, « Se déconnecter » un <button> (la déconnexion est un envoi de
   formulaire, pas un simple lien). Une règle de soulignement qui ne viserait
   que les liens ne s'appliquerait jamais au bouton, quelle que soit la classe
   partagée — d'où ce reset qui vaut pour les deux types d'éléments, afin que
   les trois entrées réagissent identiquement au survol. */
.nav-menu .dropdown-item {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  border: 0;
  border-radius: 3px;
  background: none;
  padding: 8px 10px;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--color-navy);
  text-decoration: none;
  cursor: pointer;
}

.nav-menu .dropdown-item:hover,
.nav-menu .dropdown-item:focus {
  background: var(--color-paper);
  color: var(--color-navy-deep);
  text-decoration: none;
}

.nav-menu .dropdown-item.active {
  background: var(--color-paper);
  color: var(--color-accent);
  font-weight: 600;
}

/* L'icône ne porte pas de sens : elle double le libellé pour l'œil qui balaie.
   Sa couleur reste en retrait pour que ce soit le mot qu'on lise d'abord. */
.nav-menu .dropdown-item i {
  font-size: 16px;
  line-height: 1;
  color: var(--color-ink-soft);
}

.nav-menu .dropdown-item:hover i {
  color: inherit;
}

/* Connexion / déconnexion. Un lien, distingué par sa seule graisse, et non un
   bouton encadré : c'est une action qu'on fait une fois par session, elle n'a
   pas à peser plus lourd que le reste de la barre. */
.header-link {
  margin-left: 28px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--color-navy);
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0.5px;
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.3s;
  -webkit-appearance: none;
  appearance: none;
}

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


/* Bootstrap sert .btn-primary dans son propre bleu (#007bff), employé tel
   quel sur les formulaires de connexion, d'inscription, de signalement et de
   soumission. Réaligné sur la couleur d'accentuation de la palette. */
.btn-primary {
  color: #fff;
  background-color: var(--color-accent);
  border-color: var(--color-accent);
}

.btn-primary:hover {
  background-color: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
}

.btn-primary.focus,
.btn-primary:focus {
  background-color: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
  box-shadow: 0 0 0 0.2rem rgba(var(--color-accent-rgb), 0.5);
}

.btn-primary.disabled,
.btn-primary:disabled {
  background-color: var(--color-accent);
  border-color: var(--color-accent);
}

.btn-primary:not(:disabled):not(.disabled).active,
.btn-primary:not(:disabled):not(.disabled):active {
  background-color: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
}

.btn-primary:not(:disabled):not(.disabled).active:focus,
.btn-primary:not(:disabled):not(.disabled):active:focus {
  box-shadow: 0 0 0 0.2rem rgba(var(--color-accent-rgb), 0.5);
}

/* Same story as .btn-primary above: Bootstrap's stock alert-primary
   (#004085 text on #cce5ff) is used bare for search-result counts, the
   Django messages banner, and decision-submission confirmations. */
/* Opaque et non translucide : #hideDiv est positionné en absolu (top: 90%) et
   peut donc se poser sur n'importe quoi ; une teinte translucide s'y délaverait
   jusqu'à devenir illisible. */
.alert-primary {
  color: var(--color-navy);
  background-color: #e6ecf8;
  border-color: #c1cfed;
}

.alert-primary hr {
  border-top-color: #c1cfed;
}

.alert-primary .alert-link {
  color: var(--color-navy-deep);
}

/* Every text input/textarea site-wide except the sidebar search (which
   has its own underlined style) used Bootstrap's stock blue focus ring. */
.form-control:focus {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 0.2rem rgba(var(--color-accent-rgb), 0.25);
}

/* Native checkbox (submit_decision's confidentiality checkbox) otherwise
   renders with the browser/OS accent color instead of the brand's. */
.form-check-input {
  accent-color: var(--color-accent);
}

/* Header content (logo + "Se déconnecter"/"Se connecter" + toggle) is too
   wide to fit a phone-width viewport at the sizes above — it silently
   overflows the flex row (nowrap), pushing .mobile-nav-toggle off-screen
   entirely. Shrink logo and button enough to fit down to a 320px viewport. */
@media (max-width: 480px) {
  #header .logo {
    font-size: 20px;
    letter-spacing: 0.5px;
  }
  .get-started-btn {
    margin: 0 8px 0 0;
    padding: 5px 12px;
    font-size: 12px;
  }
  .mobile-nav-toggle {
    margin-left: 4px;
  }
}

/* Mobile Navigation */

/* En flex plutôt qu'en bloc de texte : les métriques verticales d'une police
   d'icônes débordent la boîte du glyphe, et le bouton se calerait sur la ligne
   de base au lieu de son centre, pendant sous les mots voisins. */
.mobile-nav-toggle {
  position: relative;
  z-index: 9998;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  padding: 0;
  background: none;
  font-size: 24px;
  margin-left: 15px;
  transition: all 0.4s;
  line-height: 1;
  cursor: pointer;
}

.mobile-nav-toggle:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.mobile-nav-toggle i {
  color: var(--color-navy);
}

.mobile-nav {
  position: fixed;
  top: 55px;
  right: 15px;
  bottom: 15px;
  left: 15px;
  z-index: 9999;
  overflow-y: auto;
  background: #fff;
  transition: ease-in-out 0.2s;
  opacity: 0;
  visibility: hidden;
  border-radius: 10px;
  padding: 10px 0;
}

.mobile-nav * {
  margin: 0;
  padding: 0;
  list-style: none;
}

.mobile-nav a {
  display: block;
  position: relative;
  color: var(--color-navy);
  padding: 10px 20px;
  font-weight: 500;
  outline: none;
}

.mobile-nav a:hover,
.mobile-nav .active > a,
.mobile-nav li:hover > a {
  color: var(--color-accent);
  text-decoration: none;
}

.mobile-nav-overly {
  width: 100%;
  height: 100%;
  z-index: 9997;
  top: 0;
  left: 0;
  position: fixed;
  background: rgba(var(--color-ink-rgb), 0.6);
  overflow: hidden;
  display: none;
  transition: ease-in-out 0.2s;
}

.mobile-nav-active {
  overflow: hidden;
}

.mobile-nav-active .mobile-nav {
  opacity: 1;
  visibility: visible;
}

.mobile-nav-active .mobile-nav-toggle i {
  color: #fff;
}

/*--------------------------------------------------------------
  # Titres de section
  --------------------------------------------------------------*/

.section-title {
  text-align: center;
  padding-bottom: 30px;
}

.section-title h2 {
  font-size: 32px;
  font-weight: bold;
  text-transform: uppercase;
  margin-bottom: 20px;
  padding-bottom: 20px;
  position: relative;
  color: var(--color-navy);
}

.section-title h2::before {
  content: "";
  position: absolute;
  display: block;
  width: 120px;
  height: 1px;
  background: var(--color-line);
  bottom: 1px;
  left: calc(50% - 60px);
}

.section-title h2::after {
  content: "";
  position: absolute;
  display: block;
  width: 40px;
  height: 3px;
  background: var(--color-accent);
  bottom: 0;
  left: calc(50% - 20px);
}

.section-title p {
  margin-bottom: 0;
}

/*
  Titre d'une page autonome (politique de confidentialité, méthode, préface,
  écrans de compte…). .section-title est fait pour découper la page d'accueil
  en sections : ses 32px en capitales soulignés de deux filets servent de
  césure entre deux blocs, et deviennent une enseigne disproportionnée en tête
  d'une page qui n'a qu'un seul titre.

  Reprend le rendu de « Les dernières nullités » : la formule est celle que
  Bootstrap applique à un h3, dupliquée ici pour que le niveau de titre reste
  libre — l'apparence ne doit pas dicter la sémantique.
*/
.page-title {
  text-align: center;
  font-size: calc(1.3rem + 0.6vw);
  font-weight: 500;
  text-transform: none;
  color: var(--color-navy);
  margin-bottom: 8px;
  padding-bottom: 16px;
}

@media (min-width: 1200px) {
  .page-title {
    font-size: 1.75rem;
  }
}

/*
  Intertitre d'une page autonome. Les h4 de Bootstrap font 24px, pour un titre
  de page à 28px : quatre pixels d'écart et la même graisse, soit une hiérarchie
  que l'œil ne distingue plus. Descendus à 20px, avec de l'air au-dessus pour
  compenser le contraste de taille qu'on leur retire.

  Classe explicite plutôt qu'une règle sur h4 : le même niveau sert de nom sur
  les cartes de la page « À propos », où ce rendu n'aurait aucun sens.
*/
.page-section-title {
  font-size: 1.25rem;
  margin-top: 1.75rem;
}

/*
  Tables de contenu (politique de confidentialité). Bootstrap laisse les
  siennes en noir pur, hors palette. --color-ink plutôt que --color-ink-soft,
  qui est la couleur du texte courant : un tableau se parcourt en diagonale
  plutôt qu'il ne se lit, et la densité y aide là où elle fatiguerait sur de la
  prose. On garde donc le contraste, on ne garde pas le noir.

  Les cellules héritaient par ailleurs du text-align du conteneur, justifié
  au-delà de 992px, d'où des mots espacés au fil de colonnes étroites.

  La couleur passe par --bs-table-color et non par `color` : Bootstrap la
  ré-applique cellule par cellule à partir de cette variable, un `color` posé
  sur .table serait donc écrasé.
*/
.table {
  --bs-table-color: var(--color-ink);
}

.table > thead th {
  text-align: center;
}

.table > tbody td {
  text-align: left;
}

/*--------------------------------------------------------------
  # Accueil public

  Deux colonnes qui remplissent l'écran : la marque d'un côté, ce
  qu'est le site de l'autre. Pas de barre du haut, pas de portraits —
  la page ne pose qu'une question, entrer ou non.
  --------------------------------------------------------------*/

.accueil {
  /* body est une colonne flex : c'est ce qui donne à cette page toute la
     hauteur restante, et donc de quoi centrer verticalement ses deux moitiés.
     Le pied de page se pose dessous, sans jamais la comprimer. */
  flex: 1 0 auto;
  /* Fond blanc explicite et sur toute la largeur : cette page n'a pas de
     #content, qui le porte ailleurs, et se poserait sinon à même le gris du
     corps. Le plafond est sur la grille à l'intérieur, pas ici — sinon des
     bandes grises apparaîtraient de part et d'autre sur un écran large. */
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 56px 32px;
}

.accueil-grille {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: center;
  gap: 48px;
  /* Plafonnée puis centrée : sans cela, les deux moitiés s'écartent l'une de
     l'autre à mesure que l'écran s'élargit, jusqu'à ne plus se lire comme un
     même ensemble. */
  max-width: 1320px;
  width: 100%;
}

.accueil-marque {
  text-align: center;
}

.accueil-nom {
  font-family: var(--font-logo);
  /* Échelle fluide : ce mot est le seul objet de sa moitié d'écran, il doit
     suivre la largeur disponible plutôt que rester figé. Le plafond de clamp()
     l'empêche de devenir une enseigne sur un écran très large. */
  font-size: clamp(2.4rem, 5vw, 4rem);
  font-weight: 500;
  letter-spacing: 3px;
  text-transform: uppercase;
  line-height: 1;
  color: var(--color-navy-deep);
  margin: 0 0 14px;
}

.accueil-slogan {
  font-family: var(--font-heading);
  font-size: clamp(1rem, 1.5vw, 1.25rem);
  line-height: 1.4;
  color: var(--color-ink-soft);
  max-width: 24ch;
  margin: 0 auto;
}

.accueil-propos {
  /* Borné et centré dans sa moitié : au-delà, les lignes s'allongent jusqu'à
     ce que l'œil perde le début de la suivante. */
  max-width: 34em;
  margin: 0 auto;
  text-align: justify;
  hyphens: auto;
}

.accueil-propos p {
  margin-bottom: 16px;
}

/* La ligne qui dit où trouver le QR code — accueil public et écran de
   connexion. En retrait de toute action : rien n'y est cliquable, et lui
   donner le poids d'un lien laisserait croire le contraire.

   Pas d'alignement ici : l'accueil la veut à gauche (le paragraphe qu'elle
   suit est justifié), la connexion centrée (comme le reste de cet écran).
   Chaque page le fixe via extra_class, en passant text-start ou text-center. */
.qr-signup-hint {
  margin-top: 18px;
  font-size: 14px;
  color: var(--color-ink-soft);
}

.accueil-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 28px;
  /* Les boutons ne suivent pas la justification du texte au-dessus : ce sont
     des objets, pas des lignes. */
  text-align: left;
}

/* Bouton contour à la couleur d'accentuation. Écrit ici plutôt que repris de
   .btn-outline-primary, figé sur le bleu de Bootstrap (#0d6efd) : le corriger
   demanderait autant de règles que d'en écrire. Se remplit de SA PROPRE couleur
   au survol, conformément à la règle des boutons. */
.btn-outline-accent {
  color: var(--color-accent);
  border: 1px solid var(--color-accent);
  background: transparent;
}

.btn-outline-accent:hover,
.btn-outline-accent:focus {
  color: #fff;
  background: var(--color-accent);
  border-color: var(--color-accent);
}

/* Une seule colonne dès que la moitié d'écran devient trop étroite pour porter
   un paragraphe justifié — bien avant le point de rupture du mobile, sans quoi
   le texte se disloque en lignes trouées sur une tablette en portrait. */
@media (max-width: 991px) {
  .accueil {
    padding: 40px 24px;
    /* Aligné en haut : centrer verticalement une colonne unique la ferait
       flotter au milieu d'une page qu'elle remplit déjà presque. */
    align-items: flex-start;
  }

  .accueil-grille {
    grid-template-columns: 1fr;
    gap: 32px;
  }

  .accueil-propos {
    margin: 0;
    max-width: none;
  }

  .accueil-actions {
    justify-content: flex-start;
  }
}

/*--------------------------------------------------------------
  # Auteurs

  Des notices, pas des cartes. Ombre portée, coins arrondis et
  soulèvement au survol suggèrent un élément qu'on prend, trie ou
  clique ; il s'agit ici de trois biographies qu'on lit une fois.
  Une photo, un nom, une qualité, et rien de plus.
  --------------------------------------------------------------*/

/* Pas de filet entre les personnes. Un filet marque où finit une entrée dans
   une liste qu'on parcourt ; deux ou trois notices que sépare déjà un portrait
   n'en ont pas besoin, et le trait n'ajouterait que du bruit horizontal à une
   page qui en a déjà avec ses intertitres. */
.auteur {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 18px 0;
}

.auteur-portrait {
  position: relative;
  display: block;
  width: 96px;
  height: 96px;
  flex-shrink: 0;
  overflow: hidden;
  border-radius: 50%;
  /* Les portraits sont en niveaux de gris et sur fond clair : sans ce filet,
     leur bord se dissout dans le blanc de la page. */
  border: 1px solid var(--color-line-soft);
}

/* Recadrage sur le visage, et non simple décalage. `object-fit: cover` seul ne
   sert à rien ici : les sources font 625×747, soit un rapport déjà proche du
   carré, et il n'en retire que 122px de hauteur — le portrait en buste se
   retrouve donc entier dans un cercle de 96px, où le visage ne fait plus qu'un
   tiers. Il faut agrandir puis rogner, ce que seul un conteneur à débordement
   caché permet.

   Un réglage par photo, et non un réglage commun : les trois sources n'ont pas
   le même cadrage — la tête occupe 290px de haut chez Léon, 285 chez Rémi mais
   410 chez Maxim, dont le portrait est bien plus serré. Une valeur unique
   conviendrait à l'un en desservant les deux autres.

   Chaque paire (largeur, décalage) découpe le carré qui cadre la tête aux
   trois quarts du cercle. Pour une photo neuve : mesurer la tête dans la
   source, prendre un carré d'un tiers plus grand centré dessus, et convertir —
   largeur = 625 ÷ côté du carré, décalage = −abscisse du carré ÷ côté. */
.auteur-portrait img {
  position: absolute;
  top: 0;
}

.auteur-portrait--leon img {
  width: 162%;
  left: -29%;
}

.auteur-portrait--remi img {
  width: 164%;
  left: -30%;
}

.auteur-portrait--maxim img {
  width: 114%;
  left: 0;
}

.auteur-nom {
  font-family: var(--font-heading);
  font-size: 19px;
  font-weight: 700;
  color: var(--color-navy);
  margin: 0 0 2px;
}

.auteur-qualite {
  display: block;
  font-size: 14px;
  color: var(--color-ink-soft);
}

.auteur-detail {
  font-size: 14px;
  color: var(--color-ink-soft);
  margin: 6px 0 0;
  line-height: 1.5;
}

/* Le lien social : un mot plutôt qu'une pastille ronde. Une icône seule
   demande d'être devinée, et il n'y en a qu'une par personne — la pastille
   ne rangeait donc rien. */
#content .auteur-lien {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: 8px;
  font-size: 13px;
  color: var(--color-accent);
  text-decoration: none;
}

#content .auteur-lien:hover {
  text-decoration: underline;
}

@media (max-width: 575px) {
  .auteur {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
  }
}

/*--------------------------------------------------------------
  # Contact
  --------------------------------------------------------------*/

/* Aucun traitement de carte ici — ni filet d'accentuation, ni ombre portée :
   une carte ne se détache que posée sur un fond coloré, et cette page est
   blanche. Le formulaire suit le registre des autres formulaires du site. */
.contact .php-email-form {
  width: 100%;
}

.contact .php-email-form .mb-3 {
  padding-bottom: 8px;
}

.contact .php-email-form input,
.contact .php-email-form textarea {
  border-radius: 0;
  box-shadow: none;
  font-size: 14px;
  border-radius: 4px;
}

.contact .php-email-form input:focus,
.contact .php-email-form textarea:focus {
  border-color: var(--color-accent);
}

.contact .php-email-form input {
  height: 44px;
}

.contact .php-email-form textarea {
  padding: 10px 12px;
}

/* Le bouton en gélule est parti avec la carte : les autres formulaires du site
   (connexion, soumission) emploient .btn .btn-primary, déjà à la couleur
   d'accentuation, et le gabarit fait de même. */

/*--------------------------------------------------------------
  # Footer
  --------------------------------------------------------------*/

#footer {
  font-size: 13px;
  background: var(--color-paper);
  border-top: 1px solid var(--color-line);
  /* Marks the true end of the page: without it, iOS Safari's rubber-band
     overscroll (which reveals the body's own background, identical to
     the footer's) is indistinguishable from real footer content. */
  border-bottom: 1px solid var(--color-line);
}

.footer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 20px 0;
}

.footer-brand {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--font-body);
  color: var(--color-ink-soft);
}

.footer-brand-name {
  font-weight: 600;
  color: var(--color-navy);
}

/* Centré, y compris quand les liens passent à la ligne. Le pied de page bascule
   en colonne sur petit écran et s'aligne alors sur `text-align: center`, mais
   cette liste est elle-même un conteneur flex : la propriété n'a aucune prise
   sur ses éléments, qui restaient collés au bord gauche. */
.footer-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 20px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.footer-links a {
  color: var(--color-ink-soft);
}

.footer-links a:hover {
  color: var(--color-accent);
  text-decoration: none;
}

.footer-disclaimer {
  padding-bottom: 20px;
  color: var(--color-ink-soft);
}

.footer-disclaimer p {
  margin: 0;
  text-align: center;
}

.footer-disclaimer small {
  font-size: 12px;
}

@media (max-width: 768px) {
  .footer-row {
    flex-direction: column;
    text-align: center;
  }
}

/* ---------------------------------------------------
    GENERAL STYLE
----------------------------------------------------- */

/* Colonne pleine hauteur : le pied de page se pose au bas de la fenêtre quand
   le contenu ne la remplit pas. Ne pas confier ce rôle à un `min-height: 100vh`
   sur #content — il garantirait l'inverse, une page dépassant toujours d'un
   écran, donc un défilement obligatoire pour atteindre le pied. */
body {
  font-family: var(--font-body);
  background: var(--color-paper);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

/* Prend toute la hauteur restante, sans jamais se comprimer sous celle de son
   contenu (flex-shrink à 0) : sans quoi une page longue verrait son contenu
   écrasé pour tenir dans l'écran. */
.wrapper {
  flex: 1 0 auto;
}

#footer {
  flex-shrink: 0;
}

#content {
  font-family: var(--font-body);
}

#content h3 {
  color: var(--color-navy);
}

#content a {
  color: var(--color-navy);
  text-decoration: underline;
}

#content a:hover {
  color: var(--color-accent);
  text-decoration: underline;
}

/* Les deux règles ci-dessus visent les liens de prose. Sur un lien stylé en
   bouton, le soulignement ne fait que barrer le libellé.

   La couleur demande plus d'attention : `#content a` compte un identifiant,
   `.btn-primary` une simple classe, et le marine l'emporte donc sur le blanc du
   bouton — texte bleu sur fond bleu. D'où une reprise variante par variante, à
   spécificité au moins égale. Un `color: inherit` global n'y suffirait pas : il
   ferait descendre la couleur du corps, soit du sombre sur fond d'accentuation. */
#content a.btn,
#content a.btn:hover {
  text-decoration: none;
}

#content a.btn-primary,
#content a.btn-primary:hover {
  color: #fff;
}

#content a.btn-outline-accent {
  color: var(--color-accent);
}

#content a.btn-outline-accent:hover {
  color: #fff;
}

p {
  font-family: var(--font-body);
  font-size: 1em;
  font-weight: 400;
  line-height: 1.6em;
}

/* Explicite plutôt que le `bolder` par défaut du navigateur, qui est
   relatif à la graisse héritée : sous 400, il ne monte qu'à 400 et le
   gras devient invisible. */
b,
strong {
  font-weight: 700;
}

/* Listes à tirets (registre éditorial) plutôt que puces rondes. Pas de
   ::marker : le rendu reste identique sur les navigateurs qui ne
   supportent pas `content` sur ce pseudo-élément. */
.list-dash {
  list-style: none;
  padding-left: 1.4em;
}

.list-dash > li {
  position: relative;
}

.list-dash > li::before {
  content: "—";
  position: absolute;
  left: -1.4em;
}

#sidebar a,
#sidebar a:hover,
#sidebar a:focus {
  color: inherit;
  text-decoration: none;
  transition: all 0.3s;
}

/* ---------------------------------------------------
    RECHERCHE (barre du haut et volet mobile)
----------------------------------------------------- */

/* Le champ appartient à la barre du haut et non à la barre latérale : celle-ci
   est absente de toute une série de pages — mon compte, mentions légales, 404,
   double authentification — et sur mobile elle se trouve derrière un bouton.

   Cadre et loupe plutôt qu'un simple trait souligné : sur un fond gris, un
   champ souligné se lit comme une légende plutôt que comme une zone de saisie,
   et rien n'invite à cliquer dedans. Le cadre le désigne, la loupe le nomme. */
.search-form {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 12px;
  height: 38px;
  background: #fff;
  border: 1px solid var(--color-line);
  border-radius: 6px;
  transition: border-color 0.2s, box-shadow 0.2s;
}

.search-form:focus-within {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 3px rgba(var(--color-accent-rgb), 0.15);
}

.search-form-icon {
  font-size: 16px;
  line-height: 1;
  color: var(--color-ink-soft);
  flex-shrink: 0;
}

/* Champ nu : le cadre, le fond et le focus sont portés par le formulaire,
   pas par l'input — sinon deux bordures se superposent. */
.search-form-input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  background: transparent;
  padding: 0;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--color-navy);
}

.search-form-input:focus {
  outline: none;
}

.search-form-input::placeholder {
  color: var(--color-ink-soft);
}

/* Occupe l'espace laissé libre entre le logo et le menu, sans le dévorer :
   au-delà, le champ s'étire jusqu'à devenir l'élément dominant de la barre. */
/* Occupe l'espace laissé libre entre le logo et le menu. Le plafond l'empêche
   de s'étirer jusqu'à dominer la barre sur les très grands écrans, sans le
   confiner à une largeur de formulaire sur les écrans courants. */
.header-search {
  flex: 1 1 auto;
  max-width: 520px;
  margin-left: 40px;
}

/* Sur petit écran le champ reste dans la barre plutôt que de descendre dans
   le volet : c'est la navigation principale du site, et l'enfermer derrière le
   hamburger la met à deux gestes sur l'appareil où le geste coûte le plus. La
   place vient de l'initiale qui remplace le nom (voir .logo-compact).

   Sans plafond ici : il ne reste que trois éléments dans la barre, et le champ
   doit prendre tout ce qui sépare l'initiale du bouton de menu. */
@media (max-width: 767px) {
  .header-search {
    max-width: none;
    margin-left: 14px;
  }
}

/* Le nom réduit à son initiale, connecté et sur petit écran seulement. */
@media (max-width: 767px) {
  .logo-compact .logo-suite {
    display: none;
  }
}

/* Le bouton de déconnexion du volet : c'est un bouton de formulaire (POST,
   jeton anti-CSRF), pas un lien, et `.mobile-nav *` remet son style à zéro —
   il faut donc lui redonner l'aspect des entrées voisines. */
.mobile-nav .mobile-nav-logout {
  display: block;
  width: 100%;
  border: 0;
  background: none;
  padding: 10px 20px;
  text-align: left;
  font-family: inherit;
  font-size: inherit;
  font-weight: 500;
  color: var(--color-navy);
  cursor: pointer;
}

.mobile-nav .mobile-nav-logout:hover {
  color: var(--color-accent);
}

/* ---------------------------------------------------
    DECISION CARDS (registre)
----------------------------------------------------- */

.decision-list {
  border-top: 1px solid var(--color-line-soft);
}

.decision-card {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 24px;
  padding: 22px 32px;
  border-bottom: 1px solid var(--color-line-soft);
}

.decision-card-main {
  min-width: 0;
}

.decision-card-ref {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--color-accent);
  letter-spacing: 0.01em;
  margin-bottom: 6px;
  font-variant-numeric: tabular-nums;
}

/* #content-prefixed: #content a (generic prose links, for inline
   citations elsewhere in decision content) otherwise wins the cascade
   over a plain class selector — same specificity fight that caused
   the card titles/categories to render as plain underlined blue
   links instead of this styling. */
#content .decision-card-title {
  display: block;
  font-family: var(--font-heading);
  font-size: 18px;
  line-height: 1.35;
  color: var(--color-ink);
  text-decoration: none;
}

#content .decision-card-title:hover {
  color: var(--color-accent);
  text-decoration: none;
}

.decision-card-cat {
  font-family: var(--font-body);
  font-size: 12.5px;
  color: var(--color-ink-soft);
  margin-top: 8px;
}

#content .decision-card-cat a {
  color: var(--color-ink-soft);
  text-decoration: none;
}

#content .decision-card-cat a:hover {
  color: var(--color-accent);
  text-decoration: underline;
}

.decision-card-badge {
  flex-shrink: 0;
  text-align: right;
  white-space: nowrap;
  padding-top: 2px;
}

.decision-card-badge-label {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--color-ink-soft);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.decision-card-badge-num {
  display: block;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 20px;
  color: var(--color-navy);
  margin-top: 2px;
}

.decision-card-badge-num-text {
  font-size: 14px;
}

@media (max-width: 576px) {
  .decision-card {
    flex-direction: column;
    gap: 8px;
    padding: 18px 16px;
  }
  .decision-card-badge {
    text-align: left;
  }
  .decision-card-badge-label,
  .decision-card-badge-num {
    display: inline;
  }
  .decision-card-badge-num {
    margin-left: 6px;
  }
}

/* ---------------------------------------------------
    DECISION DOSSIER (fiche de décision)
----------------------------------------------------- */

.dossier-ref {
  font-family: var(--font-mono);
  font-size: 17px;
  color: var(--color-accent);
  letter-spacing: 0.01em;
  margin-bottom: 14px;
  font-variant-numeric: tabular-nums;
}

#content .dossier-title {
  font-size: 26px;
  line-height: 1.25;
  margin: 0 0 12px;
}

/* ---------------------------------------------------
    LARGEUR DU CORPS
----------------------------------------------------- */

/* Une seule mesure pour toutes les pages autres que les listes de décisions et
   les fiches, dont la présentation diffère par nature. Les gabarits employaient
   jusqu'à quatre grilles Bootstrap différentes — col-md-6, 7, 8 et une
   combinaison col-sm-10/col-md-6 —, si bien que la colonne de texte changeait
   de largeur d'une page à l'autre sans qu'aucune raison ne le justifie.

   En `ch` et non en pixels : ce qui compte est le nombre de signes par ligne,
   pas une distance. Une valeur absolue cesserait d'être juste dès qu'un
   visiteur agrandit la police de son navigateur — le texte grossirait, la
   colonne non.

   Et non une fraction de grille Bootstrap : celle-ci découpe en douzièmes un
   conteneur dont la largeur saute à chaque point de rupture, ce qui est
   précisément la cause de l'incohérence qu'on corrige ici.

   `min(…, 100%)` plutôt qu'un simple max-width : sur un écran étroit, la
   mesure l'emporterait et ferait déborder la page.

   Attention au piège de l'unité avant de toucher à ce nombre : `ch` vaut la
   largeur du chiffre « 0 », plus large que la moyenne des lettres. Mesuré sur
   cette police, 1 signe ≈ 0,73ch — ces 83ch donnent donc environ 112 signes
   par ligne, et non 83.

   Ce choix est délibéré et connu : la fourchette de confort en typographie est
   de 50 à 75 signes, et WCAG 1.4.8 plafonne à 80. C'est un critère de niveau
   AAA, que la quasi-totalité des sites ne vise pas, et l'occupation de l'écran
   a été préférée à la longueur de ligne — une colonne conforme ferait 560px et
   laisserait, sur un écran de 1920, plus des deux tiers de la page en blanc.

   Les deux grandeurs sont liées par « largeur = signes × 0,44 × taille de
   police ». À 16px, un signe vaut 7px : on ne peut donc élargir la colonne
   qu'en allongeant la ligne, ou en grossissant le texte. */
.page-body {
  width: min(83ch, 100%);
  margin-inline: auto;

}

/* ---------------------------------------------------
    FIL D'ARIANE
----------------------------------------------------- */

/* Situe la page dans l'arbre là où la barre latérale ne le fait pas : elle est
   repliée derrière un bouton sous 768px, et absente des résultats de recherche
   comme des fiches atteintes par un lien direct. */
.fil-ariane {
  margin-bottom: 18px;
}

.fil-ariane ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--color-ink-soft);
}

/* Séparateur en ::before plutôt qu'entre deux éléments : il suit le retour à
   la ligne des échelons, là où un caractère posé dans le balisage se
   retrouverait seul en fin de ligne. */
.fil-ariane li + li::before {
  content: "/";
  margin-right: 6px;
  color: var(--color-line);
}

/* #content-préfixé : sans cela, la règle générale des liens de contenu les
   souligne et les met au marine du corps de texte. */
#content .fil-ariane a {
  color: var(--color-ink-soft);
  text-decoration: none;
}

#content .fil-ariane a:hover {
  color: var(--color-accent);
  text-decoration: underline;
}

.fil-ariane [aria-current="page"] {
  color: var(--color-ink);
  font-weight: 500;
}

.dossier-field {
  display: flex;
  gap: 28px;
  padding: 18px 0;
  border-top: 1px solid var(--color-line-soft);
}

.dossier-field:last-child {
  border-bottom: 1px solid var(--color-line-soft);
}

.dossier-key {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-ink-soft);
  width: 140px;
  flex-shrink: 0;
  padding-top: 3px;
}

.dossier-val {
  font-family: var(--font-body);
  font-size: 15.5px;
  line-height: 1.6;
  color: var(--color-ink);
}

.dossier-val p {
  margin: 0 0 10px;
}

.dossier-val p:last-child {
  margin-bottom: 0;
}

#content .dossier-subheading {
  font-size: 18px;
  margin: 40px 0 4px;
}

.dossier-report {
  margin-top: 24px;
  text-align: right;
  font-size: 13px;
}

.dossier-report a {
  color: var(--color-ink-soft);
}

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

@media (max-width: 576px) {
  .dossier-field {
    flex-direction: column;
    gap: 4px;
  }
  .dossier-key {
    width: auto;
  }
  /* On mobile the title routinely wraps to 3-6 lines instead of desktop's
     one, making the 14/12px gaps meant for a short single-line title read
     as cramped against a much taller block of text. */
  .dossier-ref {
    margin-bottom: 18px;
  }
  #content .dossier-title {
    margin-bottom: 18px;
  }
}

/* ---------------------------------------------------
    SIDEBAR STYLE
----------------------------------------------------- */

/* Le dégagement de l'en-tête fixe est porté ici et non par #content : la barre
   latérale en a besoin autant que lui, et il doit être posé sur leur parent
   commun pour que la position STATIQUE de la barre soit déjà la bonne.

   Ne pas déplacer ce dégagement sur #content seul : `position: sticky` ne
   repousse un élément vers son seuil que s'il lui reste de la course dans son
   bloc conteneur, et rien ne garantit qu'elle existe. La barre passerait alors
   sous l'en-tête sans qu'aucune règle n'ait l'air fautive. */
.wrapper {
  display: flex;
  width: 100%;
  align-items: stretch;
  padding-top: var(--header-height);
}

/* Sidebar vs content: two zones, separated by a hairline border, not
   by a background-color difference — both are #fff. --color-paper
   is reserved here for interactive state (hover/active row tint),
   not as the sidebar's own resting background. */
#sidebar {
  min-width: 250px;
  max-width: 250px;
  background: #fff;
  color: var(--color-navy);
  transition: all 0.3s;
}

/* Défilement propre à la barre, au-dessus de 768px seulement : en dessous
   elle devient un panneau plein écran commandé par #sidebarCollapse, régime
   entièrement différent (voir MEDIAQUERIES).

   `top: var(--header-height)` cale la barre exactement sous l'en-tête fixe,
   de sorte que sa zone de défilement commence là où celui-ci finit ; un seuil
   plus haut masquerait ses premières lignes derrière lui à toute position.

   `overscroll-behavior: contain` est ce qui rend les deux zones vraiment
   indépendantes : sans lui, atteindre le bas de la barre enchaîne sur le
   défilement de la page. */
@media (min-width: 769px) {
  #sidebar {
    position: sticky;
    top: var(--header-height);
    /* Plafond et non hauteur fixe. `sticky` ne retient un élément que
       tant qu'il lui reste de la course dans son bloc conteneur — course qui
       vaut la hauteur du conteneur moins celle de l'élément. Une hauteur figée
       à 100vh moins l'en-tête l'annulerait dès que le contenu est court, et la
       barre repartirait vers le haut avec la page.

       En laissant `align-items: stretch` faire son travail, la barre prend la
       hauteur du contenu quand celui-ci est court (course nulle, mais la page
       ne défile pas non plus) et se plafonne à la fenêtre quand il est long
       (course égale au reste, donc elle tient jusqu'au pied de page). */
    max-height: calc(100vh - var(--header-height));
    border-right: 1px solid var(--color-line-soft);

    /* Colonne : l'arbre défile, le pied reste collé en bas. Le conteneur de
       défilement est donc .components et non #sidebar — c'est toute la
       différence entre un bloc épinglé et un bloc qu'il faut aller chercher au
       bout de la liste. static/js/main.js résout ce même conteneur pour
       conserver la position d'une page à l'autre : les deux doivent rester
       d'accord (voir sidebarScroller). */
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }

  #sidebar .components {
    flex: 1 1 auto;
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    /* La barre commence sous l'en-tête fixe : il ne reste qu'à donner
       de l'air au premier titre de groupe. */
    padding-top: 20px;
  }

  #sidebar .sidebar-footer {
    flex: 0 0 auto;
  }
}

/* Le lien de contribution, seul point d'entrée vers la page de soumission.
   Filet plutôt que fond : la barre et le contenu ne se séparent jamais par une
   différence de fond (voir les jetons), et cette frontière-là est interne. */
.sidebar-footer {
  border-top: 1px solid var(--color-line);
  padding: 6px 0;
}

/* Bloc plein et non simple lien : c'est le seul appel à contribuer de tout le
   site, et en lien discret au bas d'une colonne il se confondait avec les
   entrées de l'arbre juste au-dessus. Le fond le détache de la liste sans
   ajouter de couleur à la palette. */
#sidebar .sidebar-footer a {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin: 6px 16px;
  padding: 10px 12px;
  border-radius: 4px;
  background: var(--color-accent);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  color: #fff;
  transition: background-color 0.2s;
}

#sidebar .sidebar-footer a:hover {
  background: var(--color-accent-hover);
  color: #fff;
}

#sidebar .sidebar-footer a i {
  /* Ni marge ni taille propres : l'icône suit le texte, et l'écart est réglé
     une fois par le `gap` ci-dessus plutôt que sur chaque glyphe. */
  line-height: 1;
}

#sidebar ul p {
  color: var(--color-navy);
  padding: 10px;
}

#sidebar .components {
  padding: 20px 0;
}

/* Les catégories de premier niveau (« Enquête et instruction », etc.)
   commandent toute la lecture de la barre : elles doivent peser plus que les
   entrées qu'elles coiffent, jamais moins. Texte courant, gras, encre sombre —
   la même famille que le corps, deux crans au-dessus en taille et en
   contraste. */
.sidebar-group-label {
  display: block;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 600;
  color: var(--color-navy-deep);
  padding: 4px 24px 8px;
  /* Aligné sur les entrées qu'il coiffe par la même construction qu'elles,
     et non par un chiffre calculé à la main : celles-ci réservent 2px de
     bordure gauche transparente pour le liseré de l'entrée active, puis
     retirent de 20px (#sidebar ul ul a). Répliquer les deux déclarations
     maintient l'alignement si la largeur du liseré change. */
  border-left: 2px solid transparent;
  padding-left: 20px;
}

/* Sépare les groupes par l'espace seul. Un filet les refermerait en blocs
   distincts, alors qu'ils forment une seule progression — l'ordre
   chronologique de la procédure. Le gras des titres et cette respiration
   suffisent à les distinguer. */
#sidebar .components > li + li {
  margin-top: 26px;
}

#sidebar ul li a {
  padding: 7px 24px;
  font-size: 14px;
  font-family: var(--font-body);
  display: block;
  color: var(--color-navy);
  border-left: 2px solid transparent;
}

#sidebar ul li a:hover {
  color: var(--color-navy-deep);
  background: var(--color-paper);
}

#sidebar a[aria-expanded="true"] {
  color: var(--color-navy-deep);
}

a[data-bs-toggle="collapse"] {
  position: relative;
}

#sidebar .dropdown-toggle::after {
  content: "";
  display: block;
  position: absolute;
  top: 50%;
  right: 20px;
  width: 6px;
  height: 6px;
  border: none;
  border-right: 1.5px solid var(--color-ink-soft);
  border-bottom: 1.5px solid var(--color-ink-soft);
  transform: translateY(-50%) rotate(45deg);
  transition: transform 0.2s;
}

#sidebar .dropdown-toggle[aria-expanded="true"]::after {
  transform: translateY(-50%) rotate(-135deg);
}

#sidebar ul ul a {
  font-size: 13.5px;
  padding-left: 20px;
}

#sidebar ul ul ul a {
  font-size: 13px;
  padding-left: 32px;
}

#sidebar ul ul a.active {
  font-weight: 600;
  color: var(--color-accent);
  background: var(--color-paper);
  border-left-color: var(--color-accent);
}

/* .dropdown-toggle[aria-expanded="true"]:after {
    transform: rotate(180deg);
}

.dropdown-toggle:after {
    transition: 0.5s;
} */

/* ---------------------------------------------------
    CONTENT STYLE
----------------------------------------------------- */

/* Ni min-height ni dégagement d'en-tête ici : la pleine hauteur est garantie
   par body en colonne flex (voir GENERAL STYLE) et le dégagement par .wrapper,
   que le contenu partage avec la barre latérale. Ne reste que la respiration
   propre au contenu. */
#content {
  width: 100%;
  padding: 32px;
  transition: all 0.3s;
  background: #fff;
}

.btn {
  white-space: normal;
}

button#sidebarCollapse {
  display: none;
  color: var(--color-navy);
  background: white;
  border: none;
  font-size: 24px;
}

button#sidebarCollapse:focus {
  box-shadow: none;
}

/* Pagination */

#content .pagination {
  gap: 8px;
  margin-top: 28px;
}

#content .page-link {
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--color-navy);
  background: #fff;
  border: 1px solid var(--color-line);
  border-radius: 2px;
  margin-left: 0;
  padding: 8px 16px;
  text-decoration: none;
}

#content .page-link:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

#content .page-item.disabled .page-link {
  color: var(--color-ink-soft);
  opacity: 0.5;
  background: var(--color-paper);
  border-color: var(--color-line);
}

#content .page-item.active .page-link {
  background: var(--color-navy);
  border-color: var(--color-navy);
  color: #fff;
}

/* Decision prev/next pager: the "active" item repeats the current
   decision's full reference (already shown at the top of the dossier),
   styled after Bootstrap's single-digit "active page" pill. On mobile
   that long text wraps to 2 lines while the arrow buttons don't, so the
   row's items end up visibly different heights. Drop the redundant
   label instead of fighting its width — the two arrows plus the
   nav's own aria-label already convey prev/next. */
@media (max-width: 576px) {
  nav[aria-label="Décision précédente/suivante"] .page-item.active {
    display: none;
  }
}

/* Alerts */

.alert ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

#hideDiv {
  position: absolute;
  top: 90%;
  left: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  z-index: 9;
}

.messages {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* ---------------------------------------------------
    MEDIAQUERIES
----------------------------------------------------- */

@media (max-width: 768px) {
  body.overflow-off {
    overflow: hidden;
  }
  #sidebarCollapse span {
    display: none;
  }

  /* Le volet part du haut de l'écran : il lui faut son propre dégagement
     d'en-tête, celui de .wrapper ne s'appliquant qu'au flux normal. */
  #sidebar {
    min-width: 100%;
    position: fixed;
    z-index: 200;
    width: 100%;
    right: 200%;
    left: -100%;
    padding-top: var(--header-height);
    padding-bottom: 70px;
  }
  #sidebar.active {
    margin-left: 0;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
  }
  #sidebar.overflow-on {
    overflow-y: scroll;
  }
  button#sidebarCollapse {
    color: white;
    position: fixed;
    right: 40px;
    background-color: var(--color-accent);
    z-index: 201;
    bottom: 70px;
    border-radius: 50px;
    width: 40px;
    height: 40px;
    align-items: center;
    justify-content: center;
    display: flex;
  }
  .back-to-top {
    right: 40px;
  }
  .back-to-top.hide {
    opacity: 0;
    transition: all 0.4s;
  }
  button#sidebarCollapse:hover {
    background-color: var(--color-accent-hover);
  }
}

@media (max-width: 576px) {
  .text-xs-left {
    text-align: left !important;
  }
}

@media (min-width: 992px) {
  .text-lg-justify {
    text-align: justify !important;
  }
}

