/* ═══════════════════════════════════════════════════════════════════════
   MatchEthics — feuille de style unique (aucun framework, aucun CDN,
   aucune ressource externe : polices système, icônes SVG inline, logo de
   marque servi depuis static/marque/).
   Direction : « instrument de relevé » : papier froid, encre sapin,
   données en monospace. Signature : le bandeau de compteurs (dials) et
   les jauges de score. Le balayage du radar de l'en-tête a été retiré avec
   l'arrivée du logo de marque, qui est fixe.
   Palette : STRICTEMENT identique à la version précédente — seuls la
   typographie, l'espacement, la hiérarchie et le mouvement changent.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  /* ── Palette (conservée telle quelle) ── */
  --paper:   #eef1ee;   /* fond général, gris-vert froid */
  --card:    #ffffff;
  --ink:     #1b2420;
  --muted:   #5c6a62;
  --line:    #d3dbd4;
  --line-2:  #b9c4bb;
  --pine:    #0f5c49;   /* primaire */
  --pine-2:  #0b4436;
  --pine-t:  #e2efe9;   /* teinte pine très claire */
  --amber:   #9a640a;   /* signal « à valider » */
  --amber-t: #f6ecd7;
  --brick:   #a33d2e;   /* exclusions, erreurs */
  --brick-t: #f6e4e0;
  --blue:    #2c5f8a;   /* candidatures (déjà utilisé pour « postulées ») */
  --blue-t:  #e3ecf4;

  /* ── Surfaces dérivées (mode clair) ── */
  --surface-2: #fbfcfb;   /* champs, boutons */
  --card-2:    #fcfdfc;   /* barres d'outils, survols de carte */
  --row-hover: #f5f9f6;
  --row-new:   #fbfef9;
  --ink-2:     #38443d;   /* texte secondaire des cellules */

  /* ── Tokens dérivés (mêmes teintes, alpha uniquement) ── */
  --shadow-1: 0 1px 2px rgba(27, 36, 32, 0.05), 0 1px 4px rgba(27, 36, 32, 0.06);
  --shadow-2: 0 3px 8px rgba(27, 36, 32, 0.08), 0 8px 22px rgba(27, 36, 32, 0.07);
  --ring: 0 0 0 3px rgba(15, 92, 73, 0.18);
  --radius: 10px;
  --radius-s: 6px;
  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);

  --mono: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono", Consolas, monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
}

* { box-sizing: border-box; }

/* Les navigateurs donnent à <fieldset> un `min-width: min-content` non
   surchargeable autrement : le bloc refuse alors de descendre sous la largeur
   de son contenu et sort de l'écran. C'est ce qui faisait déborder la console
   de recherche à 375 px (464 px de large pour 375 px disponibles), alors
   qu'aucune règle du projet ne demandait cette largeur. */
fieldset { min-width: 0; }

/* Un champ de saisie a une largeur INTRINSÈQUE héritée de l'attribut `cols`
   ou `size` : le commentaire d'une candidature faisait 200 px dans une carte
   de 150 px et sortait de l'écran à 320 px. Aucun champ ne doit pouvoir
   dépasser la boîte qui le contient, quelle que soit cette largeur héritée. */
input, select, textarea, button { max-width: 100%; }

/* L'ATTRIBUT `hidden` DOIT GAGNER, et sans cette règle il perdait.
   Le navigateur le traduit par `display: none` dans sa propre feuille, mais
   une feuille d'auteur l'emporte toujours sur celle du navigateur, quelle
   que soit la spécificité. Mesuré sur le formulaire de CV : les blocs
   répétables portaient bien `hidden`, et `.cv-ligne { display: flex }`
   les affichait quand même, tous, à leur hauteur pleine (67 px par ligne de
   lien, 322 px par expérience). Le script masquait, le CSS démasquait.
   `!important` est ici le sens même de l'attribut : caché veut dire caché. */
[hidden] { display: none !important; }
html { font-size: 16px; scroll-behavior: smooth; }
body {
  margin: 0;
  background:
    radial-gradient(1100px 420px at 50% -160px, rgba(15, 92, 73, 0.055), transparent 70%),
    var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  line-height: 1.55;
  font-size: 0.96rem;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--pine); text-underline-offset: 2px; transition: color 0.15s var(--ease); }
a:hover { color: var(--pine-2); }

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

::selection { background: var(--pine-t); color: var(--pine-2); }

/* ── Mouvement d'entrée des sections ───────────────────────────────────── */

@keyframes fade-up {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
main > section, main > .stats-grid > section {
  animation: fade-up 0.45s var(--ease) backwards;
}
main > section:nth-child(2) { animation-delay: 0.05s; }
main > section:nth-child(3) { animation-delay: 0.10s; }
main > section:nth-child(4) { animation-delay: 0.15s; }
main > section:nth-child(5) { animation-delay: 0.20s; }
main > section:nth-child(6) { animation-delay: 0.25s; }

/* ── Barre supérieure ──────────────────────────────────────────────────── */

.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 0.7rem 1.4rem;
  background: linear-gradient(180deg, #212b26, #1b2420);
  color: #e9efe9;
  border-bottom: 3px solid var(--pine);
  transition: box-shadow 0.25s var(--ease);
}
.topbar.scrolled { box-shadow: 0 6px 18px rgba(27, 36, 32, 0.28); }

.brand { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
/* Logo + nom : UNE zone cliquable. Le lien hérite la couleur de la barre
   (aucune teinte nouvelle) et ne se souligne pas — il ne doit pas se lire
   comme un lien de texte au milieu d'un en-tête. */
.brand-lien {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  color: inherit;
  text-decoration: none;
  border-radius: var(--radius-s);
  padding: 0.15rem 0.25rem;
  margin: -0.15rem -0.25rem;
  transition: opacity 0.15s var(--ease);
}
.brand-lien:hover { opacity: 0.82; }
.brand-lien:focus-visible { box-shadow: var(--ring); outline: none; }
/* Logo de marque. Il remplace l'ancien radar dessiné en SVG, dont le balayage
   tournait en boucle (`@keyframes sweep-turn`, retiré avec lui) : le nouveau
   logo est fixe, et rien ne le remplace de ce côté.
   `display: block` sur l'image supprime l'espace que la ligne de base réserve
   sous un élément en ligne, qui décalait le logo de quelques pixels vers le
   haut par rapport au nom. */
.brand-logo { display: inline-flex; }
.brand-logo img { display: block; }
.brand-name {
  font-family: var(--mono);
  font-weight: 700;
  letter-spacing: 0.2em;
  font-size: 1rem;
}
.brand-sub { color: #9db3a7; font-size: 0.8rem; letter-spacing: 0.02em; }

/* `flex-wrap` manquait : sous ~700 px la navigation sortait de l'écran par
   la droite (mesuré à 375 px : bord droit à 675 px), et c'est elle qui
   rendait TOUTES les pages défilables horizontalement, y compris celles dont
   le contenu tenait très bien. Le débordement venait du gabarit commun, pas
   des pages. */
.topbar nav {
  display: flex;
  gap: 0.35rem;
  flex-wrap: wrap;
  justify-content: flex-end;
  min-width: 0;
}
/* Sans `min-width: 0`, un élément flex refuse de passer sous la largeur de
   son contenu : la marque poussait la navigation dehors au lieu de lui
   céder la place. */
.brand { min-width: 0; }

/* ── Menu de navigation repliable (zéro JavaScript) ──────────────────────── */

/* HABILLAGE DU MENU REPLIÉ, hors de tout palier de largeur.
   Ces règles vivaient dans `@media (max-width: 720px)`, ce qui les liait au
   portrait. Le menu replié sert désormais dans DEUX situations sans rapport
   entre elles : le portrait étroit, et le paysage tactile où la largeur est
   grande mais la hauteur minuscule. Un habillage recopié dans deux paliers
   finirait par diverger, d'où ce déplacement.
   Seul le `display` reste piloté par les paliers, plus bas dans la feuille :
   ces déclarations viennent AVANT eux, l'ordre de cascade fait le reste. */
.nav-repli { display: block; position: relative; }
.nav-bouton {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  list-style: none;
  cursor: pointer;
  padding: 0.4rem 0.7rem;
  /* Même traitement que le lien de navigation actif : aucune valeur de
     couleur nouvelle n'est introduite. */
  border: 1px solid var(--pine);
  border-radius: 6px;
  font-size: 0.88rem;
  color: #cfdcd2;
}
.nav-bouton::-webkit-details-marker { display: none; }
/* Chevron dessiné en CSS : aucune image, aucune police d'icônes. */
.nav-bouton::after {
  content: "";
  width: 0.42rem;
  height: 0.42rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
}
.nav-repli[open] > .nav-bouton { background: rgba(15, 92, 73, 0.4); color: #fff; }
.nav-repli[open] > .nav-bouton::after { transform: rotate(-135deg) translate(-2px, -2px); }

/* Panneau flottant, comme le menu « Actions » des documents : il se
   superpose au contenu au lieu de le repousser vers le bas. */
.nav-liens {
  display: flex;
  flex-direction: column;
  position: absolute;
  left: 0;
  top: calc(100% + 0.35rem);
  z-index: 45;
  min-width: min(13rem, calc(100vw - 2rem));
  padding: 0.3rem;
  background: #212b26;
  border: 1px solid var(--pine);
  border-radius: var(--radius-s);
  box-shadow: var(--shadow-2);
}
/* Le retrait des liens DANS le panneau reste conditionné, contrairement au
   reste de l'habillage. Ce sélecteur (0,3,1) est plus spécifique que
   `.topbar nav a` (0,2,1) et gagne quel que soit l'ordre : rendu
   inconditionnel, il s'appliquait aussi à la navigation de bureau, où les
   liens passaient de 6,08/12,8 px à 8,8/11,2 px. Mesuré à 1280 px.
   La virgule est un OU : les deux situations où le panneau existe vraiment. */
@media (max-width: 720px), (pointer: coarse) and (max-height: 500px) {
  .topbar nav .nav-liens a { padding: 0.55rem 0.7rem; }
}

/* Sur écran large, le <details> doit s'effacer : ses liens se comportent
   comme avant, et le bouton « Menu » n'a pas lieu d'être.

   ATTENTION, PIÈGE COÛTEUX : `display: contents` sur le <details> NE SUFFIT
   PAS. Le navigateur replie le contenu d'un <details> fermé via le
   pseudo-élément `::details-content` (`content-visibility: hidden`), qui
   s'applique quel que soit le `display` du conteneur. Les liens gardaient
   alors une boîte mesurable — d'où une vérification qui les croyait présents
   — mais n'étaient PAS peints : la navigation de bureau avait disparu.
   C'est donc ce pseudo-élément qu'il faut viser. */
/* Ces trois règles valent à partir de 721 px SEULEMENT : plus bas, le
   <details> doit redevenir un vrai <details> et se replier normalement. */
@media (min-width: 721px) {
  .nav-repli { display: contents; }
  .nav-bouton { display: none; }
  .nav-liens { display: contents; }
  .nav-repli::details-content { content-visibility: visible; }

  /* Repli de sécurité pour un navigateur qui ne connaîtrait pas
     `::details-content` : sans lui, les liens resteraient masqués ET leur
     bouton d'ouverture aussi, ce qui rendrait la navigation inatteignable.
     On préfère alors afficher le bouton « Menu » sur grand écran : moins
     joli, jamais cassé. */
  @supports not selector(::details-content) {
    .nav-repli { display: block; position: relative; }
    .nav-bouton { display: inline-flex; }
  }
}
.topbar nav a {
  position: relative;
  color: #cfdcd2;
  text-decoration: none;
  font-size: 0.88rem;
  padding: 0.38rem 0.8rem;
  border: 1px solid transparent;
  border-radius: 6px;
  transition: color 0.15s var(--ease), background 0.15s var(--ease), border-color 0.15s var(--ease);
}
.topbar nav a::after {
  content: "";
  position: absolute;
  left: 0.8rem;
  right: 0.8rem;
  bottom: 3px;
  height: 2px;
  border-radius: 2px;
  background: #7fc7ae;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.22s var(--ease);
}
.topbar nav a:hover { color: #fff; background: rgba(127, 199, 174, 0.08); }
.topbar nav a:hover::after { transform: scaleX(1); }
.topbar nav a.active {
  color: #fff;
  border-color: var(--pine);
  background: rgba(15, 92, 73, 0.4);
}
.topbar nav a.active::after { transform: scaleX(1); }

main { max-width: 1240px; margin: 0 auto; padding: 1.4rem 1.4rem 3rem; }

/* CAUSE RACINE d'un défaut observé sur /politique : un bloc qui se contraint
   en largeur (`max-width`) sans marges horizontales automatiques reste collé
   à GAUCHE de `main`, laissant tout le vide à droite. Sur un écran de
   1920 px : 22 px de vide à gauche, 482 px à droite.
   La règle est posée ICI, sur tous les enfants directs de `main`, plutôt que
   corrigée bloc par bloc : un élément pleine largeur n'est pas affecté (des
   marges automatiques y valent zéro), et le prochain bloc étroit qu'on
   ajoutera sera centré sans qu'on ait à y penser. */
main > * { margin-inline: auto; }

/* ── Étiquettes de panneau ─────────────────────────────────────────────── */

.panel-label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 0.8rem;
}
.panel-label::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 2px;
  background: var(--pine);
  opacity: 0.65;
  flex: none;
}
.panel-label a { font-weight: 400; letter-spacing: 0; text-transform: none; }

.count-badge {
  font-family: var(--mono);
  font-size: 0.72rem;
  background: var(--pine-t);
  color: var(--pine-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.05rem 0.5rem;
  letter-spacing: 0;
}

/* ── Bandeau de relevé (signature) ─────────────────────────────────────── */

.readout {
  /* FLEX plutôt que GRID, à dessein. Une grille `auto-fit` découpe des
     colonnes fixes : sept compteurs sur cinq colonnes laissaient trois
     cellules VIDES en fin de bandeau, visibles en gris parce que le fond du
     conteneur sert justement à dessiner les filets d'un pixel. En flex, les
     éléments de la dernière ligne s'étirent pour la remplir : plus aucun
     trou, quel que soit le nombre de compteurs et la largeur de l'écran.
     L'aspect (filets d'un pixel, coins arrondis) est identique. */
  display: flex;
  flex-wrap: wrap;
  gap: 1px;
  background: var(--line-2);
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 1.2rem;
  box-shadow: var(--shadow-1);
}
@keyframes dial-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}
.dial {
  position: relative;
  /* `1 1 132px` : même largeur plancher qu'avant, mais chaque compteur peut
     désormais s'étirer pour absorber la place restante de sa ligne. */
  flex: 1 1 132px;
  min-width: 0;
  background: var(--card);
  padding: 0.75rem 0.85rem 0.6rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  animation: dial-in 0.4s var(--ease) backwards;
  animation-delay: calc(var(--i, 0) * 55ms);
  transition: background 0.18s var(--ease);
}
.dial::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--line);
  transition: background 0.18s var(--ease);
}
.dial:hover { background: var(--card-2); }
.dial-n {
  font-family: var(--mono);
  font-size: 1.6rem;
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.dial-max { font-size: 0.85rem; color: var(--muted); font-weight: 400; }
.dial-l { font-size: 0.72rem; color: var(--muted); letter-spacing: 0.03em; }
.dial-new::before     { background: var(--pine); }
.dial-new .dial-n     { color: var(--pine); }
.dial-applied::before { background: var(--blue); }
.dial-applied .dial-n { color: var(--blue); }
.dial-check::before   { background: var(--amber); }
.dial-check .dial-n   { color: var(--amber); }
.dial-off::before     { background: var(--brick); }
.dial-off .dial-n     { color: var(--brick); }
.dial-budget { background: var(--pine-t); }
.dial-budget::before { background: var(--pine); }
.dial-budget:hover { background: var(--pine-t); }

/* ── Cartes ────────────────────────────────────────────────────────────── */

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.1rem 1.25rem;
  margin-bottom: 1.2rem;
  box-shadow: var(--shadow-1);
}

/* ── Console de recherche ──────────────────────────────────────────────── */

.search-console { border-top: 3px solid var(--pine); }
.search-fields {
  display: grid;
  /* `min(210px, 100%)` et non `210px` : un plancher fixe dans une grille
     `auto-fit` déborde dès que la place disponible est plus étroite que lui
     (mesuré sur /profil à 320 px : colonne de 290 px pour 249 px de place).
     Toutes les grilles de cette feuille suivent la même forme, pour que le
     défaut ne revienne pas par une seule d'entre elles. */
  grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
  gap: 1rem;
  margin-bottom: 0.9rem;
}
.search-fields label,
.doc-add label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--ink);
}
.hint { color: var(--muted); font-weight: 400; font-size: 0.8rem; }
p.hint { margin: 0.6rem 0 0; }

/* `input[type="email"]` MANQUAIT à cette liste : les deux champs « Adresse
   courriel » (inscription et Profil → Mon compte) n'héritaient donc d'AUCUNE
   de ces déclarations et retombaient sur le style par défaut du navigateur —
   fond blanc, texte noir, coins carrés, 1 px de rembourrage. Sur le thème
   sombre, ça donnait une bande blanche au milieu de champs sombres, et du
   texte noir sur blanc dans une carte sombre en cours de saisie. Mesuré côte
   à côte sur la même page : fond rgb(255,255,255) contre rgb(33,43,37) pour
   le champ voisin. Un type d'`input` oublié ici est invisible à la relecture :
   la règle a l'air complète, et seul le champ concerné trahit l'oubli. */
/* LA MÊME OMISSION S'EST REPRODUITE, et l'énumération en était la cause.
   `input[type="tel"]` manquait à son tour : le champ « Téléphone » du
   formulaire de CV n'héritait donc d'AUCUNE de ces déclarations. Mesuré sur
   la page : une seule règle du projet touchait ce champ, `input:focus`, qui
   pose un fond (`var(--card)`) sans jamais poser de couleur de texte. Au
   repos, le champ était blanc à texte noir au milieu de champs sombres ; à la
   frappe, le fond passait au vert sombre de la carte sous un texte resté noir
   par défaut du navigateur. Noir sur vert, pendant la saisie.

   La liste est donc remplacée par une EXCLUSION. Un type d'`input` oublié
   dans une énumération est invisible à la relecture — la règle a l'air
   complète — alors qu'un type non exclu est simplement stylé comme les
   autres. Le défaut penche désormais du bon côté. Les types réellement
   différents (case, bouton radio, fichier, envoi, caché) restent écartés :
   ils ont leur propre habillage.

   SPÉCIFICITÉ : un seul `:not()` à liste, et non dix `:not()` enchaînés.
   Une chaîne de dix vaudrait (0,10,1) et écraserait toute règle plus
   spécifique du projet — mesuré : la bordure d'un champ marqué invalide
   restait grise. Un `:not()` à liste prend la spécificité de son argument le
   plus précis, soit (0,1,1) : exactement celle de l'ancienne énumération. */
input:not([type="checkbox"], [type="radio"], [type="file"], [type="submit"], [type="button"], [type="reset"], [type="hidden"], [type="range"], [type="color"], [type="image"]),
select, textarea {
  font: inherit;
  font-size: 0.9rem;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--line-2);
  border-radius: var(--radius-s);
  background: var(--surface-2);
  color: var(--ink);
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease), background 0.15s var(--ease);
}
input:hover, select:hover, textarea:hover { border-color: var(--muted); }
input:focus, select:focus, textarea:focus {
  border-color: var(--pine);
  box-shadow: var(--ring);
  background: var(--card);
  outline: none;
}
/* ── Champs auto-remplis par le navigateur ──────────────────────────────
   Un champ auto-rempli reçoit un fond imposé par le navigateur (bleu très
   clair sur Chrome), peint DANS une couche que `background` ne remplace pas :
   sur le thème sombre, le texte clair du site s'y retrouve illisible. La
   seule prise reste une ombre interne assez épaisse pour couvrir la boîte,
   plus `-webkit-text-fill-color`, que le navigateur respecte là où il ignore
   `color`. Les valeurs viennent des variables de thème : clair et sombre
   suivent sans règle dupliquée.

   Deux blocs séparés, et non un sélecteur à virgules : si le navigateur ne
   connaît pas l'un des deux, il jette la règle ENTIÈRE — le correctif
   disparaîtrait là où il sert justement.

   La variante `:focus` est nécessaire : `input:-webkit-autofill` l'emporte en
   spécificité sur `input:focus`, l'anneau de mise au point serait donc perdu
   sur un champ auto-rempli. Les deux ombres cohabitent dans une même liste :
   l'anneau à l'extérieur, le fond à l'intérieur. */
input:-webkit-autofill,
input:-webkit-autofill:hover {
  box-shadow: inset 0 0 0 1000px var(--surface-2);
  -webkit-text-fill-color: var(--ink);
  caret-color: var(--ink);
}
input:-webkit-autofill:focus {
  box-shadow: var(--ring), inset 0 0 0 1000px var(--card);
  -webkit-text-fill-color: var(--ink);
  caret-color: var(--ink);
}
input:autofill,
input:autofill:hover {
  box-shadow: inset 0 0 0 1000px var(--surface-2);
  -webkit-text-fill-color: var(--ink);
  caret-color: var(--ink);
}
input:autofill:focus {
  box-shadow: var(--ring), inset 0 0 0 1000px var(--card);
  -webkit-text-fill-color: var(--ink);
  caret-color: var(--ink);
}

select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 1.7rem;
  /* chevron SVG encodé en data-URI : local, aucune requête réseau */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%235c6a62' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.6rem center;
}

.search-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  padding-top: 0.7rem;
  border-top: 1px dashed var(--line);
}
.pplx-opt { font-size: 0.85rem; display: flex; align-items: center; gap: 0.4rem; }
.pplx-opt em { color: var(--muted); font-style: normal; font-size: 0.8rem; }
.pplx-off { color: var(--muted); }

/* ── Boutons ───────────────────────────────────────────────────────────── */

.btn {
  font: inherit;
  font-size: 0.87rem;
  font-weight: 500;
  padding: 0.48rem 0.95rem;
  border: 1px solid var(--line-2);
  border-radius: var(--radius-s);
  background: var(--surface-2);
  color: var(--ink);
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  transition: border-color 0.15s var(--ease), color 0.15s var(--ease),
              background 0.15s var(--ease), transform 0.12s var(--ease),
              box-shadow 0.15s var(--ease);
}
.btn:hover {
  border-color: var(--pine);
  color: var(--pine-2);
  box-shadow: var(--shadow-1);
  transform: translateY(-1px);
}
.btn:active { transform: translateY(0) scale(0.985); box-shadow: none; }
.btn:focus-visible { box-shadow: var(--ring); outline: none; }
.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.btn-primary {
  background: linear-gradient(180deg, #12664f, var(--pine));
  border-color: var(--pine-2);
  color: #fff;
  font-weight: 600;
  box-shadow: 0 1px 2px rgba(11, 68, 54, 0.35);
}
.btn-primary:hover {
  background: linear-gradient(180deg, var(--pine), var(--pine-2));
  color: #fff;
  box-shadow: 0 3px 10px rgba(11, 68, 54, 0.3);
}
.btn-search { margin-left: auto; padding: 0.6rem 1.7rem; }
.btn-ghost { background: transparent; }
.btn-small { font-size: 0.77rem; padding: 0.28rem 0.6rem; }
.btn-danger:hover {
  border-color: var(--brick);
  color: var(--brick);
  background: var(--brick-t);
}

/* Bouton de recherche en attente : spinner CSS pur */
#btn-search.loading { opacity: 0.75; pointer-events: none; }
@keyframes spin { to { transform: rotate(360deg); } }
#btn-search.loading::before {
  content: "";
  width: 0.85em;
  height: 0.85em;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #fff;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

/* ── Messages flash ────────────────────────────────────────────────────── */

@keyframes flash-in {
  from { opacity: 0; transform: translateX(-6px); }
  to   { opacity: 1; transform: none; }
}
.flash-panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-left: 4px solid var(--pine);
  border-radius: var(--radius);
  padding: 0.85rem 1.05rem;
  margin-bottom: 1.2rem;
  box-shadow: var(--shadow-1);
}
.flash-panel ul { margin: 0; padding: 0; list-style: none; }
/* Une notification par ligne, lisible : pastille colorée, texte en police de
   lecture (l'ancienne police à chasse fixe donnait un aspect « journal de
   console » à des messages destinés à être lus). Rendues par le serveur —
   il n'y a jamais eu, et il n'y a toujours pas, d'alerte native ici. */
.flash {
  font-size: 0.86rem;
  line-height: 1.45;
  padding: 0.5rem 0.7rem;
  margin-bottom: 0.35rem;
  border: 1px solid var(--line-2);
  border-left: 3px solid var(--line-2);
  border-radius: var(--radius-s);
  background: var(--surface-2);
  display: flex;
  gap: 0.6rem;
  align-items: baseline;
  animation: flash-in 0.35s var(--ease) backwards;
  animation-delay: calc(var(--i, 0) * 60ms + 0.1s);
}
.flash:last-child { margin-bottom: 0; }
.flash::before {
  flex: none;
  font-weight: 700;
  line-height: 1.3;
}
.flash-ok            { border-left-color: var(--pine); }
.flash-ok::before    { content: "✓"; color: var(--pine); }
.flash-warn          { border-left-color: var(--amber); background: var(--amber-t); }
.flash-warn::before  { content: "⚠"; color: var(--amber); }
.flash-err           { border-left-color: var(--brick); background: var(--brick-t); }
.flash-err::before   { content: "✕"; color: var(--brick); }

/* ── Barre de filtres ──────────────────────────────────────────────────── */

.filterbar {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  flex-wrap: wrap;
  margin-bottom: 0.9rem;
}
.filters {
  display: flex;
  gap: 0.45rem;
  flex-wrap: wrap;
  align-items: center;
  flex: 1;
}
/* `min(240px, 100%)` et non `240px` : un plancher en pixels durs ne cède
   jamais, donc l'élément sort de son conteneur dès que la place est plus
   étroite que lui (mesuré : le champ « compétences » faisait 240 px dans un
   bloc de 218 px). La forme `min()` garde l'intention — un champ confortable
   quand la place existe — sans la transformer en exigence quand elle n'existe
   pas. Toute la feuille suit cette forme ; les seules largeurs qui restent en
   pixels PURS sont celles qui doivent rester des mesures physiques : la
   taille des zones tactiles, les jauges et les pastilles. */
.filters input[type="search"] { min-width: min(240px, 100%); flex: 1; }
.filters select, .filters input { font-size: 0.84rem; padding: 0.42rem 0.55rem; }
.filters select { padding-right: 1.6rem; }
.input-score { width: min(92px, 100%); }
.filter-check {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.82rem;
  /* `nowrap` convenait tant que ces étiquettes tenaient en deux mots. Depuis
     qu'elles portent une précision entre parenthèses, la ligne ne peut plus
     se couper et sort de l'écran (mesuré à 375 px : 433 px de large). Le
     retour à la ligne est autorisé, et l'alignement passe en haut pour que la
     case reste en face de la PREMIÈRE ligne du texte, pas au milieu du
     paragraphe. */
  flex-wrap: wrap;
  align-items: flex-start;
  max-width: 100%;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.15s var(--ease);
}
/* Une case à cocher dans un conteneur flex se laisse écraser sous sa taille
   propre quand le texte à côté est long : elle devenait un rectangle de
   13 x 24 px. `flex: none` lui rend sa taille. */
.filter-check input[type="checkbox"] { flex: none; }
/* Le texte, lui, doit pouvoir se couper : sans `min-width: 0`, un élément
   flex refuse de descendre sous la largeur de son contenu. */
.filter-check > span, .filter-check .hint { min-width: 0; white-space: normal; }
.filter-check:hover { color: var(--ink); }
input[type="checkbox"] { accent-color: var(--pine); width: 15px; height: 15px; cursor: pointer; }

/* Au doigt, 15 px est trop petit : le WCAG 2.5.8 demande 24 px au minimum.
   Le critère est le POINTEUR, pas la largeur d'écran — une tablette large se
   manipule au doigt elle aussi, et une petite fenêtre sur un portable se
   manipule à la souris. `pointer: coarse` pose exactement la bonne question. */
@media (pointer: coarse) {
  input[type="checkbox"], input[type="radio"] { width: 24px; height: 24px; }
  .filter-check { gap: 0.5rem; padding: 0.15rem 0; }
}

.hidden { display: none !important; }

/* ── Tableau des offres ────────────────────────────────────────────────── */

.table-card { padding: 0; overflow: hidden; }

/* Un tableau plus large que son écran doit DÉFILER dans sa carte, jamais
   déborder de la page ni se faire rogner. La règle existait, mais attachée à
   `.table-card` puis recopiée sur `.hist-card` : les tableaux de
   /admin, /admin/statistiques et /statistiques, eux, n'avaient rien et
   sortaient de leur carte (mesuré à 375 px : 678 px de large pour 375 px
   disponibles). Elle est donc posée une seule fois, pour TOUT tableau de
   carte, et les deux copies ont été retirées. */
.card table {
  display: block;
  overflow-x: auto;
}
/* Pas de `max-width` ici, volontairement : un bloc est déjà borné par son
   conteneur, et la déclaration écrasait par spécificité les largeurs voulues
   ailleurs (`.stats-table` passait de 680 px à 1153 px). */

.table-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.8rem;
  flex-wrap: wrap;
  padding: 0.7rem 1rem;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, var(--card-2), var(--surface-2));
}
.table-toolbar .panel-label { margin: 0; }
.table-toolbar .hint { flex: 1; }

table.jobs { border-collapse: collapse; width: 100%; font-size: 0.87rem; }
.jobs thead th {
  position: sticky;
  top: 0;
  background: var(--pine-t);
  color: var(--pine-2);
  font-family: var(--mono);
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: left;
  padding: 0.6rem 0.75rem;
  border-bottom: 2px solid var(--pine);
  z-index: 1;
  white-space: nowrap;
}
.jobs td {
  padding: 0.65rem 0.75rem;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
  transition: background 0.15s var(--ease);
}
.jobs tbody tr { transition: background 0.15s var(--ease), box-shadow 0.15s var(--ease); }
.jobs tbody tr:hover { background: var(--row-hover); }
.jobs tbody tr:hover td:first-child { box-shadow: inset 3px 0 0 var(--line-2); }
.row-nouveau { background: var(--row-new); }
.row-check td:first-child { box-shadow: inset 3px 0 0 var(--amber); }
.row-check:hover td:first-child { box-shadow: inset 3px 0 0 var(--amber); }
.row-postule { opacity: 0.78; }
.row-postule:hover { opacity: 1; }
tr.is-selected { background: var(--pine-t) !important; }
tr.is-selected td:first-child { box-shadow: inset 3px 0 0 var(--pine); }

.cell-check { width: 2.1rem; text-align: center; }
.cell-company strong { display: block; font-size: 0.9rem; }
.sub { display: block; color: var(--muted); font-size: 0.74rem; margin-top: 0.15rem; }
.cell-title { min-width: 210px; font-weight: 500; }
.col-desc { max-width: 360px; color: var(--ink-2); font-size: 0.82rem; }
/* `white-space: nowrap` a du sens pour ce que cette classe sert d'ordinaire :
   une date, un score, un nombre — des valeurs courtes qu'une coupure rendrait
   illisibles. Mais la classe sert AUSSI à afficher des chaînes techniques
   longues et insécables (l'URL de la base sur la page Administration), et là
   elle poussait la page entière : 49 px de débordement horizontal mesurés à
   320 px. Le `nowrap` est donc réservé aux CELLULES de tableau, où il protège
   un alignement de colonnes ; partout ailleurs, la chaîne peut se couper. */
.cell-mono, .cell-score {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}
td.cell-mono, td.cell-score {
  white-space: nowrap;
  overflow-wrap: normal;
}

/* Badges / pastilles */
.badges { display: block; margin-top: 0.3rem; }
.pill {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.04em;
  padding: 0.12rem 0.48rem;
  border-radius: 999px;
  border: 1px solid transparent;
  margin: 0 0.25rem 0.15rem 0;
  white-space: nowrap;
  transition: transform 0.12s var(--ease);
}
.pill:hover { transform: translateY(-1px); }
.pill-new     { background: var(--pine-t);  color: var(--pine-2); border-color: #bcd8cd; }
.pill-seen    { background: #eef0ee;        color: var(--muted);  border-color: var(--line-2); }
.pill-applied { background: var(--blue-t);  color: #24506f;       border-color: #bccfdf; }
/* pill-check : ambre du TEXTE assombri d'un cran (#9a640a → #8f5d09, même
   famille) — seule paire sous WCAG AA de tout l'audit (4.26:1 → 4.79:1) ;
   la variable --amber, elle, ne change nulle part ailleurs. */
.pill-check   { background: var(--amber-t); color: #8f5d09;       border-color: #e3ca97; cursor: help; }
.pill-known   { background: #f1f7ee;        color: #3c6b2f;       border-color: #cadfc0; cursor: help; }
.pill-remote  { background: #eef2f6;        color: #46617a;       border-color: #ccd8e2; }
.pill-agency  { background: #f3efe9;        color: #7a6242;       border-color: #ddd0bc; cursor: help; }

/* Score : jauge animée */
.score { font-weight: 700; font-size: 0.95rem; display: inline-block; }
.score-high { color: var(--pine); }
.score-mid  { color: var(--amber); }
.score-low  { color: var(--muted); }
@keyframes meter-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.meter {
  display: block;
  width: 64px;
  height: 5px;
  margin-top: 0.3rem;
  border-radius: 999px;
  background: var(--line);
  overflow: hidden;
}
.meter i {
  display: block;
  height: 100%;
  width: var(--w, 0%);
  border-radius: inherit;
  background: currentColor;
  transform-origin: left;
  animation: meter-fill 0.7s var(--ease) 0.15s backwards;
}

.job-link {
  font-family: var(--mono);
  font-size: 0.8rem;
  white-space: nowrap;
  text-decoration-color: rgba(15, 92, 73, 0.35);
}
.job-link:hover { text-decoration-color: currentColor; }

/* Statut / « J'ai postulé » */
.cell-status { min-width: 150px; }

/* Menu d'actions d'une offre. Sur écran large, `display: contents` fait
   disparaître la boîte du <details> : ses boutons redeviennent enfants
   directs de la cellule et se placent EXACTEMENT comme avant. Un <details>
   fermé dont la boîte a disparu n'a plus rien à replier, donc rien n'est
   masqué. Même technique que le menu de navigation. */
/* Même piège que pour la navigation, et même cadrage : c'est
   `::details-content` qui replie, pas le `display` du conteneur, et ces
   règles ne valent qu'à partir de 721 px. */
@media (min-width: 721px) {
  .offre-actions, .offre-actions-liste { display: contents; }
  .offre-actions-bouton { display: none; }
  .offre-actions::details-content { content-visibility: visible; }
  @supports not selector(::details-content) {
    .offre-actions { display: block; }
    .offre-actions-bouton { display: inline-flex; }
  }
}
.cell-status form { margin-top: 0.3rem; }
details.apply { margin-top: 0.35rem; }
details.apply summary {
  cursor: pointer;
  font-size: 0.78rem;
  color: var(--pine);
  text-decoration: underline;
  text-underline-offset: 2px;
  list-style: none;
  transition: color 0.15s var(--ease);
}
details.apply summary::-webkit-details-marker { display: none; }
details.apply summary:hover { color: var(--pine-2); }
@keyframes pop-in {
  from { opacity: 0; transform: translateY(-4px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}
details.apply[open] .apply-form { animation: pop-in 0.22s var(--ease); }
.apply-form {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.45rem;
  margin-top: 0.45rem;
  padding: 0.65rem;
  min-width: min(195px, 100%);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  box-shadow: var(--shadow-1);
}
.apply-form label {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.73rem;
  font-weight: 600;
  width: 100%;
}
.apply-form select { font-size: 0.78rem; padding: 0.3rem 1.5rem 0.3rem 0.45rem; max-width: 175px; }
.apply-form input[type="file"] { font-size: 0.75rem; max-width: 180px; }
.apply-form .hint { font-size: 0.7rem; }

/* ── Vide / exclues ────────────────────────────────────────────────────── */

.empty { padding: 2.4rem 1.2rem; text-align: center; color: var(--muted); }
.empty-tight { padding: 1.2rem; }
.empty p { margin: 0.3rem 0; }
.empty code {
  font-family: var(--mono);
  background: var(--pine-t);
  padding: 0.05rem 0.3rem;
  border-radius: 3px;
}
@keyframes radar-pulse {
  0%, 100% { opacity: 0.55; transform: scale(1); }
  50%      { opacity: 1;    transform: scale(1.06); }
}
.empty-radar {
  display: inline-flex;
  color: var(--line-2);
  margin-bottom: 0.5rem;
  animation: radar-pulse 3.2s var(--ease) infinite;
}

.excluded-zone { margin-top: 0.4rem; }
/* Zone des exclues : un repli, plus un rechargement. Le <summary> porte le
   même ton que l'ancien lien — c'est la mécanique qui change, pas le rang de
   l'information. */
.excluded-repli { margin-bottom: 1.2rem; }
.excluded-toggle {
  font-family: var(--mono);
  font-size: 0.76rem;
  color: var(--brick);
  cursor: pointer;
  padding: 0.4rem 0.2rem;
}
.excluded-toggle:hover { text-decoration: underline; }
.excluded-repli[open] > .excluded-toggle { margin-bottom: 0.4rem; }
.excluded-card { border-left: 4px solid var(--brick); }
.excluded-list { list-style: none; margin: 0; padding: 0; }
.excluded-list li {
  padding: 0.5rem 0;
  border-bottom: 1px dotted var(--line);
  font-size: 0.85rem;
  color: var(--muted);
}
.excluded-list li:last-child { border-bottom: 0; }
.excluded-list .sub { display: block; }
.excluded-item { display: flex; gap: 0.8rem; align-items: flex-start; }
.excluded-item-txt { flex: 1; min-width: 0; }

/* Motif d'exclusion : l'information sur laquelle repose la décision de
   récupérer ou de supprimer. Il doit pouvoir se couper — un motif cite un
   mot-clé et une catégorie, ce n'est pas une valeur courte. */
.excluded-motif {
  display: block;
  margin-top: 0.25rem;
  font-size: 0.78rem;
  color: var(--muted);
  overflow-wrap: anywhere;
}
/* Deux boutons côte à côte (Supprimer, Récupérer) : ils restent groupés à
   droite du texte plutôt que de s'empiler chacun sur sa ligne. */
.excluded-item .inline-form { flex-shrink: 0; }

/* ── Page documents ────────────────────────────────────────────────────── */

.upload-card { border-top: 3px solid var(--pine); }
.doc-add {
  display: flex;
  gap: 1rem;
  align-items: flex-end;
  flex-wrap: wrap;
  margin: 0.7rem 0 0.3rem;
}
.doc-add input[type="text"] { min-width: min(230px, 100%); }

/* Champ fichier habillé (l'input réel reste accessible au clavier) */
.file-pick { position: relative; display: flex; align-items: center; gap: 0.6rem; }
.file-pick input[type="file"] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}
.file-pick-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  font-weight: 500;
  padding: 0.48rem 0.9rem;
  border: 1px dashed var(--line-2);
  border-radius: var(--radius-s);
  background: var(--surface-2);
  color: var(--pine-2);
  transition: border-color 0.15s var(--ease), background 0.15s var(--ease);
  pointer-events: none;
}
.file-pick:hover .file-pick-btn { border-color: var(--pine); background: var(--pine-t); }
.file-pick:focus-within .file-pick-btn { border-color: var(--pine); box-shadow: var(--ring); }
.file-pick-name { font-size: 0.78rem; color: var(--muted); max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.doc-section { margin-bottom: 1.4rem; }
.doc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(290px, 100%), 1fr));
  gap: 0.9rem;
}
/* Une seule définition de carte pour « Mes documents » et pour la liste des
   comptes de l'administration : deux blocs jumeaux finiraient par diverger. */
.doc-card, .compte-carte {
  display: flex;
  gap: 0.85rem;
  align-items: flex-start;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0.95rem 1rem;
  box-shadow: var(--shadow-1);
  animation: fade-up 0.4s var(--ease) backwards;
  animation-delay: calc(var(--i, 0) * 60ms);
  transition: box-shadow 0.18s var(--ease), transform 0.18s var(--ease), border-color 0.18s var(--ease);
}
.doc-card:hover, .compte-carte:hover { box-shadow: var(--shadow-2); transform: translateY(-2px); }
.doc-principal { border-color: #bcd8cd; background: linear-gradient(180deg, var(--card-2), var(--card)); }

.doc-icon {
  position: relative;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 60px;
  border-radius: var(--radius-s);
  border: 1px solid var(--line);
}
.doc-icon-pdf  { color: var(--brick); background: var(--brick-t); border-color: #e8cdc6; }
.doc-icon-docx { color: var(--blue);  background: var(--blue-t);  border-color: #ccd8e2; }
/* Archive LaTeX générée (.zip à déposer sur Overleaf) — teinte de la palette. */
.doc-icon-zip  { color: var(--pine);  background: var(--pine-t);  border-color: #bcd8cd; }
.doc-ext {
  position: absolute;
  bottom: 4px;
  font-family: var(--mono);
  font-size: 0.55rem;
  font-weight: 700;
  letter-spacing: 0.08em;
}
.doc-body { flex: 1; min-width: 0; }
.doc-title {
  font-size: 0.95rem;
  font-weight: 600;
  margin: 0 0 0.2rem;
  overflow-wrap: anywhere;
}
.doc-meta { margin: 0.35rem 0 0; font-size: 0.78rem; color: var(--muted); line-height: 1.5; }
.doc-meta a { overflow-wrap: anywhere; }
.doc-actions {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  align-items: stretch;
}
.doc-actions .btn { justify-content: center; }

.inline-form { display: flex; gap: 0.3rem; align-items: center; }
.inline-form input { font-size: 0.8rem; padding: 0.28rem 0.5rem; width: min(160px, 100%); }

/* ── Page candidatures ─────────────────────────────────────────────────── */

.cell-docs { font-size: 0.8rem; min-width: 150px; line-height: 1.7; }
.cell-comment { max-width: 230px; }
.cell-comment summary {
  cursor: pointer;
  font-size: 0.8rem;
  color: var(--muted);
  transition: color 0.15s var(--ease);
}
.cell-comment summary:hover { color: var(--ink); }
.cell-comment details[open] summary { color: var(--pine-2); }
.comment-form { display: flex; flex-direction: column; gap: 0.35rem; margin-top: 0.4rem; animation: pop-in 0.22s var(--ease); }
/* `min-width: 200px` l'emportait sur toute limite de largeur : dans une carte
   de 150 px, le champ sortait de l'écran. `min()` garde l'intention (un champ
   confortable quand la place existe) sans la transformer en exigence quand
   elle n'existe pas. Même famille de défaut que `.cell-title`. */
.comment-form textarea { font-size: 0.8rem; min-width: min(200px, 100%); resize: vertical; }

/* Sélecteur de statut coloré selon l'état (palette existante) */
.statut-select {
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0.3rem 1.6rem 0.3rem 0.55rem;
  border-radius: 999px;
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease),
              background-color 0.25s var(--ease), color 0.25s var(--ease);
}
.st-attente  { background-color: var(--blue-t);  color: #24506f;      border-color: #bccfdf; }
.st-entrevue { background-color: var(--pine-t);  color: var(--pine-2); border-color: #bcd8cd; }
.st-offre    { background-color: var(--pine);    color: #ffffff;       border-color: var(--pine-2); }
.st-silence  { background-color: var(--amber-t); color: var(--amber);  border-color: #e3ca97; }
.st-refus    { background-color: var(--brick-t); color: var(--brick);  border-color: #e8cdc6; }

.danger-confirm summary {
  cursor: pointer;
  font-size: 0.78rem;
  color: var(--brick);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.danger-confirm form {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.45rem;
  padding: 0.65rem;
  border: 1px solid #e8cdc6;
  border-left: 3px solid var(--brick);
  border-radius: var(--radius-s);
  background: var(--brick-t);
  max-width: 245px;
  animation: pop-in 0.22s var(--ease);
}
.danger-confirm .hint { margin: 0; }
.danger-confirm input:focus {
  border-color: var(--brick);
  box-shadow: 0 0 0 3px rgba(163, 61, 46, 0.15);
}

/* ── Page statistiques ─────────────────────────────────────────────────── */

.stats-head { margin-bottom: 1rem; }
.stats-kpi { margin-bottom: 1.2rem; }
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(340px, 100%), 1fr));
  gap: 1.2rem;
  margin-bottom: 1.2rem;
}
.stats-grid .card { margin-bottom: 0; }
.stats-wide { grid-column: 1 / -1; }
.stats-card { transition: box-shadow 0.18s var(--ease); }
.stats-card:hover { box-shadow: var(--shadow-2); }

.chart-box { position: relative; height: 280px; margin-top: 0.4rem; }
.chart-conversion { height: 240px; }
.chart-entreprises { height: 320px; }

.stats-table { margin-top: 1rem; max-width: 680px; }
.stats-table .meter { width: 52px; display: inline-block; vertical-align: middle; margin: 0 0 0 0.45rem; }

/* ── Pied de page ──────────────────────────────────────────────────────── */

footer {
  max-width: 1240px;
  margin: 0 auto;
  padding: 1.1rem 1.4rem 2.2rem;
  color: var(--muted);
  font-size: 0.78rem;
  border-top: 1px solid var(--line);
}
footer p { margin: 0.3rem 0; }

/* Lien de pied de page : discret par construction, mais jamais illisible.
   Une politique de confidentialité qu'on ne trouve pas vaut autant qu'une
   politique qui n'existe pas. */
.footer-liens { margin-top: 0.7rem; }
.footer-liens a { color: var(--muted); text-decoration: underline; }
.footer-liens a:hover { color: var(--pine); }

/* ── Politique de confidentialité ──────────────────────────────────────── */
/* Colonne étroite : c'est un texte qui se LIT en entier, pas un tableau de
   bord qu'on balaie. Au-delà d'environ 70 caractères par ligne, l'oeil perd
   le début de la ligne suivante. */
.politique { max-width: 46rem; }
.politique h1 { font-size: 1.35rem; margin: 0 0 1rem; }
.politique h2 {
  font-size: 0.95rem;
  margin: 1.6rem 0 0.4rem;
  color: var(--pine);
}
.politique p, .politique li { line-height: 1.7; }
.politique ul { padding-left: 1.2rem; }
.politique li { margin-bottom: 0.7rem; }
.politique-fin {
  margin-top: 1.8rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--line);
  color: var(--muted);
  font-size: 0.88rem;
}

/* ── Responsive ────────────────────────────────────────────────────────── */

@media (max-width: 720px) {
  main { padding: 0.9rem 0.9rem 2rem; }
  .col-desc { display: none; }
  .btn-search { margin-left: 0; width: 100%; justify-content: center; }
  .brand-sub { display: none; }
  .doc-actions { flex-direction: row; }
  .chart-box { height: 240px; }

  /* La barre supérieure passe en deux lignes : marque au-dessus, navigation
     en dessous, alignée à gauche. Alignée à droite, elle laissait un trou
     irrégulier en fin de dernière ligne. */
  .topbar { padding: 0.6rem 0.9rem; gap: 0.5rem; }
  .topbar nav { justify-content: flex-start; width: 100%; }
  .topbar nav a { padding: 0.4rem 0.55rem; }

  /* ── Le menu redevient un vrai <details> ──────────────────────────────
     Les six liens occupaient TROIS rangées pleines avant le moindre contenu.
     Le conteneur reprend une boîte, donc le navigateur replie de nouveau ses
     enfants : il ne reste qu'un bouton « Menu » sur une ligne, et les liens
     s'affichent en panneau, par-dessus la page, quand on l'ouvre. Aucun
     script : c'est le pliage natif de <details>.
     L'habillage du bouton et du panneau vit plus haut dans cette feuille,
     hors palier : il est partagé avec le paysage tactile. Ici, seul le
     `display` est rétabli, pour annuler le dépliage du palier 721 px. */
  .nav-repli { display: block; position: relative; }
  .nav-bouton { display: inline-flex; }
  .nav-liens { display: flex; }

  /* ── Offres : la rangée de tableau devient une carte ────────────────────
     CAUSE DU GRAND VIDE signalé sur un vrai téléphone. Dans un tableau,
     TOUTES les cellules d'une rangée prennent la hauteur de la plus haute.
     Ici la cellule de statut porte le bloc « Générer CV/lettre » : 230 px de
     contenu, contre 38 px pour la case, 117 px pour l'entreprise et 90 px
     pour le titre. Avec `vertical-align: top`, les trois premières collaient
     leur contenu en haut et laissaient 100 à 200 px de vide dessous. C'est le
     même mécanisme que le défaut corrigé au round précédent sur les champs de
     recherche : une contrainte d'alignement qui a du sens quand les colonnes
     se lisent côte à côte, et qui devient un trou dès qu'on n'en voit qu'une
     partie.
     La rangée cesse donc d'être une rangée : chaque cellule devient un bloc
     dans une grille à deux colonnes (case à cocher, puis tout le reste
     empilé). Plus de hauteur partagée, donc plus de vide. Et comme il n'y a
     plus de colonnes à aligner, le tableau n'a plus besoin de faire 824 px de
     large : le défilement horizontal du tableau disparaît par la même
     occasion. */
  .jobs, .jobs tbody { display: block; }
  .jobs thead { display: none; }
  /* FLEX et non grille : les cellules courtes (date, score, lien) se placent
     alors d'elles-mêmes côte à côte sur une ligne, au lieu d'occuper chacune
     une ligne presque vide. Les cellules longues demandent la largeur pleine
     avec `flex-basis: 100%`. */
  .jobs tbody tr {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.25rem 0.7rem;
    padding: 0.8rem 0.9rem;
    border-bottom: 1px solid var(--line);
  }
  .jobs tbody td {
    display: block;
    flex: 0 0 auto;
    padding: 0;
    border: none;
    min-width: 0;
  }
  /* La description brève reste masquée, comme avant : elle doublerait la
     hauteur de chaque carte pour une information secondaire. La règle est
     répétée ici parce que `.jobs tbody td` ci-dessus l'emporterait sur le
     `.col-desc { display: none }` général, plus faible en spécificité. */
  .jobs tbody td.col-desc { display: none; }

  .jobs tbody td.cell-check { width: auto; }
  .jobs tbody td.cell-company { flex: 1 1 auto; }
  .jobs tbody td.cell-company strong { font-size: 0.82rem; font-weight: 500; color: var(--muted); }
  /* `min-width: 210px` gardait une colonne de titre lisible dans le tableau ;
     en carte, il empêcherait la ligne de descendre sous 210 px. */
  /* Ces trois `min-width` (210 px, 150 px, 150 px) servent à garder des
     colonnes lisibles DANS un tableau ; en carte, ils empêcheraient la
     ligne de descendre sous leur valeur. On les neutralise ici plutôt que de
     les passer en `min(…, 100%)` : dans un tableau, un pourcentage se résout
     contre la largeur de la table et changerait le calcul des colonnes sur
     grand écran, là où ils rendent justement service. */
  .jobs tbody td.cell-status, .jobs tbody td.cell-docs { min-width: 0; }
  .jobs tbody td.cell-title {
    flex: 1 1 100%;
    min-width: 0;
    font-size: 0.95rem;
    font-weight: 600;
  }
  .jobs tbody td.cell-status { flex: 1 1 100%; margin-top: 0.25rem; }

  /* ── Actions de l'offre : un seul bouton au lieu de trois blocs ─────────
     Empilée en carte, chaque offre affichait « J'ai postulé », « Générer
     CV/lettre », sa case Perplexity et « Marquer vu » les uns sous les
     autres : quatre commandes pour une offre qu'on est en train de survoler.
     Elles passent derrière un bouton unique. Le pliage est celui du
     navigateur, pas le nôtre. */
  .offre-actions { display: block; position: relative; margin-top: 0.4rem; }
  .offre-actions-bouton {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    list-style: none;
    cursor: pointer;
    padding: 0.4rem 0.75rem;
    border: 1px solid var(--line-2);
    border-radius: var(--radius-s);
    background: var(--surface-2);
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--ink-2);
  }
  .offre-actions-bouton::-webkit-details-marker { display: none; }
  /* Chevron dessiné en CSS, comme celui du menu de navigation. */
  .offre-actions-bouton::after {
    content: "";
    width: 0.4rem;
    height: 0.4rem;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg) translate(-1px, -1px);
  }
  .offre-actions[open] > .offre-actions-bouton {
    background: var(--pine-t);
    color: var(--pine-2);
    border-color: var(--pine);
  }
  .offre-actions[open] > .offre-actions-bouton::after {
    transform: rotate(-135deg) translate(-2px, -2px);
  }
  /* Les actions s'ouvrent DANS le flux et non en panneau flottant : une carte
     d'offre est déjà un bloc à part entière, un panneau superposé masquerait
     l'offre suivante sans rien gagner. */
  .offre-actions-liste {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.45rem;
    margin-top: 0.5rem;
    padding: 0.6rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-s);
    background: var(--surface-2);
  }
  .offre-actions-liste > * { margin: 0; }
  /* Date, score et lien partagent une ligne : la jauge du score est un bloc,
     donc l'alignement par la ligne de base plaçait le nombre au-dessus des
     deux autres. En les centrant verticalement, les trois se lisent d'un
     seul balayage. */
  .jobs tbody td.cell-mono,
  .jobs tbody td.cell-score,
  .jobs tbody td.cell-lien { align-self: center; }
  .jobs tbody td.cell-score { display: flex; align-items: center; gap: 0.4rem; }
  /* Le liseré vertical d'une rangée « à valider » passait par un `box-shadow`
     posé sur la première cellule ; en carte, il se lit mieux comme bordure de
     la carte entière. */
  .jobs tbody tr:hover td:first-child, .row-check td:first-child { box-shadow: none; }
  .row-check { border-left: 3px solid var(--amber); }
  tr.is-selected td:first-child { box-shadow: none; }

  /* Le menu d'actions d'un compte était plus large que l'écran (20 rem
     minimum imposés) : il sortait de la carte au lieu de s'y adapter. */
  .compte-menu .doc-menu-panneau { min-width: 0; width: 100%; }

  /* Un texte de politique n'a pas besoin d'être bridé quand l'écran est déjà
     plus étroit que la limite de confort de lecture. */
  .politique { max-width: none; }

}

/* Entre la tablette et le petit portable, la navigation tient sur une ligne à
   quelques pixels près : les six liens occupaient 691 px pour 723 px
   disponibles, et la bascule de thème (34 px) partait seule à la ligne
   suivante. Resserrer les liens de quelques pixels suffit à tout garder sur
   une ligne, sans changer leur taille de texte ni leur zone cliquable
   verticale. */
@media (min-width: 721px) and (max-width: 1024px) {
  .topbar nav { gap: 0.2rem; }
  .topbar nav a { padding: 0.38rem 0.5rem; }
}

/* ── Téléphone en paysage : la largeur ment sur le pointeur ──────────────
   DÉFAUT MESURÉ (767 x 375, pointeur tactile émulé) : les six liens du menu
   mesuraient 30,7 px de haut et se suivaient à 4,06 px d'écart.

   La cause est le critère de bascule. Un téléphone couché dépasse 721 px de
   large : il quitte donc le menu repliable et reçoit la navigation en ligne,
   puis le resserrement ci-dessus, prévu pour une fenêtre de bureau étroite
   manipulée à la souris. La largeur a augmenté, le doigt non.

   Le critère juste est le POINTEUR, comme pour les cases à cocher plus haut.
   `pointer: coarse` reste vrai en paysage, en portrait et sur tablette, quelle
   que soit la largeur. Le bloc vient APRÈS le resserrement pour l'annuler.
   Les liens peuvent passer à la ligne, la barre porte déjà `flex-wrap`, et
   deux rangées atteignables valent mieux qu'une rangée manquée. */
@media (pointer: coarse) {
  .topbar nav a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0.55rem 0.7rem;
    /* MARGE et non `gap` du conteneur, après vérification : les liens ne sont
       pas des enfants flex de `.topbar nav`. Ils vivent dans le
       `::details-content` du menu repliable, que `display: contents` ne fait
       pas disparaître. Mesuré en direct : porter le `gap` de la barre à 40 px
       laisse l'écart des liens à 4,06 px, une marge de 6 px le porte à
       16,06 px. Ces 4,06 px sont l'espace blanc du gabarit entre deux balises,
       et c'est tout ce qui séparait deux cibles tactiles. */
    margin-inline: 0.25rem;
  }
  /* Le soulignement d'onglet actif suit le nouveau retrait horizontal. */
  .topbar nav a::after { left: 0.7rem; right: 0.7rem; }
}

/* ── Téléphone couché : la barre tient sur UNE rangée ────────────────────
   DÉFAUT MESURÉ (767 x 375, pointeur tactile) : la barre occupait 144,80 px,
   soit 38,6 % de la hauteur visible, sur trois zones empilées. La marque
   tenait la première, les six liens la deuxième, « Se déconnecter » et la
   bascule de thème la troisième. Elle est en `position: sticky`, donc ces
   38,6 % restent pris pendant tout le défilement.

   La cause est un simple calcul de place : la marque fait 474 px avec son
   sous-titre, la navigation dépliée en réclame 722, pour 722 px utiles. Rien
   ne peut tenir sur une rangée dans ces conditions, et les six liens seuls en
   demandent déjà 645.

   Le critère est le POINTEUR croisé avec la HAUTEUR, jamais l'orientation :
   `orientation: landscape` est vrai aussi sur un écran de bureau, et la
   largeur ne dit rien du doigt. Sous 500 px de haut et au doigt, la marque
   perd son sous-titre et la navigation reprend le menu replié déjà utilisé en
   portrait. Mesuré : 186 + 61 + 116 + 35 px et trois gouttières, soit 446 px
   pour 722 disponibles.

   AUCUN SCRIPT n'est nécessaire, et c'est ce qui a fait retenir cette voie
   plutôt qu'un masquage au défilement : rien à charger, rien qui puisse
   échouer, et la barre ne disparaît jamais sous le doigt.

   Les cibles tactiles gardent leurs 44 px : compacité et zone atteignable ne
   s'opposent pas ici, parce que la place gagnée vient du nombre de rangées,
   pas de la taille des boutons. */
@media (pointer: coarse) and (max-height: 500px) {
  .topbar { padding: 0.3rem 0.9rem; gap: 0.55rem; }
  /* Le sous-titre coûte 279 px sur 474 et ne porte aucune information dont
     dépend une action. Il est déjà masqué en portrait, pour la même raison. */
  .brand-sub { display: none; }

  /* La navigation se replie, comme en portrait. Seul le `display` est
     rétabli : l'habillage du bouton et du panneau est commun aux deux cas et
     vit en haut de cette feuille. */
  .nav-repli { display: block; position: relative; }
  .nav-bouton { display: inline-flex; min-height: 44px; }
  .nav-liens { display: flex; }
  /* Le palier 721 px force l'ouverture du contenu du <details> pour déplier
     la navigation de bureau. Il faut lui rendre son comportement normal,
     sinon le panneau resterait affiché en permanence. */
  .nav-repli:not([open])::details-content { content-visibility: hidden; }
  .nav-repli[open]::details-content { content-visibility: visible; }

  /* Le bouton est à droite de la barre : le panneau s'aligne sur son bord
     droit, sinon il sortirait de l'écran. Il défile au besoin, une hauteur de
     375 px ne pouvant pas toujours contenir six entrées de 44 px. */
  .nav-liens {
    left: auto;
    right: 0;
    max-height: calc(100vh - 4.5rem);
    overflow-y: auto;
  }

  /* « Se déconnecter » mesurait 31,42 px, en dehors du correctif du lot
     précédent qui ne visait que les liens de navigation. Le porter à 44 px
     ne coûte rien en hauteur : la rangée est déjà à 44 px, imposée par le
     bouton « Menu » voisin. */
  .logout-btn { min-height: 44px; }
}

/* ── Accessibilité : mouvement réduit ──────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  html { scroll-behavior: auto; }
}

/* ═══════════════════════════════════════════════════════════════════════
   MODE SOMBRE — déclinaison cohérente de la palette (pas une inversion
   brute) : mêmes familles de teintes, éclaircies pour le contraste sur
   fonds encre. Activé par html[data-theme="sombre"], rendu CÔTÉ SERVEUR
   depuis le cookie fonctionnel « radar-theme » (formulaire de bascule) ;
   défaut sans choix = prefers-color-scheme (bloc @media plus bas).
   ═══════════════════════════════════════════════════════════════════════ */

html[data-theme="sombre"] {
  --paper:   #121814;
  --card:    #1a221d;
  --ink:     #e3eae4;
  --muted:   #97a89d;
  --line:    #2b362f;
  --line-2:  #3d4a42;
  --pine:    #46a585;   /* primaire éclairci (contraste sur fond sombre) */
  --pine-2:  #6fc2a4;
  --pine-t:  #20342b;
  --amber:   #d9a04a;
  --amber-t: #362b17;
  --brick:   #d4796a;
  --brick-t: #38221d;
  --blue:    #82aed1;
  --blue-t:  #1e2a35;

  --surface-2: #212b25;
  --card-2:    #1e2823;
  --row-hover: #202a24;
  --row-new:   #1d2721;
  --ink-2:     #bcc8bf;

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 4px rgba(0, 0, 0, 0.25);
  --shadow-2: 0 3px 8px rgba(0, 0, 0, 0.35), 0 8px 22px rgba(0, 0, 0, 0.3);
  --ring: 0 0 0 3px rgba(70, 165, 133, 0.25);
}

/* Transition douce entre les deux thèmes */
body, .card, .dial, .readout, .table-toolbar, .apply-form, .doc-card,
input, select, textarea, .btn {
  transition-property: background-color, background, border-color, color, box-shadow;
  transition-duration: 0.2s;
  transition-timing-function: var(--ease);
}

/* Chevron des <select> en version claire sur fond sombre */
html[data-theme="sombre"] select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%2397a89d' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* Pastilles : mêmes familles de teintes, versions sombres dédiées */
html[data-theme="sombre"] .pill-new     { background: #20342b; color: #8fd3b8; border-color: #31584a; }
html[data-theme="sombre"] .pill-seen    { background: #242d27; color: var(--muted); border-color: var(--line-2); }
html[data-theme="sombre"] .pill-applied { background: #1e2a35; color: #9cc0de; border-color: #2f4a60; }
html[data-theme="sombre"] .pill-check   { background: #362b17; color: #e0b269; border-color: #5c4a26; }
html[data-theme="sombre"] .pill-known   { background: #22301f; color: #a3cf90; border-color: #3a5233; }
html[data-theme="sombre"] .pill-remote  { background: #212b34; color: #a4bdd3; border-color: #374d5f; }
html[data-theme="sombre"] .pill-agency  { background: #2f2a20; color: #c4a97e; border-color: #4d4231; }

/* Sélecteur de statut des candidatures */
html[data-theme="sombre"] .st-attente  { background-color: #1e2a35; color: #9cc0de; border-color: #2f4a60; }
html[data-theme="sombre"] .st-entrevue { background-color: #20342b; color: #8fd3b8; border-color: #31584a; }
html[data-theme="sombre"] .st-offre    { background-color: var(--pine); color: #0f1d17; border-color: var(--pine-2); }
html[data-theme="sombre"] .st-silence  { background-color: #362b17; color: #e0b269; border-color: #5c4a26; }
html[data-theme="sombre"] .st-refus    { background-color: #38221d; color: #dd9c8f; border-color: #57352d; }

/* Icônes de documents et zone de suppression */
html[data-theme="sombre"] .doc-icon-pdf  { border-color: #57352d; }
html[data-theme="sombre"] .doc-icon-docx { border-color: #2f4a60; }
html[data-theme="sombre"] .doc-icon-zip  { border-color: #2c4a3e; }
html[data-theme="sombre"] .danger-confirm form { border-color: #57352d; }
html[data-theme="sombre"] .btn-primary {
  background: linear-gradient(180deg, #1d7a5f, #14604a);
  border-color: #0f5c49;
  color: #ffffff;
}
html[data-theme="sombre"] .btn-primary:hover {
  background: linear-gradient(180deg, #23906f, #187055);
}

/* ── Défaut SYSTÈME sans choix enregistré (aucun JavaScript) ─────────────
   Sans cookie « radar-theme », <html> n'a pas d'attribut data-theme : le
   mode sombre suit prefers-color-scheme. Ce bloc est la COPIE CONFORME du
   bloc html[data-theme="sombre"] ci-dessus — toute retouche du thème
   sombre doit être reportée ici (vérifié par un test). ─────────────────── */

@media (prefers-color-scheme: dark) {
  html:not([data-theme]) {
    --paper:   #121814;
    --card:    #1a221d;
    --ink:     #e3eae4;
    --muted:   #97a89d;
    --line:    #2b362f;
    --line-2:  #3d4a42;
    --pine:    #46a585;   /* primaire éclairci (contraste sur fond sombre) */
    --pine-2:  #6fc2a4;
    --pine-t:  #20342b;
    --amber:   #d9a04a;
    --amber-t: #362b17;
    --brick:   #d4796a;
    --brick-t: #38221d;
    --blue:    #82aed1;
    --blue-t:  #1e2a35;

    --surface-2: #212b25;
    --card-2:    #1e2823;
    --row-hover: #202a24;
    --row-new:   #1d2721;
    --ink-2:     #bcc8bf;

    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 4px rgba(0, 0, 0, 0.25);
    --shadow-2: 0 3px 8px rgba(0, 0, 0, 0.35), 0 8px 22px rgba(0, 0, 0, 0.3);
    --ring: 0 0 0 3px rgba(70, 165, 133, 0.25);
  }

  /* Transition douce entre les deux thèmes */
  body, .card, .dial, .readout, .table-toolbar, .apply-form, .doc-card,
  input, select, textarea, .btn {
    transition-property: background-color, background, border-color, color, box-shadow;
    transition-duration: 0.2s;
    transition-timing-function: var(--ease);
  }

  /* Chevron des <select> en version claire sur fond sombre */
  html:not([data-theme]) select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%2397a89d' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  }

  /* Pastilles : mêmes familles de teintes, versions sombres dédiées */
  html:not([data-theme]) .pill-new     { background: #20342b; color: #8fd3b8; border-color: #31584a; }
  html:not([data-theme]) .pill-seen    { background: #242d27; color: var(--muted); border-color: var(--line-2); }
  html:not([data-theme]) .pill-applied { background: #1e2a35; color: #9cc0de; border-color: #2f4a60; }
  html:not([data-theme]) .pill-check   { background: #362b17; color: #e0b269; border-color: #5c4a26; }
  html:not([data-theme]) .pill-known   { background: #22301f; color: #a3cf90; border-color: #3a5233; }
  html:not([data-theme]) .pill-remote  { background: #212b34; color: #a4bdd3; border-color: #374d5f; }
  html:not([data-theme]) .pill-agency  { background: #2f2a20; color: #c4a97e; border-color: #4d4231; }

  /* Sélecteur de statut des candidatures */
  html:not([data-theme]) .st-attente  { background-color: #1e2a35; color: #9cc0de; border-color: #2f4a60; }
  html:not([data-theme]) .st-entrevue { background-color: #20342b; color: #8fd3b8; border-color: #31584a; }
  html:not([data-theme]) .st-offre    { background-color: var(--pine); color: #0f1d17; border-color: var(--pine-2); }
  html:not([data-theme]) .st-silence  { background-color: #362b17; color: #e0b269; border-color: #5c4a26; }
  html:not([data-theme]) .st-refus    { background-color: #38221d; color: #dd9c8f; border-color: #57352d; }

  /* Icônes de documents et zone de suppression */
  html:not([data-theme]) .doc-icon-pdf  { border-color: #57352d; }
  html:not([data-theme]) .doc-icon-docx { border-color: #2f4a60; }
  html:not([data-theme]) .doc-icon-zip  { border-color: #2c4a3e; }
  html:not([data-theme]) .danger-confirm form { border-color: #57352d; }
  html:not([data-theme]) .btn-primary {
    background: linear-gradient(180deg, #1d7a5f, #14604a);
    border-color: #0f5c49;
    color: #ffffff;
  }
  html:not([data-theme]) .btn-primary:hover {
    background: linear-gradient(180deg, #23906f, #187055);
  }
}


/* ── Bouton de bascule clair/sombre (dans la barre, toujours sombre) ───── */

.theme-toggle {
  margin-left: 0.35rem;
  padding: 0.42rem 0.55rem;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  color: #cfdcd2;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  transition: color 0.15s var(--ease), border-color 0.15s var(--ease),
              background 0.15s var(--ease), transform 0.12s var(--ease);
}
.theme-toggle:hover { color: #fff; border-color: #40544a; transform: translateY(-1px); }
.theme-toggle:active { transform: none; }
.theme-toggle svg { display: block; }
/* `.theme-toggle .icon-sun` et non `.icon-sun` seul : la règle de masquage
   doit peser plus lourd que `.theme-toggle svg` juste au-dessus, qui vaut
   (0,1,1). Avec une seule classe elle valait (0,1,0), perdait, et LES DEUX
   icônes se peignaient en thème clair — boîte de 50 px au lieu de 35. Le
   thème sombre n'était pas touché : ses règles portent `html[data-theme]`
   en plus, donc (0,2,1), et l'emportaient déjà. Passer à (0,2,0) suffit ici
   et laisse les règles de thème, plus spécifiques, garder la main. */
.theme-toggle .icon-sun { display: none; }
html[data-theme="sombre"] .icon-sun { display: block; }
html[data-theme="sombre"] .icon-moon { display: none; }
@media (prefers-color-scheme: dark) {
  html:not([data-theme]) .icon-sun { display: block; }
  html:not([data-theme]) .icon-moon { display: none; }
}
/* Formulaire de bascule : transparent pour la mise en page de la barre */
.theme-form { display: contents; }

/* ── Console de recherche : champs alignés sur une même ligne de base ──── */

/* Les cellules de cette grille n'ont pas la même hauteur : certaines
   étiquettes portent une longue précision entre parenthèses, d'autres non.
   L'ancien `justify-content: flex-end` alignait bien les champs en bas, mais
   au prix d'étiquettes qui « flottaient » à des hauteurs différentes, avec un
   vide au-dessus des plus courtes. En repartant du haut et en poussant le
   seul champ vers le bas, les DEUX se tiennent : titres alignés en haut,
   champs alignés en bas. */
.search-fields label { justify-content: flex-start; }
.search-fields label > input,
.search-fields label > select { margin-top: auto; }

/* ── Page profil ───────────────────────────────────────────────────────── */

.profil-alerte { border-left: 4px solid var(--amber); background: var(--amber-t); }
.profil-alerte p { margin: 0; }

.gemini-card { border-top: 3px solid var(--blue); }
.gemini-form { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 0.6rem; align-items: flex-start; }
.gemini-form textarea { width: 100%; }

.suggestion-banner { border-left: 4px solid var(--blue); background: var(--blue-t); }
.suggestion-banner .hint { color: inherit; opacity: 0.85; }

.profil-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(290px, 100%), 1fr));
  gap: 1.1rem;
}
.profil-grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); }
.profil-grid label, .profil-stack label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.84rem;
  font-weight: 600;
}
.profil-wide { grid-column: 1 / -1; }
/* Un `label.profil-wide` posé DIRECTEMENT dans une carte, sans grille autour
   (liste noire personnelle), n'était atteint par aucune règle : il restait
   `display: inline`, et son libellé se retrouvait à CÔTÉ du champ au lieu
   d'être au-dessus. Mêmes valeurs que `.profil-grid label` : dans une grille,
   rien ne change. */
label.profil-wide {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.84rem;
  font-weight: 600;
}
.profil-stack { display: flex; flex-direction: column; gap: 1rem; }
.profil-grid textarea { font-family: var(--mono); font-size: 0.82rem; line-height: 1.6; }
.profil-fieldset {
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  padding: 0.7rem 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  margin: 0;
}
.profil-fieldset legend { font-size: 0.8rem; font-weight: 600; padding: 0 0.35rem; }
.profil-actions { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }

/* ── Sélecteur de sources (console de recherche) ───────────────────────── */

.sources-select {
  border: 1px dashed var(--line-2);
  border-radius: var(--radius-s);
  padding: 0.55rem 0.9rem 0.65rem;
  margin: 0 0 0.8rem;
  display: flex;
  gap: 0.4rem 1.2rem;
  flex-wrap: wrap;
  align-items: center;
}
.sources-select legend {
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0 0.4rem;
}
.sources-select legend .hint { text-transform: none; letter-spacing: 0; font-family: var(--sans); }
.sources-select .filter-check { color: var(--ink); }

/* ── Renommage d'un document ───────────────────────────────────────────── */

.doc-rename summary { list-style: none; cursor: pointer; }
.doc-rename summary::-webkit-details-marker { display: none; }
.doc-rename[open] form { margin-top: 0.4rem; animation: pop-in 0.22s var(--ease); }
.doc-rename input { width: min(130px, 100%); }

/* ── Filtres ciblés de recherche (console) ─────────────────────────────── */

.advanced-filters {
  margin: 0 0 0.8rem;
  border: 1px dashed var(--line-2);
  border-radius: var(--radius-s);
  padding: 0.55rem 0.9rem 0.2rem;
}
.advanced-filters[open] { padding-bottom: 0.8rem; }
.advanced-filters > summary {
  cursor: pointer;
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  padding-bottom: 0.35rem;
  transition: color 0.15s var(--ease);
}
.advanced-filters > summary:hover { color: var(--ink); }
.advanced-filters > summary .hint { text-transform: none; letter-spacing: 0; font-family: var(--sans); }
.advanced-filters .search-fields { margin: 0.5rem 0 0.8rem; }
.advanced-filters .salaire-check { align-self: end; padding-bottom: 0.55rem; }

.competences-select {
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  padding: 0.55rem 0.9rem 0.65rem;
  margin: 0;
  display: flex;
  gap: 0.4rem 1.1rem;
  flex-wrap: wrap;
  align-items: center;
}
.competences-select legend {
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0 0.35rem;
}
.competences-select input[type="text"] { flex: 1; min-width: min(240px, 100%); font-size: 0.82rem; }

/* ── Affichage progressif du tableau ───────────────────────────────────── */

/* ── Pied de tableau : total et navigation de pages ─────────────────────
   A remplacé `.table-more` (le bouton « afficher 50 de plus », qui reposait
   sur du JavaScript). La pagination est maintenant faite de vrais liens
   rendus par le serveur : rien à charger, l'URL reste partageable. */
.table-pied {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: 0.7rem 1rem;
  border-top: 1px dashed var(--line);
}
.pagination { display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; }
/* La page courante n'est pas un lien : elle ne mène nulle part. Même taille
   qu'un bouton pour que la rangée ne saute pas d'une page à l'autre. */
.page-courante {
  display: inline-flex;
  align-items: center;
  padding: 0.3rem 0.6rem;
  border-radius: var(--radius-s);
  background: var(--pine-t);
  color: var(--pine-2);
  border: 1px solid var(--pine);
  font-family: var(--mono);
  font-size: 0.8rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ── Historique des recherches ─────────────────────────────────────────── */

.hist-card { padding: 0; overflow: hidden; }
/* (défilement traité par la règle `.card table`, plus haut) */
.hist-total td {
  background: var(--pine-t);
  border-top: 2px solid var(--pine);
  font-weight: 600;
}

/* ── Liste des offres exclues : suppression (jamais de réintégration) ──── */

.excluded-item {
  display: flex;
  gap: 0.8rem;
  align-items: flex-start;
  justify-content: space-between;
}
.excluded-item-txt { flex: 1; min-width: 0; }
.excluded-clean { margin-top: 0.7rem; text-align: right; }

/* ── Assistant Gemini : CV optionnel ───────────────────────────────────── */

.gemini-cv {
  display: flex;
  gap: 1.2rem;
  flex-wrap: wrap;
  align-items: flex-end;
  width: 100%;
}
.gemini-cv label {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  font-size: 0.84rem;
  font-weight: 600;
}

/* ── Page de connexion (instance personnelle hébergée) ─────────────────── */
/* Palette et composants existants réutilisés tels quels : la carte de
   connexion est une .card ordinaire, simplement centrée et étroite. */

.login-main { max-width: 26rem; margin: 3rem auto; }
.login-card { border-top: 3px solid var(--pine); }
.login-card h1 {
  font-size: 1.05rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  margin: 0 0 0.3rem;
}
.login-fields {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  margin: 1.1rem 0;
}
.login-fields label {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.84rem;
  font-weight: 600;
}
/* Avis neutre (session expirée) — délibérément PAS la couleur d'erreur :
   rien n'a été refusé, la session s'est simplement terminée. `--blue` est la
   teinte informative déjà utilisée ailleurs ; aucune couleur nouvelle. */
.login-avis {
  margin: 0.8rem 0 0;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--blue);
  border-radius: var(--radius-s);
  background: var(--blue-t);
  color: var(--blue);
  font-size: 0.86rem;
}
.login-erreur {
  margin: 0.8rem 0 0;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--brick);
  border-radius: var(--radius-s);
  color: var(--brick);
  font-size: 0.86rem;
}
.login-actions { display: flex; justify-content: flex-end; }

/* Action SECONDAIRE de la page de connexion (« Inscription ») : séparée du
   bouton principal par un filet, pour qu'on ne la confonde pas avec « Se
   connecter » — et pour qu'elle reste malgré tout visible sans chercher. */
.login-secondaire {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--line);
}

/* Bouton « Se déconnecter » de la barre supérieure : même gabarit que les
   liens de navigation, sans les remplacer visuellement. */
.logout-form { display: flex; align-items: center; }
.logout-btn {
  font: inherit;
  font-size: 0.8rem;
  cursor: pointer;
  color: #9db3a7;
  background: transparent;
  border: 1px solid rgba(157, 179, 167, 0.35);
  border-radius: var(--radius-s);
  padding: 0.3rem 0.6rem;
}
.logout-btn:hover { color: #fff; border-color: #7fc7ae; }

/* ── Aperçu des documents générés (CV / lettre) ────────────────────────── */
/* Le cadre affiche le MÊME HTML que celui converti en PDF. */

.apercu-panel { border-top: 3px solid var(--pine); }
.apercu-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  gap: 1rem;
  margin-top: 0.8rem;
}
.apercu-item { margin: 0; }
.apercu-item figcaption {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.6rem;
  font-size: 0.84rem;
  margin-bottom: 0.4rem;
}
.apercu-item figcaption strong { font-weight: 600; }
.apercu-cadre {
  width: 100%;
  height: 560px;
  border: 1px solid var(--line-2);
  border-radius: var(--radius-s);
  background: #fff;   /* la « feuille » reste blanche, même en mode sombre */
}

/* ── Menu d'actions compact par document ───────────────────────────────── */
/* Un seul déclencheur « ⋯ Actions » remplace la pile de boutons : même
   densité que les filtres du tableau de bord et de la page Rejets. */

/* ── Un menu ouvert passe au-dessus de tout le reste de la page ──────────
   DÉFAUT MESURÉ (375 px, « Mes documents ») : le bas du panneau d'un menu
   ouvert était peint SOUS la carte suivante. `elementFromPoint` au milieu du
   panneau renvoyait `article.doc-card`, pas le panneau.

   La cause n'est PAS la valeur du `z-index`, et l'augmenter n'aurait rien
   changé. Une carte devient son propre CONTEXTE D'EMPILEMENT dès qu'elle
   porte une transformation ou une opacité : c'est le cas pendant l'animation
   d'entrée `fade-up`, et c'est le cas au survol comme à l'appui tactile
   (`transform: translateY(-2px)`, que le tactile garde collé après le
   toucher). À l'intérieur d'un tel contexte, le `z-index: 20` du panneau ne
   vaut plus que face aux autres enfants de SA carte ; entre deux cartes,
   c'est l'ordre du document qui tranche, et la suivante gagne.

   La correction porte donc sur la CARTE, pas sur le panneau : la carte qui
   contient un menu ouvert est élevée, avec tout son contenu. `:focus-within`
   double la règle pour les navigateurs sans `:has()`, et couvre le clavier :
   le menu ne s'ouvre qu'après un focus sur son résumé. Aucun contenu n'est
   masqué en permanence, l'élévation dure le temps de l'ouverture. */
.doc-card, .compte-carte { position: relative; }
.doc-card:has(.doc-menu[open]),
.compte-carte:has(.doc-menu[open]),
.doc-card:focus-within,
.compte-carte:focus-within { z-index: 30; }

.doc-menu { position: relative; }
.doc-menu > summary { list-style: none; cursor: pointer; user-select: none; }
.doc-menu > summary::-webkit-details-marker { display: none; }
.doc-menu-panneau {
  position: absolute;
  right: 0;
  z-index: 20;
  min-width: min(15rem, calc(100vw - 2rem));
  margin-top: 0.3rem;
  padding: 0.3rem;
  background: var(--card);
  border: 1px solid var(--line-2);
  border-radius: var(--radius-s);
  box-shadow: var(--shadow-2);
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}
.doc-menu-panneau form { margin: 0; }
.doc-action {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  padding: 0.4rem 0.55rem;
  font: inherit;
  font-size: 0.84rem;
  text-align: left;
  text-decoration: none;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-radius: var(--radius-s);
  cursor: pointer;
}
.doc-action:hover { background: var(--row-hover); color: var(--pine-2); }
.doc-action-danger { color: var(--brick); }
.doc-action-danger:hover { background: var(--brick-t); color: var(--brick); }
.doc-menu .doc-rename { width: 100%; }
.doc-menu .doc-rename > summary { list-style: none; }
.doc-menu .doc-rename > summary::-webkit-details-marker { display: none; }
.doc-menu .doc-rename .inline-form { padding: 0.3rem 0.55rem 0.45rem; gap: 0.35rem; }
.doc-menu .doc-rename input[type="text"] { width: 100%; font-size: 0.82rem; }

/* Consentement Perplexity dans la ligne d'actions d'une offre : même
   composant que la console de recherche, en plus discret. */
.gen-pplx { font-size: 0.78rem; margin-left: 0.1rem; }
.gen-pplx em { color: var(--muted); font-style: normal; }

/* ── Multi-comptes : pastille de navigation, tableaux d'administration ──────
   Rien de neuf côté palette : ces règles réutilisent les variables déjà
   définies plus haut, pour que le thème clair/sombre continue de fonctionner
   sans exception. */
.pastille {
  display: inline-block;
  min-width: 1.1rem;
  padding: 0.05rem 0.32rem;
  margin-left: 0.25rem;
  border-radius: 999px;
  background: var(--amber-t);
  color: var(--amber);
  border: 1px solid var(--amber);
  font-family: var(--mono);
  font-size: 0.66rem;
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.statut-actif    { color: var(--pine-2); }
.statut-suspendu { color: var(--amber); }
.statut-banni    { color: var(--muted); text-decoration: line-through; }
.role-admin { font-weight: 700; }
.admin-actions { display: flex; flex-wrap: wrap; gap: 0.3rem; align-items: center; }
.admin-actions form { display: inline; }
/* Zone de danger : bâtie sur les variables de thème (--brick), elle suit donc
   clair/sombre/système sans règle dupliquée à maintenir en double. */
.zone-danger {
  border: 1px solid var(--brick);
  border-radius: 8px;
  padding: 0.8rem 1rem;
  margin-top: 1rem;
  background: var(--brick-t);
}
.code-invitation {
  font-family: var(--mono);
  font-size: 0.78rem;
  word-break: break-all;
}

/* ── Modale de confirmation ────────────────────────────────────────────────
   Remplace window.confirm(), dont l'apparence est imposée par le navigateur.
   <dialog> natif : le piège de focus, la touche Échap et le retour au bouton
   d'origine viennent du navigateur, on ne les réécrit pas. */
.modale {
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--ink);
  padding: 0;
  max-width: min(32rem, calc(100vw - 2rem));
  box-shadow: var(--shadow-2);
}
.modale::backdrop { background: rgba(0, 0, 0, 0.45); }
.modale-boite { padding: 1.1rem 1.25rem 1rem; margin: 0; }
.modale-titre {
  margin: 0 0 0.5rem;
  font-size: 1rem;
  letter-spacing: 0.01em;
}
.modale-message {
  margin: 0 0 1rem;
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--ink-2, var(--ink));
}
.modale-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
}

/* ── Liste des comptes : une CARTE par compte ───────────────────────────────
   Le tableau de huit colonnes serrées mêlait ses lignes : à 375 px il
   imposait un défilement horizontal, et même au large l'œil perdait le compte
   auquel appartenait une valeur.

   Le contenant est la carte DÉJÀ EN PLACE dans « Mes documents » : la règle
   `.doc-card` porte les deux sélecteurs, il n'existe donc qu'une seule
   définition de carte dans la feuille, et non deux qui divergeraient. Seule
   la direction du contenu change ici, la peau est identique au pixel près
   (fond, bordure, rayon, retrait, ombre, animation d'entrée, survol). */
.comptes-liste { display: grid; gap: 0.9rem; }
/* `align-items` repasse à `stretch` : la carte partagée porte `flex-start`,
   utile à « Mes documents » où l'icône ne doit pas s'étirer, mais qui ici
   réduisait chaque bloc à la largeur de son contenu. Mesuré : la rangée
   d'actions faisait 81 px au lieu des 1 153 px de la carte, le menu restait
   collé à gauche et son panneau, ancré à droite de ce menu, sortait de
   l'écran de 175 px. */
.compte-carte { flex-direction: column; align-items: stretch; gap: 0.7rem; }
.compte-entete { display: flex; flex-direction: column; gap: 0.15rem; }
.compte-nom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  margin: 0;
  font-size: 1rem;
}
.compte-id { color: var(--muted); font-size: 0.8rem; font-weight: 400; }
/* Une adresse longue coupe plutôt que de pousser la carte hors de l'écran. */
.compte-courriel {
  margin: 0;
  color: var(--muted);
  font-size: 0.84rem;
  overflow-wrap: anywhere;
}
/* Les six champs du tableau, en grille souple : quatre de front au large,
   deux sur une tablette, un seul à 375 px. Aucune information retirée. */
.compte-champs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 0.6rem 1rem;
  margin: 0;
  padding-top: 0.7rem;
  border-top: 1px solid var(--line);
}
.compte-champ dt {
  margin: 0 0 0.1rem;
  font-size: 0.76rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  /* `--ink-2` et non `--muted` : à cette taille le texte n'est pas « large »
     au sens WCAG, il lui faut donc 4,5:1 comme au corps du texte. */
  color: var(--ink-2);
}
.compte-champ dd { margin: 0; font-size: 0.88rem; }
.compte-actions { display: flex; justify-content: flex-end; }

/* ── Menu « Actions » d'un compte ───────────────────────────────────────────
   Même mécanique <details> que « Mes documents » : un seul point d'entrée par
   compte. Une rangée de boutons collés rendait la liste illisible et mettait
   les actions dangereuses à portée de clic accidentel. */
.compte-menu .doc-menu-panneau { min-width: 20rem; padding: 0.35rem; }
.menu-section { width: 100%; }
.menu-section > summary { list-style: none; cursor: pointer; }
.menu-section > summary::-webkit-details-marker { display: none; }
.menu-section[open] > summary { background: var(--row-hover); border-radius: var(--radius-s); }
.menu-corps {
  padding: 0.15rem 0.55rem 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.menu-corps .hint { margin: 0; }
.menu-corps .inline-form { display: flex; gap: 0.4rem; align-items: center; }
.menu-corps input[type="number"] { width: 6rem; }
.compte-stats {
  margin: 0;
  padding: 0.15rem 0.55rem 0.5rem 1.5rem;
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--muted);
}
.doc-action-danger { color: var(--brick); }
.menu-section-danger[open] > summary { background: var(--brick-t); }
.case-comprends {
  display: flex;
  gap: 0.45rem;
  align-items: flex-start;
  font-size: 0.8rem;
  line-height: 1.4;
}
/* Étiquette réservée aux lecteurs d'écran (champ dont le libellé visible
   serait redondant à côté de son bouton). */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Encadré de nuance : sert à empêcher qu'un chiffre soit lu pour plus qu'il
   ne dit (taux de conversion). Volontairement sobre — ce n'est ni une alerte
   ni une erreur, c'est une mise en garde de lecture. */
.zone-nuance {
  border-left: 3px solid var(--blue);
  background: var(--blue-t);
  border-radius: var(--radius-s);
  padding: 0.7rem 0.9rem;
  margin-top: 0.9rem;
}
.zone-nuance p { margin: 0 0 0.4rem; font-size: 0.85rem; }
.zone-nuance p:last-child { margin-bottom: 0; }

/* Zone de notifications des actions légères : invisible tant qu'elle est
   vide, pour ne pas laisser un cadre creux en haut de page. */
.notifications:empty { display: none; }

/* ═══════════════════════════════════════════════════════════════════════
   REPLIS DE TEXTE — ce qui explique, sous ce qui sert
   ═══════════════════════════════════════════════════════════════════════
   Un test d'usage réel a montré que beaucoup de texte écrit pour documenter
   des décisions internes se lisait comme du bruit pour qui cherche un
   emploi. Ce qui reste utile mais rarement lu passe donc derrière un
   <details> : même patron que la navigation, le menu des documents et celui
   des comptes — aucun JavaScript, le pliage est celui du navigateur.
   Aucune couleur nouvelle : que des variables déjà définies plus haut.
   ═══════════════════════════════════════════════════════════════════════ */

/* Repli court, à l'intérieur d'une carte : un paragraphe d'explication. */
.repli-doc {
  margin: 0.6rem 0 0;
  border: 1px dashed var(--line-2);
  border-radius: var(--radius-s);
  padding: 0.4rem 0.8rem;
}
.repli-doc[open] { padding-bottom: 0.6rem; }
.repli-doc > summary {
  cursor: pointer;
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  transition: color 0.15s var(--ease);
}
.repli-doc > summary:hover { color: var(--ink); }
.repli-doc .hint { margin: 0.5rem 0 0; }

/* Repli de SECTION entière (administration) : le titre reste le déclencheur,
   la section garde donc exactement la même tête, ouverte ou fermée. */
.repli-section > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.repli-section > summary::-webkit-details-marker { display: none; }
.repli-section > summary h2 { margin: 0; }
/* Chevron dessiné en CSS, comme ceux de la navigation et du menu d'offre. */
.repli-section > summary::after {
  content: "";
  width: 0.42rem;
  height: 0.42rem;
  border-right: 1.5px solid var(--muted);
  border-bottom: 1.5px solid var(--muted);
  transform: rotate(45deg) translate(-1px, -1px);
  flex: none;
}
.repli-section[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }

/* ── Profil : les réglages qu'on ne rouvre presque jamais ────────────────
   Les réglages de RECHERCHE (titres, compétences, villes) restent à plat :
   ce sont eux qu'on revient modifier. Le compte, la clé et la liste partagée
   se règlent une fois — ils passent derrière un seul déclencheur. */
.profil-avance { margin-bottom: 1.2rem; }
.profil-avance > summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.75rem 1.1rem;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  transition: color 0.15s var(--ease), border-color 0.15s var(--ease);
}
.profil-avance > summary::-webkit-details-marker { display: none; }
.profil-avance > summary:hover { color: var(--ink); border-color: var(--line-2); }
.profil-avance > summary::after {
  content: "";
  width: 0.42rem;
  height: 0.42rem;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  flex: none;
  margin-left: auto;
}
.profil-avance[open] > summary { color: var(--ink); }
.profil-avance[open] > summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.profil-avance-corps { padding-top: 1.2rem; }
.profil-avance-corps > .card:last-child { margin-bottom: 0; }

/* ═══════════════════════════════════════════════════════════════════════
   MENU « ACTIONS » D'UN COMPTE — respiration et panneau non rogné
   ═══════════════════════════════════════════════════════════════════════ */

/* Le panneau paraissait autrefois tronqué et tassé. Cause réelle, mesurée :
   `.card table { overflow-x: auto }` faisait du tableau des comptes une BOÎTE
   DE DÉFILEMENT, qui rognait tout enfant en position absolue qui en dépassait.
   La parade suspendait ce défilement pendant qu'un menu était ouvert.

   Cette parade est retirée avec le tableau lui-même : la liste des comptes est
   passée en cartes, il n'y a plus de boîte de défilement autour du menu, donc
   plus rien à rogner ni à suspendre. La règle qui reste ci-dessous, elle, garde
   toute sa raison d'être. */
/* Sur petit écran, le panneau passe DANS LE FLUX plutôt que par-dessus : il
   grandit la carte au lieu d'en déborder, et le contenu reste entier. */
@media (max-width: 720px) {
  .compte-menu[open] > .doc-menu-panneau {
    position: static;
    box-shadow: none;
    margin-top: 0.4rem;
  }
}
/* Même sortie de secours pour un navigateur sans `:has()` : là, la règle
   ci-dessus ne s'applique jamais et le panneau resterait rogné. Le passage
   dans le flux ne dépend, lui, d'aucun sélecteur récent. */
@supports not selector(:has(*)) {
  .compte-menu[open] > .doc-menu-panneau {
    position: static;
    box-shadow: none;
    margin-top: 0.4rem;
  }
}

/* Respiration : les entrées se touchaient (1,6 px d'écart), les corps de
   section commençaient sous l'icône du titre au lieu de son texte, et la
   zone dangereuse n'était séparée de rien. */
.compte-menu .doc-menu-panneau {
  min-width: min(21rem, calc(100vw - 2rem));
  padding: 0.4rem;
  gap: 0.15rem;
}
.compte-menu .menu-section > summary { padding: 0.45rem 0.55rem; }
.menu-corps {
  padding: 0.35rem 0.6rem 0.6rem 1.75rem;
  gap: 0.55rem;
}
/* Alignés sur le texte du titre de section (icône + gouttière), pas sur son
   icône : deux indentations différentes pour deux listes voisines se lisaient
   comme un défaut d'alignement. */
.compte-stats {
  padding: 0.35rem 0.6rem 0.6rem 2.9rem;
  list-style: disc;
}
.menu-corps form { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; }
.menu-corps .btn { margin: 0; }
/* Un filet avant les actions irréversibles : la séparation visuelle double la
   protection déjà posée côté serveur (nom à retaper + case à cocher). */
.compte-menu .menu-section-danger {
  margin-top: 0.25rem;
  padding-top: 0.25rem;
  border-top: 1px solid var(--line);
}
.compte-menu .menu-section-danger .menu-corps { gap: 0.6rem; }
.compte-menu .menu-corps input[type="text"] { min-width: min(11rem, 100%); }

/* ═══════════════════════════════════════════════════════════════════════
   LARGEUR INTERMÉDIAIRE — une fenêtre de bureau réduite à moitié
   ═══════════════════════════════════════════════════════════════════════
   Entre la bascule mobile (720 px) et le plein écran, le cas courant est
   deux fenêtres côte à côte : ~900-1000 px. Les tableaux y débordaient de
   leur carte et défilaient EN DEDANS — mesuré à 950 px : 976 px de contenu
   pour 888 px de place sur le tableau de bord, 973 pour 903 sur les
   candidatures. La réponse est de RESSERRER (espacement, taille, largeurs
   de colonnes), pas de basculer en cartes : à cette largeur, un tableau se
   lit encore très bien, et le passage en cartes ferait perdre la comparaison
   colonne par colonne qui fait tout l'intérêt de ces pages.
   ═══════════════════════════════════════════════════════════════════════ */

@media (min-width: 721px) and (max-width: 1100px) {
  main { padding: 1.1rem 1rem 2.4rem; }

  table.jobs { font-size: 0.82rem; }
  .jobs thead th { padding: 0.5rem 0.5rem; font-size: 0.62rem; letter-spacing: 0.1em; }
  .jobs td { padding: 0.5rem 0.5rem; }

  /* Les planchers de colonne sont ce qui poussait la largeur : 210 px pour le
     titre, 150 px pour le statut et pour les documents. Ils sont abaissés,
     jamais supprimés — une colonne de titre trop étroite redeviendrait
     illisible. `min(…, 100%)` reste hors de question ici : dans un tableau, un
     pourcentage se résout contre la largeur de la table et fausserait le
     calcul des colonnes. */
  .cell-title { min-width: 150px; }
  .cell-status { min-width: 120px; }
  .cell-docs { min-width: 120px; }
  /* La description brève est la colonne la plus élastique : la borner libère
     la place pour les colonnes qui portent une décision. */
  .col-desc { max-width: 200px; font-size: 0.78rem; }
  .cell-comment { max-width: 170px; }
  .meter { width: 48px; }
  .job-link { font-size: 0.75rem; }
  .pill { font-size: 0.6rem; padding: 0.1rem 0.4rem; }

  /* Les boutons d'action d'une offre tiennent alors dans leur colonne. */
  .apply-form select { max-width: 150px; }
  .apply-form input[type="file"] { max-width: 150px; }

  /* Statistiques : deux graphiques côte à côte deviennent illisibles bien
     avant de déborder — une colonne, pleine largeur. */
  .stats-grid { grid-template-columns: 1fr; }
  .chart-box { height: 260px; }
}

/* Bas de la fourchette : resserrer ne suffit plus. Mesuré sur le tableau de
   bord, la table ne descend pas sous ~810 px tant que la description brève
   est là — elle déborde donc encore de 123 px à 721 px. La description est
   justement la colonne SECONDAIRE : c'est déjà elle que la mise en carte
   retire sous 720 px. Elle part ici aussi, une centaine de pixels plus tôt,
   plutôt que de laisser un tableau défiler en dedans. Les colonnes qui
   portent une décision (entreprise, titre, score, statut) restent toutes. */
@media (min-width: 721px) and (max-width: 880px) {
  .col-desc { display: none; }
  .cell-title { min-width: 130px; }
  .cell-status { min-width: 110px; }
  .cell-comment { max-width: 140px; }
  .cell-docs { min-width: 95px; }
  /* La pastille de statut est la cellule la plus large de la page
     Candidatures : sa largeur vient de son option la plus longue. Le rembourrage
     droit ne sert qu'à dégager la flèche du <select> — le resserrer ne rogne
     aucun texte. */
  .statut-select { font-size: 0.76rem; padding: 0.26rem 1.3rem 0.26rem 0.45rem; }
}

/* ═══════════════════════════════════════════════════════════════════════
   TÉLÉPHONE — un nom ou une URL longue ne doit jamais pousser la carte
   ═══════════════════════════════════════════════════════════════════════
   Constaté sur un vrai iPhone, pas en simulation : sur Candidatures et
   Statistiques, il fallait faire glisser horizontalement pour lire un nom de
   CV ou une adresse. Mesuré à 320 px : la rangée de candidature demandait
   435 px pour 289 px disponibles, dont une seule cellule « Documents » à
   421 px.

   CAUSE, et elle n'était pas celle qu'on croyait. Le round précédent avait
   accusé la pastille <select> de statut, qui se dimensionne sur son option la
   plus longue — elle ne fait que 128 px, elle n'était pas le sujet. Le vrai
   coupable est `flex: 0 0 auto` sur les cellules empilées en carte : « ne
   grandis pas, NE RÉTRÉCIS PAS, prends ta largeur de contenu ». Un nom de
   fichier de soixante caractères imposait donc sa largeur à toute la carte.
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 720px) {
  /* `0 1 auto` : la cellule garde sa largeur idéale tant qu'elle tient, et
     rétrécit dès qu'il le faut. `min-width: 0` lève le plancher implicite
     d'un élément flex, sans lequel il refuse de passer sous son contenu. */
  .jobs tbody td {
    flex: 0 1 auto;
    min-width: 0;
    overflow-wrap: anywhere;
  }
  /* Les deux colonnes à texte libre prennent une ligne entière : c'est là que
     vivent les noms de documents et les commentaires. */
  .jobs tbody td.cell-docs,
  .jobs tbody td.cell-comment {
    flex: 1 1 100%;
    max-width: 100%;
  }
  /* Un lien ne se coupe pas tout seul : sans ceci, une URL d'une seule
     « ligne de mots » reste indivisible et repousse la carte. */
  .cell-docs a, .cell-title a, .excluded-item a { overflow-wrap: anywhere; }
  .cell-comment summary { overflow-wrap: anywhere; white-space: normal; }

  /* Statistiques : mêmes causes, mêmes effets. Le tableau de conversion garde
     une largeur idéale de 680 px, qu'il ne peut pas tenir sur un téléphone ;
     et un libellé de CV long tient la colonne ouverte. */
  .stats-table { max-width: 100%; }
  .stats-table td, .stats-table th { overflow-wrap: anywhere; }
  .stats-table td:first-child { max-width: 11rem; }
}

/* ═══════════════════════════════════════════════════════════════════════
   PAGE D'ERREUR — une seule, pour tous les codes couverts
   ═══════════════════════════════════════════════════════════════════════
   Sobre à dessein : une erreur n'est pas un événement à décorer. Le code en
   gros sert de repère quand quelqu'un décrit ce qu'il a vu ; le reste tient
   en deux phrases et une porte de sortie. Aucune couleur nouvelle.
   ═══════════════════════════════════════════════════════════════════════ */

.erreur-carte {
  max-width: 34rem;
  margin: 3rem auto;
  text-align: center;
  border-top: 3px solid var(--line-2);
}
.erreur-code {
  margin: 0;
  font-family: var(--mono);
  font-size: 2.6rem;
  font-weight: 700;
  line-height: 1;
  color: var(--line-2);
  font-variant-numeric: tabular-nums;
}
.erreur-titre {
  margin: 0.6rem 0 0.4rem;
  font-size: 1.15rem;
  letter-spacing: 0.01em;
}
.erreur-message {
  margin: 0;
  color: var(--ink-2, var(--ink));
  line-height: 1.55;
  overflow-wrap: anywhere;
}
.erreur-detail { margin-top: 0.6rem; }
.erreur-sortie {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin: 1.3rem 0 0;
}

/* ── Formulaire de commentaires du pied de page ─────────────────────────────
   Replié par un <details> natif : il ne pèse sur aucune page tant qu'il n'est
   pas ouvert, et aucun script n'est nécessaire. Les couleurs sont celles du
   pied, déjà contrôlées en contraste dans les deux thèmes.
   PLACÉ AVANT le bloc de la page d'accueil, et hors de lui : ce formulaire
   appartient au gabarit applicatif, le confinement sous `.page-accueil`
   n'est pas touché. */
.footer-commentaires { margin: 0.6rem 0; }
.footer-commentaires > summary {
  cursor: pointer;
  display: inline-block;
  padding: 0.3rem 0;
  font-weight: 600;
}
.commentaire-form {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  /* Le pied s'étale sur toute la largeur ; un champ de saisie de 1200 px se
     lit mal. La borne suit la limite de confort de lecture du reste. */
  max-width: 34rem;
  margin-top: 0.5rem;
}
.commentaire-form label { display: flex; flex-direction: column; gap: 0.25rem; }
.commentaire-form textarea { resize: vertical; min-height: 5rem; font: inherit; }
.commentaire-form .btn { align-self: flex-start; }

/* Corps d'un message reçu : les retours à la ligne écrits par la personne
   sont conservés, sans qu'aucun balisage ne soit interprété (l'échappement
   automatique de Jinja reste actif sur ce champ). */
.commentaire-corps {
  margin: 0;
  white-space: pre-line;
  overflow-wrap: anywhere;
  font-size: 0.9rem;
  line-height: 1.6;
}

/* Repli d'auto-suppression dans la page Profil : même habillage que la zone
   dangereuse du menu « Actions » d'un compte, sans valeur nouvelle. */
.compte-suppression { margin-top: 0.8rem; }

/* ═══════════════════════════════════════════════════════════════════════════
   MATCH ETHICS HOMEPAGE START — page d'accueil publique
   ───────────────────────────────────────────────────────────────────────────
   CONFINEMENT. Tout est sous `.page-accueil`, toutes les classes portent le
   préfixe `acc-`, toutes les variables aussi et elles sont posées sur la
   classe racine, jamais sur `:root`. Ce bloc est destiné à être collé dans la
   feuille d'une application existante : rien n'en sort.

   Une seule exception, assumée : la classe `.acc-js`, posée sur <html> par le
   script de la page. Elle sert de préfixe aux règles d'animation. Il faut
   qu'elle soit posée AVANT le premier rendu, donc sur un élément qui existe
   déjà quand le script s'exécute — <body> n'existe pas encore à ce moment. La
   classe est préfixée et n'est posée que par le script de cette page.

   PROGRESSIVITÉ. L'état par défaut, sans script et sans classe, est le
   contenu VISIBLE. Les états de départ des animations (décalage, opacité
   nulle) ne s'appliquent que sous `.acc-js`. Si le script échoue, est bloqué
   par la politique de sécurité, ou n'est jamais chargé, la page reste
   entièrement lisible. Ne jamais inverser cette logique : une version
   précédente de ce projet masquait ses sections en attendant un script, le
   script a été bloqué, et la page rendait vide.

   MOUVEMENT RÉDUIT. Toutes les animations sont enfermées dans un
   `@media (prefers-reduced-motion: no-preference)`. Sous `reduce`, aucune
   règle d'animation n'est même déclarée : il n'y a rien à neutraliser, donc
   rien qui puisse fuir. Les animations pilotées par le défilement provoquent
   des nausées réelles chez les personnes souffrant de troubles vestibulaires.

   PERFORMANCE. Seuls `transform` et `opacity` sont animés. Aucune animation
   ne touche width, height, top, left, margin ni padding.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Polices auto-hébergées. Aucun service externe : la politique de sécurité
      porte `font-src 'self'`, une police distante serait bloquée sans un mot. */
@font-face { font-family: 'Manrope'; src: url('/static/polices/manrope-600.woff2') format('woff2'); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: 'Manrope'; src: url('/static/polices/manrope-700.woff2') format('woff2'); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: 'Manrope'; src: url('/static/polices/manrope-800.woff2') format('woff2'); font-weight: 800; font-style: normal; font-display: swap; }
@font-face { font-family: 'Karla';   src: url('/static/polices/karla-400.woff2')   format('woff2'); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'Karla';   src: url('/static/polices/karla-600.woff2')   format('woff2'); font-weight: 600; font-style: normal; font-display: swap; }

/* ═══════════ Jetons — thème SOMBRE, celui par défaut ═══════════ */
.page-accueil {
  /* FOND : celui de l'application, mesuré sur /connexion — #121814 en sombre,
     #eef1ee en clair, et le MÊME voile radial pin, seule superposition qu'elle
     applique. Le vert saturé et le dégradé vertical d'avant faisaient une
     marche visible au passage d'une page à l'autre. */
  --acc-bg:          #121814;
  --acc-voile:       radial-gradient(1100px 420px at 50% -160px,
                                     rgba(15, 92, 73, 0.055), transparent 70%);
  --acc-pied-txt:    #97a89d;   /* --muted de l'application, thème sombre */
  --acc-fil-pied:    #2b362f;   /* --line */
  --acc-surface:     rgba(159, 225, 203, 0.05);
  --acc-surface-up:  rgba(159, 225, 203, 0.09);
  --acc-card:        #1a221d;   /* .card de l'application, thème sombre */
  --acc-text:        #F3F4F6;
  --acc-muted:       #A9BFB5;
  --acc-faint:       #8AA096;
  --acc-accent:      #5DCAA5;
  --acc-accent-up:   #9FE1CB;
  --acc-on-accent:   #06120E;
  --acc-flag:        #E7C86A;
  --acc-reject:      #E39A8A;
  --acc-border:      rgba(159, 225, 203, 0.18);
  --acc-border-soft: rgba(159, 225, 203, 0.10);
  --acc-veil:        #05100C;   /* voile d'empilement entre sections */
  /* EN-TÊTE : les valeurs de l'application, mesurées sur /connexion. Le
     bandeau applicatif est SOMBRE dans les deux thèmes ; ces trois jetons ne
     sont donc pas redéclinés en thème clair. */
  --acc-bandeau:     linear-gradient(180deg, #212b26, #1b2420);
  --acc-bandeau-txt: #e9efe9;
  --acc-bandeau-sec: #cfdcd2;   /* nav et bascule, comme .theme-toggle */
  --acc-bandeau-fil: #46a585;   /* filet de 3 px, teinte sombre */
  --acc-btn-fond:    #212b25;   /* .btn du thème sombre applicatif */
  --acc-btn-bord:    #3d4a42;
  --acc-btn-txt:     #e3eae4;

  --acc-sans:  'Karla', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --acc-titre: 'Manrope', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  --acc-sp-2: 8px;  --acc-sp-3: 12px; --acc-sp-4: 16px; --acc-sp-5: 20px;
  --acc-sp-6: 24px; --acc-sp-8: 32px; --acc-sp-10: 40px; --acc-sp-16: 64px;
  --acc-sp-20: 80px; --acc-sp-28: 112px;
  --acc-radius: 10px;
  --acc-radius-lg: 22px;

  /* RESSORT. Troisième paramètre à 1.56 : la courbe dépasse sa cible puis
     revient. Aucune transition de cette page n'emploie ease-in-out ni linear. */
  --acc-ressort: cubic-bezier(0.34, 1.56, 0.64, 1);
  /* Variante sans rebond pour les grandes translations, où un dépassement de
     40 px se verrait comme un défaut plutôt que comme un ressort. */
  --acc-sortie:  cubic-bezier(0.16, 1, 0.30, 1);
  --acc-dur: 0.62s;

  margin: 0;
  color: var(--acc-text);
  font-family: var(--acc-sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* Un seul voile, celui de l'application. La forme raccourcie `background:`
     remet la couleur de fond à transparent : elle est reposée juste après,
     sans quoi le fond du navigateur transparaît sous le dégradé. */
  background: var(--acc-voile);
  background-color: var(--acc-bg);
}

/* ═══════════ Jetons — thème CLAIR ═══════════ */
html[data-theme="clair"] .page-accueil {
  --acc-bg:          #eef1ee;   /* --paper de l'application */
  --acc-pied-txt:    #5c6a62;   /* --muted, thème clair */
  --acc-fil-pied:    #d3dbd4;   /* --line */
  --acc-surface:     rgba(29, 158, 117, 0.05);
  --acc-surface-up:  rgba(29, 158, 117, 0.10);
  --acc-card:        #FFFFFF;
  --acc-text:        #12211C;
  --acc-muted:       #4A5F56;
  --acc-faint:       #51655B;   /* #5C7167 mesurait 4,47:1, sous le seuil */
  --acc-accent:      #146B50;   /* pour le TEXTE : #1D9E75 tombe à 2,9:1 sur
                                   #F7F5F0, sous le seuil. La teinte de marque
                                   reste employée en aplat, où le texte est
                                   blanc. */
  --acc-accent-up:   #0F5540;
  --acc-on-accent:   #FFFFFF;
  --acc-flag:        #8A6410;
  --acc-reject:      #9E3B28;
  --acc-border:      rgba(18, 33, 28, 0.14);
  --acc-border-soft: rgba(18, 33, 28, 0.08);
  --acc-veil:        #C9C5BB;
  /* Seul le filet change entre les deux thèmes, exactement comme dans
     l'application : le bandeau, lui, reste sombre. */
  --acc-bandeau-fil: #0f5c49;
  --acc-btn-fond:    #fbfcfb;   /* .btn du thème clair applicatif */
  --acc-btn-bord:    #b9c4bb;
  --acc-btn-txt:     #1b2420;

  /* Un seul voile, celui de l'application. La forme raccourcie `background:`
     remet la couleur de fond à transparent : elle est reposée juste après,
     sans quoi le fond du navigateur transparaît sous le dégradé. */
  background: var(--acc-voile);
  background-color: var(--acc-bg);
}

/* Remise à zéro en `:where()` : spécificité nulle au-delà de `.page-accueil`,
   donc les classes `.acc-*` qui suivent ne sont jamais battues par elle. */
.page-accueil :where(*, *::before, *::after) { box-sizing: border-box; }
.page-accueil :where(h1, h2, h3, p, ul, figure) { margin: 0; padding: 0; }
.page-accueil :where(ul) { list-style: none; }
.page-accueil :where(a) { text-decoration: none; color: inherit; }
.page-accueil :where(img) { display: block; }

/* ── NEUTRALISATION DE RÈGLES DE L'APPLICATION ──────────────────────────────
   La consigne de confinement protège l'application de cette page. L'inverse
   est vrai aussi : la feuille applicative porte des SÉLECTEURS D'ÉLÉMENT
   globaux qui attrapent le balisage d'ici. Relevé par audit sur la page
   rendue, en interrogeant chaque règle applicative contre chaque élément :

     • `main > section { animation: fade-up ... }` faisait partir toutes les
       sections à `opacity: 0` et `translateY(10px)`, en `backwards`, avec la
       courbe de l'application. Conflit direct avec les apparitions écrites
       ici, et sections figées à leur état de départ quand l'onglet n'était
       pas au premier plan.
     • `main { max-width: 1240px; padding: 1.4rem 1.4rem 3rem }` rentrait les
       sections dans une colonne : les fonds pleine largeur ne touchaient plus
       les bords.
     • `footer { max-width: 1240px; ... }` faisait de même en pied de page.

   Neutralisées POUR CETTE PAGE SEULEMENT. Les règles applicatives ne sont pas
   modifiées : l'application les garde intactes.

   Écrites en `:where()` : la neutralisation garde ainsi la spécificité (0,1,0)
   de `.page-accueil` seule. Sans cela `.page-accueil footer` vaudrait (0,1,1)
   et battrait `.acc-site-footer`, qui vaut (0,1,0) : la neutralisation aurait
   effacé le pied de page que cette feuille dessine juste après. */
.page-accueil :where(main) > :where(section) { animation: none; }
.page-accueil :where(main) { max-width: none; margin: 0; padding: 0; }
.page-accueil :where(main) > * { margin-inline: 0; }
.page-accueil :where(footer) { max-width: none; margin: 0; padding: 0; border-top: 0; }

.acc-container { width: 100%; max-width: 1120px; margin: 0 auto; padding: 0 var(--acc-sp-5); }

/* ═══════════ En-tête ═══════════ */
.acc-site-header {
  position: sticky; top: 0; z-index: 60;
  /* Dégradé et filet de 3 px repris de `.topbar` : passer de l'accueil à la
     connexion ne doit produire aucune marche. Le bandeau étant opaque, le
     flou d'arrière-plan précédent n'a plus d'objet. */
  background: var(--acc-bandeau);
  color: var(--acc-bandeau-txt);
  border-bottom: 3px solid var(--acc-bandeau-fil);
}
.acc-site-header-inner {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: var(--acc-sp-3) var(--acc-sp-4);
  padding-block: var(--acc-sp-4);
}
.acc-brand { display: flex; align-items: center; gap: 10px; margin-right: auto; }
/* Nom de marque : la police, la casse et l'interlettrage de l'application.
   Mesuré sur /connexion : ui-monospace, 16 px, 700, interlettrage 3,2 px,
   aucun `text-transform` (les capitales sont dans le texte). */
.acc-brand-name {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", "Roboto Mono",
               Consolas, monospace;
  font-weight: 700; font-size: 16px; letter-spacing: 3.2px;
  color: var(--acc-bandeau-txt);
}
.acc-site-nav { display: none; gap: var(--acc-sp-6); }
.acc-site-nav a { font-size: 14px; font-weight: 600; color: var(--acc-bandeau-sec); }
.acc-site-nav a:hover { color: #fff; }
.acc-header-actions { display: flex; align-items: center; gap: var(--acc-sp-3); }
.acc-signin { display: none; font-size: 14px; font-weight: 600; color: var(--acc-bandeau-txt); }

.acc-theme-form { display: flex; margin: 0; }
/* Bascule de thème : gabarit de `.theme-toggle`, mesuré sur /connexion —
   fond et bordure transparents, rayon 6 px, remplissage 6,72 × 8,8 px,
   couleur #cfdcd2, survol vers le blanc avec une bordure #40544a. */
.acc-theme-btn {
  display: inline-flex; align-items: center; justify-content: center;
  margin-left: 0.35rem; padding: 6.72px 8.8px; line-height: 1;
  font-family: inherit; cursor: pointer;
  background: transparent; color: var(--acc-bandeau-sec);
  border: 1px solid transparent; border-radius: 6px;
}
.acc-theme-btn:hover { color: #fff; border-color: #40544a; }
.acc-theme-btn svg { display: block; }
/* UNE SEULE icône à la fois. Dans l'application, `.theme-toggle svg` (0,1,1)
   l'emporte sur `.icon-sun { display: none }` (0,1,0) et les DEUX icônes
   s'affichent : bogue applicatif signalé, non corrigé ici puisque aucun style
   applicatif ne doit être touché. La règle reproduite est celle qui était
   visiblement voulue. */
/* L'icône annonce la DESTINATION, comme dans l'application : en thème
   sombre le soleil (« passer au clair »), en thème clair la lune. La page
   est sombre par défaut, d'où le soleil dans la règle de base. */
.acc-theme-btn .acc-icone-lune { display: none; }
.acc-theme-btn .acc-icone-soleil { display: block; }
html[data-theme="clair"] .acc-theme-btn .acc-icone-soleil { display: none; }
html[data-theme="clair"] .acc-theme-btn .acc-icone-lune { display: block; }

/* ═══════════ Boutons ═══════════ */
/* Boutons : forme, rayon et couleurs de `.btn` et `.btn-primary`, mesurés
   sur /connexion — rayon 6 px, dégradé pin, bordure #0b4436. Les TAILLES,
   elles, restent celles d'une page de présentation : `.acc-btn-lg` garde son
   remplissage généreux, l'erreur d'un lot précédent ayant été d'importer
   aussi la densité de l'interface. */
.acc-btn {
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--acc-sans); font-weight: 500; font-size: 14px;
  padding: 8px 16px; border-radius: 6px; cursor: pointer;
  border: 1px solid var(--acc-btn-bord); background: var(--acc-btn-fond);
  color: var(--acc-btn-txt); white-space: nowrap;
}
.acc-btn-primaire {
  background: linear-gradient(180deg, #12664f, #0f5c49);
  color: #fff; font-weight: 600; border-color: #0b4436;
  box-shadow: 0 1px 2px rgba(11, 68, 54, 0.35);
}
.acc-btn-primaire:hover { background: linear-gradient(180deg, #0f5c49, #0b4436); }
.acc-btn-lg { padding: 15px 30px; font-size: 15px; }
/* Dans le bandeau sombre, le bouton neutre suit le bandeau, pas la page. */
.acc-site-header .acc-btn:not(.acc-btn-primaire) {
  background: transparent; color: var(--acc-bandeau-txt); border-color: #3d4a42;
}

/* ═══════════ Sections ═══════════ */
.acc-section { position: relative; padding: var(--acc-sp-28) 0; }
.acc-section-head { max-width: 720px; margin: 0 auto var(--acc-sp-16); text-align: center; }
.acc-eyebrow {
  display: inline-block; font-family: var(--acc-titre); font-weight: 700;
  font-size: 12.5px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--acc-accent); padding: 6px 14px; border-radius: 999px;
  background: var(--acc-surface); border: 1px solid var(--acc-border);
}
.acc-h2 {
  font-family: var(--acc-titre); font-weight: 800;
  font-size: clamp(28px, 5vw, 40px); line-height: 1.14; letter-spacing: -0.02em;
  margin-top: var(--acc-sp-5); text-wrap: balance;
}
.acc-section-head p {
  margin-top: var(--acc-sp-5); font-size: 16.5px; line-height: 1.7;
  color: var(--acc-muted); text-wrap: pretty;
}

/* ═══════════ Hero ═══════════ */
.acc-hero { position: relative; padding: var(--acc-sp-20) 0 var(--acc-sp-28); }
.acc-hero-grid { display: grid; grid-template-columns: 1fr; gap: var(--acc-sp-16); align-items: center; }
.acc-hero h1 {
  font-family: var(--acc-titre); font-weight: 800;
  font-size: clamp(34px, 6.4vw, 56px); line-height: 1.07; letter-spacing: -0.028em;
  margin: var(--acc-sp-6) 0 var(--acc-sp-6);
}
.acc-hero-sub {
  font-size: 17.5px; line-height: 1.68; color: var(--acc-muted);
  max-width: 33rem; margin-bottom: var(--acc-sp-10); text-wrap: pretty;
}
.acc-hero-actions { display: flex; flex-wrap: wrap; gap: var(--acc-sp-3); margin-bottom: var(--acc-sp-10); }
.acc-trust { display: flex; flex-wrap: wrap; gap: var(--acc-sp-3) var(--acc-sp-6); font-size: 13px; color: var(--acc-faint); }
.acc-trust li { position: relative; padding-left: 16px; }
.acc-trust li::before {
  content: ""; position: absolute; left: 0; top: 50%;
  width: 6px; height: 6px; margin-top: -3px; border-radius: 50%;
  background: var(--acc-accent);
}

/* ── MASQUAGE TYPOGRAPHIQUE. Chaque ligne est un bloc en `overflow: hidden`
      qui recadre son enfant. Les lignes sont écrites à la main dans le HTML :
      aucun découpage par script, donc rien à reconstruire si le script manque.
      Sans `.acc-js`, l'enfant n'est pas translaté et la ligne est lisible. */
.acc-ligne { display: block; overflow: hidden; padding-bottom: 0.08em; }
.acc-ligne > span { display: block; will-change: transform; }

/* ═══════════ Illustration des statuts ═══════════ */
.acc-hero-visuel { display: flex; justify-content: center; }
.acc-trieur {
  width: min(440px, 100%); padding: var(--acc-sp-5);
  background: var(--acc-card); border: 1px solid var(--acc-border);
  border-radius: var(--acc-radius-lg);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.28);
  display: flex; flex-direction: column; gap: var(--acc-sp-3);
}
html[data-theme="clair"] .acc-trieur { box-shadow: 0 20px 50px rgba(18, 33, 28, 0.12); }
.acc-trieur-tete { display: flex; align-items: baseline; justify-content: space-between; padding-bottom: var(--acc-sp-3); border-bottom: 1px solid var(--acc-border-soft); }
.acc-trieur-titre { font-family: var(--acc-titre); font-weight: 700; font-size: 13px; }
.acc-trieur-meta { font-size: 12px; font-weight: 600; color: var(--acc-faint); }
.acc-offre {
  display: flex; align-items: center; gap: var(--acc-sp-4);
  padding: var(--acc-sp-4); border-radius: var(--acc-radius);
  background: var(--acc-surface); border: 1px solid var(--acc-border-soft);
  border-left: 3px solid var(--acc-accent);
}
.acc-offre.acc-o-flag   { border-left-color: var(--acc-flag); }
.acc-offre.acc-o-reject { border-left-color: var(--acc-reject); }
.acc-etat {
  flex-shrink: 0; font-family: var(--acc-titre); font-weight: 700;
  font-size: 11px; letter-spacing: 0.04em; padding: 4px 10px; border-radius: 999px;
  background: var(--acc-surface-up); color: var(--acc-accent);
  border: 1px solid var(--acc-border);
}
.acc-o-flag .acc-etat   { color: var(--acc-flag); }
.acc-o-reject .acc-etat { color: var(--acc-reject); }
.acc-lignes { display: flex; flex-direction: column; gap: 7px; flex: 1; }
.acc-lignes i { display: block; height: 6px; border-radius: 999px; background: var(--acc-border); }
.acc-lignes i:last-child { opacity: 0.55; }

/* ═══════════ Cartes ═══════════ */
.acc-cartes { display: grid; grid-template-columns: 1fr; gap: var(--acc-sp-5); max-width: 980px; margin: 0 auto; }
.acc-carte {
  padding: var(--acc-sp-8); border-radius: var(--acc-radius-lg);
  background: var(--acc-card); border: 1px solid var(--acc-border);
}
html[data-theme="clair"] .acc-carte { box-shadow: 0 1px 3px rgba(18, 33, 28, 0.06); }
.acc-carte h3 { font-family: var(--acc-titre); font-weight: 700; font-size: 20px; line-height: 1.3; margin-bottom: var(--acc-sp-3); }
.acc-carte p { font-size: 15px; line-height: 1.68; color: var(--acc-muted); }

/* ═══════════ Section ÉPINGLÉE ═══════════
   Le conteneur est haut ; son enfant colle en haut de la fenêtre et y reste
   pendant que la fenêtre parcourt la hauteur restante. Le script convertit
   cette progression en index d'étape. Sans script, `.acc-etape` reste dans son
   état visible et les trois issues sont simplement empilées. */
.acc-epingle-piste { position: relative; }
.acc-epingle-vue { padding: var(--acc-sp-20) 0; }
.acc-epingle-carte {
  max-width: 760px; margin: 0 auto;
  padding: var(--acc-sp-10) var(--acc-sp-8);
  background: var(--acc-card); border: 1px solid var(--acc-border);
  border-radius: var(--acc-radius-lg);
}
html[data-theme="clair"] .acc-epingle-carte { box-shadow: 0 20px 50px rgba(18, 33, 28, 0.10); }
.acc-etapes { display: flex; flex-direction: column; gap: var(--acc-sp-5); }
.acc-etape { display: flex; gap: var(--acc-sp-5); align-items: flex-start; }
.acc-etape-puce {
  flex-shrink: 0; width: 42px; height: 42px; border-radius: 999px;
  display: flex; align-items: center; justify-content: center;
  font-family: var(--acc-titre); font-weight: 800; font-size: 15px;
  background: var(--acc-surface-up); border: 1px solid var(--acc-border);
  color: var(--acc-accent);
}
.acc-e-flag   .acc-etape-puce { color: var(--acc-flag); }
.acc-e-reject .acc-etape-puce { color: var(--acc-reject); }
.acc-etape h3 { font-family: var(--acc-titre); font-weight: 700; font-size: 19px; margin-bottom: 6px; }
.acc-etape p { font-size: 15px; line-height: 1.66; color: var(--acc-muted); }
/* Jauge de progression : animée en `scaleX`, jamais en `width`. */
.acc-jauge { height: 3px; border-radius: 999px; background: var(--acc-border-soft); margin-bottom: var(--acc-sp-8); overflow: hidden; }
/* État par défaut : jauge PLEINE. Sous mouvement réduit, ou sans script, il
   n'y a pas de séquence à parcourir ; une jauge figée à zéro se lirait comme
   un défaut. Le départ à zéro n'existe que sous `.acc-js`, plus bas. */
.acc-jauge i { display: block; height: 100%; background: var(--acc-accent); transform: scaleX(1); transform-origin: left center; }

/* ═══════════ Appel final et pied ═══════════ */
.acc-cta-inner {
  max-width: 680px; margin: 0 auto; text-align: center;
  padding: var(--acc-sp-20) var(--acc-sp-8);
  background: var(--acc-card); border: 1px solid var(--acc-border);
  border-radius: var(--acc-radius-lg);
}
.acc-cta-inner h2 { font-family: var(--acc-titre); font-weight: 800; font-size: clamp(26px, 4.5vw, 36px); line-height: 1.2; letter-spacing: -0.02em; margin-bottom: var(--acc-sp-6); text-wrap: balance; }
.acc-cta-inner p { color: var(--acc-muted); font-size: 16px; margin-bottom: var(--acc-sp-8); }
/* PIED DE PAGE : celui de l'application, mesuré sur /connexion — aligné à
   gauche, largeur maximale 1240 px, remplissage 17,6 / 22,4 / 35,2 px, filet
   de 1 px, texte à 12,48 px, marges de paragraphe à 4,8 px. La version
   centrée d'avant était le seul bloc de la page à ne ressembler à rien
   d'autre dans le produit. */
.acc-site-footer {
  max-width: 1240px; margin: 0 auto;
  padding: 17.6px 22.4px 35.2px;
  border-top: 1px solid var(--acc-fil-pied);
  color: var(--acc-pied-txt);
  font-size: 12.48px;
}
.acc-footer-inner { display: block; text-align: start; }
.acc-footer-brand { font-family: var(--acc-titre); font-weight: 800; font-size: 12.48px; color: var(--acc-pied-txt); }
.acc-footer-note { font-size: 12.48px; color: var(--acc-pied-txt); line-height: 1.6; max-width: none; margin: 4.8px 0; }
/* Le lien de la politique n'est pas mis en évidence par la couleur dans le
   pied applicatif : même teinte que le texte, simplement souligné. */
.acc-footer-lien { font-size: 12.48px; color: var(--acc-pied-txt); text-decoration: underline; text-underline-offset: 2px; }
.acc-footer-lien:hover { color: var(--acc-text); }

/* ═══════════════════════════════════════════════════════════════════════════
   ANIMATIONS. Tout ce qui suit est doublement conditionné : par `.acc-js`
   (le script s'est exécuté) et par `prefers-reduced-motion: no-preference`.
   Sous `reduce`, aucune de ces règles n'existe.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: no-preference) {

  /* ── Micro-interactions. Ressort partout, sur transform seulement. ── */
  .page-accueil .acc-btn,
  .page-accueil .acc-theme-btn,
  .page-accueil .acc-carte,
  .page-accueil .acc-offre {
    transition: transform 0.34s var(--acc-ressort), opacity 0.34s var(--acc-ressort);
  }
  .page-accueil .acc-btn:hover,
  .page-accueil .acc-theme-btn:hover { transform: translateY(-3px) scale(1.03); }
  .page-accueil .acc-btn:active { transform: translateY(-1px) scale(0.99); }
  .page-accueil .acc-carte:hover { transform: translateY(-5px); }

  /* ── Masquage typographique ── */
  .acc-js .page-accueil .acc-ligne > span {
    transform: translateY(115%);
    transition: transform 0.86s var(--acc-sortie);
    transition-delay: var(--acc-d, 0s);
  }
  .acc-js .page-accueil .acc-vu .acc-ligne > span { transform: translateY(0); }

  /* ── Apparitions simples ── */
  .acc-js .page-accueil .acc-monte {
    opacity: 0; transform: translateY(26px);
    transition: opacity var(--acc-dur) var(--acc-sortie),
                transform var(--acc-dur) var(--acc-ressort);
    transition-delay: var(--acc-d, 0s);
  }
  .acc-js .page-accueil .acc-monte.acc-vu { opacity: 1; transform: none; }

  /* ── Section épinglée : les trois issues se révèlent l'une après l'autre ──
     LA RÉVÉLATION NE TOUCHE PLUS À L'OPACITÉ, et ce n'est pas un détail.

     Signalé par Lighthouse en contraste insuffisant sur « Retenue »,
     « Signalée » et « Écartée », titres et paragraphes, en rendu bureau
     seulement. La cause n'était PAS une couleur : mesurées sur la page, les
     couleurs seules donnent 16,67:1 pour les titres et 6,86:1 pour le texte
     en thème clair, 14,79:1 et 8,37:1 en thème sombre. Toutes très au-dessus
     des seuils. C'est l'état de départ `opacity: 0.22` qui les écrasait à
     1,58:1 et 1,39:1, le temps que le défilement pose `.acc-on`.

     Le rendu bureau seul était touché parce que le palier mobile annule déjà
     cette animation, plus bas dans cette feuille. Ce n'était donc pas un
     artefact de résolution du rapport, mais une vraie différence de style.

     POURQUOI SUPPRIMER LE FONDU PLUTÔT QUE DE REMONTER SA VALEUR. Le calcul
     ne laisse pas le choix : pour que le paragraphe atteigne 4,5:1 pendant
     l'animation, il faudrait partir de 0,83 en thème clair et de 0,67 en
     thème sombre. Un fondu de 0,83 vers 1 ne se voit pas. Le mouvement porte
     donc seul la révélation, et le texte reste lisible du premier au dernier
     instant, quel que soit l'endroit où la page est ouverte.

     Effet de bord recherché : le contraste ne dépend plus de l'animation. Un
     futur changement de palette ne peut plus réintroduire ce défaut par la
     bande. */
  .acc-js .page-accueil .acc-etape {
    transform: translateY(14px) scale(0.985);
    transition: transform 0.5s var(--acc-ressort);
  }
  .acc-js .page-accueil .acc-etape.acc-on { transform: none; }
  .acc-js .page-accueil .acc-jauge i {
    transform: scaleX(var(--acc-p, 0));   /* remplace le scaleX(1) par défaut */
    transition: transform 0.12s linear;   /* suit le doigt : un ressort ici
                                             donnerait une jauge élastique */
  }

  /* ── Empilement spatial. La section sortante recule d'un cran et
        s'assombrit pendant que la suivante glisse par-dessus. `--acc-out`,
        de 0 à 1, vient du script : c'est la part de la fenêtre déjà occupée
        par la section suivante.

        PAS DE `position: sticky` sur la section qui recule. Une section plus
        haute que la fenêtre, collée à `top: 0`, ne montrerait jamais son bas :
        elle se fige dès que son haut touche zéro et le reste sort par le bas.
        Le recul et le voile suffisent à donner la profondeur, sans ce piège
        et sans dépendre de la hauteur de fenêtre. ── */
  .acc-js .page-accueil .acc-pile {
    transform: scale(calc(1 - 0.05 * var(--acc-out, 0)));
    transform-origin: center 30%;
    will-change: transform;
  }
  .acc-js .page-accueil .acc-pile::after {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background: var(--acc-veil); opacity: calc(0.5 * var(--acc-out, 0));
  }
  /* La section qui glisse par-dessus doit être opaque, sinon la section qui
     recule se voit au travers. */
  .acc-js .page-accueil .acc-couvre {
    position: relative; z-index: 2; background: var(--acc-bg);
    border-top-left-radius: var(--acc-radius-lg);
    border-top-right-radius: var(--acc-radius-lg);
  }

  /* ── ÉPINGLAGE. La piste haute et le collage n'existent que sous `.acc-js`
        et hors mouvement réduit : sans script, la piste reprend sa hauteur
        naturelle et la section se lit d'un bloc. Écarté sous 721 px, voir
        plus bas. ── */
  @media (min-width: 721px) {
    .acc-js .page-accueil .acc-epingle-piste { height: 320vh; }
    .acc-js .page-accueil .acc-epingle-vue {
      position: sticky; top: 0; min-height: 100vh;
      display: flex; flex-direction: column; justify-content: center;
    }
  }
}

/* ═══════════ Paliers ═══════════ */
@media (min-width: 721px) {
  .acc-site-nav { display: flex; }
  .acc-signin { display: inline; }
  .acc-cartes { grid-template-columns: 1fr 1fr; gap: var(--acc-sp-6); }
  .acc-cartes > :last-child:nth-child(odd) { grid-column: 1 / -1; }
}
@media (min-width: 1101px) {
  .acc-hero-grid { grid-template-columns: 1.12fr 0.88fr; }
  .acc-hero { padding-block: var(--acc-sp-28); }
  .acc-cartes { grid-template-columns: repeat(6, 1fr); }
  .acc-cartes > * { grid-column: span 2; }
  .acc-cartes > :last-child:nth-child(3n + 1) { grid-column: span 6; }
  .acc-cartes > :nth-last-child(2):nth-child(3n + 1),
  .acc-cartes > :nth-last-child(2):nth-child(3n + 1) ~ * { grid-column: span 3; }
  .acc-cartes:has(> :last-child:nth-child(4)) { grid-template-columns: 1fr 1fr; }
  .acc-cartes:has(> :last-child:nth-child(4)) > * { grid-column: auto; }
}

/* ── MOBILE : ni épinglage ni empilement ────────────────────────────────────
   Les deux dépendent de la hauteur de fenêtre, que les barres d'adresse
   mobiles font varier en cours de défilement : la section épinglée saute et
   l'empilement se décale. Sous 721 px, la piste haute redevient de hauteur
   naturelle, le sticky est retiré, et les trois issues sont révélées par
   simple apparition comme le reste. */
@media (max-width: 720px) {
  .acc-js .page-accueil .acc-pile { transform: none; }
  .acc-js .page-accueil .acc-pile::after { display: none; }
  /* `opacity: 1` a été retiré avec le fondu qu'il annulait : plus rien ne
     touche à l'opacité des étapes, à aucun palier. Seule reste l'annulation
     du mouvement, qui garde sa raison d'être ici. */
  .acc-js .page-accueil .acc-etape { transform: none; }
  .acc-section { padding: var(--acc-sp-20) 0; }
  /* Le masquage typographique suppose UNE ligne par bloc `.acc-ligne`. À
     34 px, « Chercher un emploi » repassait à la ligne dans 335 px utiles et
     la cadence du titre se cassait. Taille recalée sur la largeur réelle. */
  .acc-hero h1 { font-size: clamp(27px, 8.2vw, 40px); }
  .acc-epingle-carte { padding: var(--acc-sp-8) var(--acc-sp-5); }
  .acc-etape { gap: var(--acc-sp-4); }
}
/* ── Page de méthode (« À propos ») ──────────────────────────────────────
   CONFINÉE comme le reste : préfixe `acc-`, sous `.page-accueil` que porte le
   gabarit public. Aucune valeur nouvelle, les couleurs et les espacements
   viennent des variables déjà déclarées plus haut, donc les contrastes déjà
   contrôlés dans les deux thèmes valent ici sans nouvelle vérification de
   palette.

   Aucune classe d'animation n'est utilisée sur cette page : un texte qui
   attend un script pour devenir visible est un texte qu'un moteur ou une
   personne peut ne jamais lire. */
.acc-prose-vue { padding: var(--acc-sp-20) 0 var(--acc-sp-28); }
.acc-prose {
  /* Colonne de lecture, pas la pleine largeur du conteneur : au-delà d'une
     soixantaine de caractères par ligne, l'œil perd le début de la suivante. */
  max-width: 680px;
  margin: 0 auto;
}
.acc-prose h1 { margin-bottom: var(--acc-sp-10); }
.acc-prose h2 {
  font-family: var(--acc-titre);
  font-size: 21px;
  font-weight: 700;
  margin: var(--acc-sp-10) 0 var(--acc-sp-4);
  color: var(--acc-text);
}
.acc-prose h2:first-of-type { margin-top: var(--acc-sp-8); }
.acc-prose p {
  margin: 0 0 var(--acc-sp-5);
  font-size: 16px;
  line-height: 1.72;
  color: var(--acc-muted);
}
.acc-prose a { color: var(--acc-accent); }

@media (max-width: 720px) {
  .acc-prose-vue { padding: var(--acc-sp-16) 0 var(--acc-sp-20); }
  .acc-prose h2 { font-size: 19px; }
}

/* ═══════════════════════ MATCH ETHICS HOMEPAGE END ═══════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════
   CRÉATION D'UN CV GÉNÉRAL — choix du gabarit, puis formulaire.
   Aucune couleur nouvelle : tout passe par les variables de thème, donc le
   mode sombre suit sans règle dédiée.
   ═══════════════════════════════════════════════════════════════════════ */

.creer-cv-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.creer-cv-texte { flex: 1 1 22rem; min-width: 0; }
.creer-cv-texte .panel-label { margin-bottom: 0.35rem; }

/* ── Grille des gabarits ────────────────────────────────────────────────
   TROIS PALIERS, et le nombre de colonnes est écrit en clair plutôt que
   confié à `auto-fill` : la consigne porte sur le nombre de colonnes par
   palier, pas sur une largeur minimale de carte. */
.styles-grille {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.1rem;
  margin-top: 1.1rem;
}
@media (min-width: 721px) {
  .styles-grille { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1101px) {
  .styles-grille { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.style-carte {
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  overflow: hidden;
  transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease);
}

/* La vignette occupe le FORMAT D'UNE FEUILLE VERTICALE : 8,5 sur 11, celui
   du document réel. `object-position: top` montre l'en-tête et les premières
   rubriques, la partie qui distingue les gabarits entre eux. */
.style-apercu {
  display: block;
  aspect-ratio: 8.5 / 11;
  overflow: hidden;
  background: #fff;
  border-bottom: 1px solid var(--line);
}
.style-apercu img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
}

/* SURVOL : agrandissement léger, seulement là où un vrai survol existe.
   Sous `pointer: coarse`, l'état de survol reste collé après un appui sur
   iOS, et la carte resterait agrandie une fois le doigt parti. */
@media (hover: hover) and (pointer: fine) {
  .style-carte:hover {
    transform: scale(1.025);
    box-shadow: var(--shadow-2);
  }
}
.style-carte:focus-within {
  box-shadow: var(--shadow-2), var(--ring);
}
@media (prefers-reduced-motion: reduce) {
  .style-carte { transition: none; }
  .style-carte:hover { transform: none; }
}

.style-info {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.85rem 0.95rem 1rem;
  flex: 1;
}
.style-nom { margin: 0; font-size: 1.02rem; color: var(--ink); }
.style-situation {
  margin: 0;
  font-size: 0.86rem;
  line-height: 1.45;
  color: var(--muted);
  flex: 1;
}
.style-choisir { align-self: flex-start; }

/* ── Aperçu détaillé ────────────────────────────────────────────────────
   Une boîte de dialogue native : le piège de focus et la fermeture par Échap
   viennent du navigateur, pas d'un script à maintenir. */
.style-zoom {
  width: min(92vw, 46rem);
  max-height: 90vh;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--ink);
  box-shadow: var(--shadow-2);
  overflow: hidden;
}
.style-zoom::backdrop { background: rgba(15, 25, 20, 0.55); }
.style-zoom-barre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--line);
}
.style-zoom-titre { margin: 0; font-size: 1.05rem; }
.style-zoom-fermer {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: var(--surface-2);
  color: var(--ink);
  cursor: pointer;
}
.style-zoom-fermer:hover { background: var(--row-hover); }
.style-zoom-corps {
  padding: 0.9rem;
  overflow-y: auto;
  max-height: calc(90vh - 9rem);
}
.style-zoom-corps img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  background: #fff;
}
.style-zoom-corps .style-situation { margin-top: 0.75rem; }
.style-zoom-pied {
  padding: 0.75rem 0.9rem;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: flex-end;
}

/* ── Formulaire de saisie ───────────────────────────────────────────────
   Sections repliables : un formulaire de cette longueur d'un seul tenant est
   décourageant sur un téléphone. `<details>` s'ouvre et se ferme sans script. */
.cv-form { display: flex; flex-direction: column; gap: 0.9rem; margin-top: 1.1rem; }

.cv-section {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}
.cv-section > summary {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  flex-wrap: wrap;
  padding: 0.85rem 1rem;
  min-height: 44px;
  cursor: pointer;
  list-style: none;
  background: var(--card-2);
}
.cv-section > summary::-webkit-details-marker { display: none; }
.cv-section > summary::before {
  content: "+";
  font-family: var(--mono, monospace);
  font-weight: 700;
  color: var(--pine);
  width: 1ch;
}
.cv-section[open] > summary::before { content: "\2212"; }
.cv-section > summary:hover { background: var(--row-hover); }
.cv-section-titre { font-weight: 650; color: var(--ink); }
.cv-section-corps {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: 1rem;
  border-top: 1px solid var(--line);
}

.cv-form label { display: block; font-size: 0.9rem; color: var(--ink); }
.cv-form input[type="text"],
.cv-form input[type="tel"],
.cv-form input[type="email"],
.cv-form input[type="number"],
.cv-form select,
.cv-form textarea {
  width: 100%;
  margin-top: 0.28rem;
  box-sizing: border-box;
}
.cv-form textarea { resize: vertical; }

.cv-duo { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.cv-duo > * { flex: 1 1 14rem; min-width: 0; }
.cv-duo > .cv-etroit { flex: 0 1 11rem; }

.cv-dates {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 0.6rem;
}
.cv-dates > .cv-mois { flex: 0 1 9rem; }
.cv-dates > .cv-annee { flex: 0 1 7rem; }

.cv-repet, .cv-bloc {
  border: 1px solid var(--line);
  border-radius: var(--radius-s);
  padding: 0.75rem 0.85rem 0.9rem;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}
.cv-repet > legend, .cv-bloc > legend {
  font-size: 0.82rem;
  font-weight: 650;
  color: var(--muted);
  padding: 0 0.35rem;
}

.cv-requis {
  font-size: 0.72rem;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pine-2);
  background: var(--pine-t);
  border-radius: 999px;
  padding: 0.1rem 0.45rem;
  margin-left: 0.3rem;
}

.cv-case {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 44px;
  font-size: 0.9rem;
}
.cv-case input { width: auto; margin: 0; }
.cv-case-inline { flex: 0 1 auto; }

/* Ce que le formulaire NE demande PAS, et pourquoi. Discret, mais lisible :
   contraste vérifié dans les deux thèmes. */
.cv-note-absence {
  margin: 0;
  font-size: 0.83rem;
  line-height: 1.5;
  color: var(--ink-2);
  background: var(--surface-2);
  border-left: 3px solid var(--line-2);
  border-radius: 0 var(--radius-s) var(--radius-s) 0;
  padding: 0.7rem 0.85rem;
}

.cv-envoi {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.cv-envoi .hint { flex: 1 1 24rem; margin: 0; }

@media (max-width: 720px) {
  .cv-envoi, .creer-cv-card { flex-direction: column; align-items: stretch; }
  /* Mesuré à 500 px : le bouton partagé faisait 39 px de haut. Sur un
     formulaire aussi long, l'action finale mérite une cible confortable.
     La règle reste bornée aux deux classes de ce lot. */
  .cv-envoi .btn, .creer-cv-card .btn { width: 100%; min-height: 44px; }
  .cv-dates > .cv-mois, .cv-dates > .cv-annee { flex: 1 1 8rem; }
}


/* ── Formulaire de CV : ajouts du lot de correction ─────────────────────── */

/* Message d'erreur POSÉ À CÔTÉ DU CHAMP fautif. Un bandeau global sur un
   formulaire de quarante champs laisse chercher lequel a échoué. */
.cv-erreur {
  margin: 0.3rem 0 0;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--brick);
  background: var(--brick-t);
  border-left: 3px solid var(--brick);
  border-radius: 0 var(--radius-s) var(--radius-s) 0;
  padding: 0.35rem 0.5rem;
}
.cv-form [aria-invalid="true"] { border-color: var(--brick); }

/* Une ligne répétable : type de lien et adresse, ou langue et niveau. */
.cv-ligne { display: flex; flex-wrap: wrap; gap: 0.7rem; align-items: flex-start; }
.cv-ligne > * { flex: 1 1 12rem; min-width: 0; }
.cv-ligne > .cv-etroit { flex: 0 1 11rem; }

.cv-ajouter { align-self: flex-start; min-height: 44px; }
.cv-repet > .cv-ajouter, .cv-section-corps > .cv-ajouter { margin-top: 0.2rem; }

.cv-fin { display: contents; }

@media (max-width: 720px) {
  .cv-ligne > *, .cv-ligne > .cv-etroit { flex: 1 1 100%; }
  .cv-ajouter { width: 100%; }
}

/* ── Sélection étendue à tout le résultat filtré ──────────────────────── */
.sel-etendue {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 1rem;
  margin: 0.5rem 0 0;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--line);
  border-left: 3px solid var(--pine);
  border-radius: 0 var(--radius-s) var(--radius-s) 0;
  background: var(--surface-2);
  color: var(--ink-2);
}
.sel-etendue-choix {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 44px;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}
.sel-etendue-choix input { margin: 0; }
