/* ==========================================================================
   styles-dashboard-v2.css : styles du dashboard (public/index.html depuis la
   bascule en prod). Palette et polices identiques à la
   charte "papier chaud" (docs/ARCHITECTURE.md) : rien n'est redéfini ici,
   tout vient des tokens de styles-index.css, chargé avant celui-ci. Ce
   fichier n'ajoute QUE des tokens de mise en page nommés (pas de valeurs
   magiques) et les composants propres à la nouvelle grille.
   ========================================================================== */

:root {
  --dv2-radius-lg: var(--radius-lg);
  --dv2-radius-md: var(--radius-md);
  --dv2-radius-sm: var(--radius-sm);
  --dv2-gap-lg: var(--esp-3);
  --dv2-gap-md: var(--esp-2);
  --dv2-shadow-soft: var(--ombre-carte);
  --dv2-shadow-lift: var(--ombre-portee);
  --dv2-glass-bg: var(--card);
  --dv2-glass-blur: 0px;
  --dv2-dur: var(--dur);
  --dv2-ease: cubic-bezier(0.2, 0.7, 0.3, 1);
  /* Ease-out franc : les courbes CSS natives sont trop molles, le mouvement
     doit démarrer vite pour que l'interface réponde "tout de suite". */
  --dv2-ease-out: var(--ease-out);
}

@media (prefers-reduced-motion: reduce) {
  :root { --dv2-dur: 0ms; }
}

/* ---------- Largeur de la page ----------
   Le dashboard est le seul écran où l'on travaille vraiment : une liste de
   candidatures, un calendrier et des tâches côte à côte. Les 1040 px communs
   au reste du site (styles-index.css) l'étranglaient : les titres de poste
   passaient à la ligne, la colonne de droite montait sur les pieds de la
   liste. Cette feuille n'est chargée que par index.html : les autres pages
   gardent leur largeur de lecture. */
.screen {
  max-width: 1320px;
}

/* ---------- Grande card englobante : fond glass permanent, non
   désactivable (l'ancienne bascule de test a été retirée). ---------- */
.dv2-shell {
  background: var(--dv2-glass-bg);
  backdrop-filter: blur(var(--dv2-glass-blur));
  -webkit-backdrop-filter: blur(var(--dv2-glass-blur));
  border-radius: var(--dv2-radius-lg);
  box-shadow: var(--dv2-shadow-soft);
  padding: var(--dv2-gap-lg);
}

/* ---------- Tête de page ----------
   Le titre, l'état de la liste, et l'action qui crée une candidature.

   La bande de six cartes de chiffres qui vivait ici a été retirée au lot 4 :
   deux d'entre elles répétaient mot pour mot les tuiles de Ton Espace, une
   troisième redisait l'agenda affiché plus bas. Les trois dernières sont un
   bilan et non une action : elles tiennent en une ligne de texte. Une page
   de travail commence par ce sur quoi on travaille, pas par un mur de
   chiffres.

   Aucune valeur en dur : tout vient de design-tokens.css. */
.dv2-tete {
  margin-bottom: var(--esp-4);
}
.dv2-tete-ligne {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--esp-3);
  flex-wrap: wrap;
}
/* min-width: 0 : sans lui, un titre long refuse de se couper et pousse les
   boutons hors de la ligne. */
.dv2-tete-titre { min-width: 0; }
.dv2-tete-actions {
  display: flex;
  align-items: center;
  gap: var(--esp-1);
  flex-wrap: wrap;
}

/* L'état de la liste : la seule ligne que l'on lit avant d'agir. */
.dv2-etat {
  margin: var(--esp-1) 0 0;
  font-size: var(--t-corps);
  color: var(--muted);
  line-height: 1.45;
}
/* Le retard ne prend sa couleur que s'il y en a vraiment un : un zéro en
   terracotta est une fausse alerte, et on finit par ne plus la voir. */
.dv2-etat-alerte {
  color: var(--alerte-texte);
  font-weight: var(--graisse-moyen);
}

/* ---------- Les cinq cartes de chiffres ----------
   Petites, de taille égale, alignées sur une seule rangée tant que l'écran
   le permet. Trois d'entre elles sont des boutons : elles filtrent la liste.
   Le chiffre est en chasse fixe (règle de la charte : une mesure s'aligne
   verticalement) et le libellé est écrit dessous, en toutes lettres. */
.dv2-kpis {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--esp-2);
  margin: var(--esp-3) 0 0;
}
/* Rien à dire (aucune candidature, ou pas encore connecté) : pas de rangée
   de cartes vides sous le titre. */
.dv2-kpis:empty { display: none; }

@media (max-width: 1040px) {
  .dv2-kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
  .dv2-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.dv2-kpi {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--esp-0-5);
  min-height: 104px;
  padding: var(--esp-2);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-carte);
  box-shadow: var(--ombre-douce);
  text-align: left;
  font-family: var(--police);
}

/* Un bouton reste un bouton : curseur main, réaction au survol, anneau de
   focus au clavier. Sans ça, personne ne devine qu'une carte se clique. */
.dv2-kpi-clic {
  cursor: pointer;
  width: 100%;
  transition: transform var(--dur-court) var(--ease-sortie),
              box-shadow var(--dur-court) var(--ease-sortie),
              border-color var(--dur-court) var(--ease-sortie);
}
.dv2-kpi-clic:hover {
  transform: translateY(-2px);
  box-shadow: var(--ombre-carte);
  border-color: var(--metal);
}
.dv2-kpi-clic:focus-visible {
  outline: none;
  box-shadow: var(--focus-anneau);
}
/* Carte active = filtre posé. Le liseré bleu dit "c'est ce que tu regardes
   en ce moment", et recliquer l'enlève. */
.dv2-kpi-clic[aria-pressed="true"] {
  border-color: var(--blue);
  box-shadow: inset 0 0 0 1px var(--blue), var(--ombre-douce);
  background: var(--fond-neutre);
}

.dv2-kpi-valeur {
  font-family: var(--police-chiffres);
  font-size: 1.75rem;
  font-weight: var(--graisse-titre);
  line-height: 1.1;
  color: var(--ink);
  letter-spacing: -0.02em;
}
.dv2-kpi-unite {
  font-size: 1rem;
  margin-left: 1px;
  color: var(--muted);
}
.dv2-kpi-attente { color: var(--muted-doux); }

.dv2-kpi-libelle {
  font-size: var(--t-interface);
  font-weight: var(--graisse-moyen);
  color: var(--ink);
  line-height: 1.25;
}
.dv2-kpi-detail {
  font-size: 0.75rem;
  color: var(--muted-doux);
  line-height: 1.3;
  margin-top: auto;
}

/* Les tons. L'alerte n'emprunte l'orange que quand il y a vraiment un
   retard : un zéro en terracotta est une fausse alerte, et on finit par ne
   plus la voir du tout. */
.dv2-kpi-alerte { background: var(--fond-alerte); border-color: transparent; }
.dv2-kpi-alerte .dv2-kpi-valeur,
.dv2-kpi-alerte .dv2-kpi-libelle { color: var(--alerte-texte); }
.dv2-kpi-alerte .dv2-kpi-detail { color: var(--alerte-texte); opacity: 0.8; }
.dv2-kpi-calme .dv2-kpi-valeur { color: var(--succes-texte); }
.dv2-kpi-entretien .dv2-kpi-valeur { color: var(--entretien-texte); }

/* La courbe des 7 derniers jours, seul ornement de la rangée, et il porte
   une vraie donnée. */
.dv2-bilan-spark {
  color: var(--succes);
  vertical-align: middle;
}

/* ---------- Grille deux colonnes ---------- */
.dv2-grid {
  display: grid;
  /* La colonne de droite (calendrier + tâches) a une largeur naturelle : la
     grille d'un mois mesure 354 px cadres et marges compris, elle n'a aucune
     raison de grandir avec l'écran. 380 px lui laissent de l'air, et toute
     la largeur gagnée va à la liste, qui elle en profite.
     Ne pas descendre sous 380 : la grille du calendrier déborderait. */
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: var(--dv2-gap-lg);
  align-items: start;
}
@media (max-width: 980px) {
  /* Sous 980 px, la liste et le calendrier passent l'un sous l'autre plutôt
     que de se serrer : rétrécir la colonne de droite ferait déborder la
     grille du mois.
     minmax(0, 1fr) et pas 1fr : sur une colonne, "1fr" garde un plancher à la
     largeur minimale du contenu (le segment de filtres, le calendrier). La
     colonne dépassait alors de 32 px sur un écran de 375 px, et la carte
     blanche se retrouvait coupée à droite. */
  .dv2-grid { grid-template-columns: minmax(0, 1fr); }
  .dv2-col-side { max-width: 380px; }
}

/* ---------- Colonne liste ---------- */
/* Chercher et filtrer agissent sur la même liste : une seule barre. Le
   bouton d'ajout, lui, est monté dans la tête de page : il ne filtre rien,
   il crée. */
.dv2-col-header {
  display: flex;
  align-items: center;
  gap: var(--esp-1);
  margin-bottom: 12px;
  flex-wrap: wrap;
}
/* Deux axes de filtrage, deux rangées, et toujours les mêmes : la recherche
   et le statut (ce que je cherche) sur la première, les archives (ce que je
   range) sur la seconde. Le retour à la ligne est décidé ici, il ne dépend
   pas de la largeur disponible : la barre a la même forme sur un portable et
   sur un grand écran. */
.dv2-col-header .dv2-filtres {
  flex: 0 0 100%;
  margin-bottom: 0;
}
/* Le menu des statuts : un champ, pas un bouton. Il règle la vue, il ne
   déclenche rien. */
.dv2-select-statut {
  flex: 0 0 auto;
  padding: 9px 12px;
  border: 1px solid var(--divider);
  border-radius: var(--dv2-radius-sm);
  background: var(--card);
  color: var(--text);
  font-family: var(--police-texte);
  font-size: 13px;
  cursor: pointer;
}
.dv2-select-statut:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.dv2-col-header input[type="search"] {
  flex: 1 1 180px;
  padding: 9px 12px;
  border: 1px solid var(--divider);
  border-radius: var(--dv2-radius-sm);
  font-family: var(--police-texte);
  font-size: 13px;
  background: var(--card);
  color: var(--text);
}
/* ---------- Filtre Actives / Archivées / Toutes ----------
   Segment posé sur la coque, pas un rang d'onglets : trois états d'une même
   liste, pas trois pages. Le bouton actif prend la surface (--card) plutôt
   qu'une couleur pleine : c'est un réglage de vue, il ne doit pas ressembler
   à une action. */
.dv2-filtres {
  display: inline-flex;
  gap: 2px;
  background: var(--bg);
  border-radius: 999px;
  padding: 3px;
  margin-bottom: 12px;
}
.dv2-filtre {
  background: none;
  border: none;
  border-radius: 999px;
  padding: 5px 13px;
  font-family: var(--police-texte);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background-color var(--dv2-dur) var(--dv2-ease-out),
              color var(--dv2-dur) var(--dv2-ease-out),
              transform 140ms var(--dv2-ease-out);
}
.dv2-filtre:active { transform: scale(0.96); }
.dv2-filtre:focus-visible { outline: 2px solid var(--green); outline-offset: 1px; }
.dv2-filtre[aria-pressed="true"] {
  background: var(--card);
  color: var(--text);
  font-weight: 600;
  box-shadow: var(--dv2-shadow-soft);
}
@media (hover: hover) and (pointer: fine) {
  .dv2-filtre:not([aria-pressed="true"]):hover { color: var(--text); }
}

/* Carte archivée : rangée, pas désactivée. Elle reste cliquable et lisible,
   juste en retrait ; l'opacité remonte au survol pour qu'on puisse la
   relire sans effort. */
.dv2-carte-archivee { opacity: 0.55; }
.dv2-carte-archivee.ouvert { opacity: 1; }
@media (hover: hover) and (pointer: fine) {
  .dv2-carte-archivee:hover { opacity: 1; }
}

/* Modale "Renommer" : deux champs, même grille que le formulaire d'ajout. */
.dv2-renommer-champs { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 4px 0 10px; text-align: left; }
.dv2-renommer-champs label { font-size: 11.5px; color: var(--text-secondary); display: block; margin-bottom: 3px; }
.dv2-renommer-champs input {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--divider);
  border-radius: 8px;
  font-family: var(--police-texte);
  font-size: 13px;
  background: var(--card);
  color: var(--text);
}
.dv2-champ-erreur { font-size: 12.5px; color: var(--status-refused-text); margin-bottom: 10px; }

/* Contenu du formulaire "Ajouter une offre" (2 voies), dans la modale
   #dv2ColletOverlay (.confirm-box.externe-box, styles-index.css). Les
   onglets utilisent le composant partage .segments/.segment (styles-base.css). */
.dv2-voie-tabs { margin-bottom: 16px; }
.dv2-coller-grille { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 6px; }
.dv2-coller-source { font-size: 12px; color: var(--green); font-weight: 600; margin: 6px 0; }
.dv2-lien-texte-toggle {
  background: none;
  border: none;
  color: var(--green);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  padding: 4px 0 10px;
  text-align: left;
}
.dv2-lien-texte-toggle:hover { text-decoration: underline; }
.dv2-coller-aide { font-size: 12px; color: var(--text-secondary); line-height: 1.5; margin: 0 0 8px; }

/* Sections du formulaire d'ajout : séparées par un filet plutôt qu'encadrées,
   pour garder la modale lisible sans l'empiler de boîtes. */
.dv2-form-section { border-top: 1px solid var(--divider); margin-top: 14px; padding-top: 12px; }
.dv2-form-section-fin { margin-bottom: 14px; }
.dv2-form-legende {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
  margin: 0 0 9px;
}
.dv2-form-facultatif {
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--text-secondary);
}

/* ---------- Les trois blocs numérotés du formulaire d'ajout ----------
   L'offre, ta candidature, les détails. Numérotés parce qu'un formulaire de
   dix champs sans repère se lit comme une liste de courses : on ne sait ni
   où on en est, ni ce qui reste. Séparés par un filet plutôt qu'encadrés,
   pour ne pas empiler les boîtes dans une modale déjà encadrée. */
.dv2-form-bloc + .dv2-form-bloc {
  border-top: 1px solid var(--divider);
  margin-top: var(--esp-2);
  padding-top: var(--esp-2);
}
/* La phrase qui dit à quoi sert le bloc, juste sous son titre. Elle répond à
   "pourquoi vous me demandez ça" avant que la question se pose. */
.dv2-form-aide {
  font-size: 12px;
  color: var(--text-secondary);
  line-height: 1.5;
  margin: -4px 0 10px;
  text-wrap: pretty;
}
/* Trois champs de front dans "Ta candidature" : date, canal, taille. En
   deux colonnes, le troisième se retrouvait seul sur une ligne à moitié
   vide. */
.dv2-form-bloc .dv2-coller-grille { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.dv2-form-bloc:first-of-type .dv2-coller-grille { grid-template-columns: 1fr 1fr; }

/* Les trois étapes de la voie "extension" : une vraie liste numérotée, pas
   trois paragraphes qui se ressemblent. */
.dv2-etapes-extension {
  margin: 0 0 var(--esp-2);
  padding-left: 20px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text);
}
.dv2-etapes-extension li { margin-bottom: 6px; }
/* Un bouton désactivé doit SE VOIR désactivé : en bleu plein, "Installation
   bientôt disponible" ressemblait à un bouton qu'on peut cliquer, et le clic
   sans effet passait pour un bug. */
#dv2PanneauExtension .btn[disabled] {
  background: var(--surface-creuse);
  border-color: var(--divider);
  color: var(--muted-doux);
  cursor: not-allowed;
  box-shadow: none;
}
#dv2ColletOverlay textarea {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--divider);
  border-radius: 8px;
  font-family: var(--police-texte);
  font-size: 13px;
  background: var(--card);
  color: var(--text);
  resize: vertical;
  margin-bottom: 8px;
}
#dv2ColletOverlay input, #dv2ColletOverlay select {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--divider);
  border-radius: 8px;
  font-family: var(--police-texte);
  font-size: 13px;
  margin-bottom: 8px;
  background: var(--card);
  color: var(--text);
}
#dv2ColletOverlay label { font-size: 11.5px; color: var(--text-secondary); display: block; margin-bottom: 3px; }

/* ---------- Contacts / interlocuteurs (mini-cartes dans le détail) ---------- */
.dv2-contact-liste { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.dv2-contact-card {
  background: var(--bg);
  border-radius: 10px;
  padding: 10px 12px;
  border: 1px solid transparent;
}
.dv2-contact-card.dv2-contact-actif { border-color: var(--green); }
.dv2-contact-entete {
  font-size: 13px;
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px;
}
.dv2-contact-poste { font-size: 11.5px; color: var(--text-secondary); }
.dv2-contact-meta { font-size: 11.5px; color: var(--text-secondary); margin-top: 3px; overflow-wrap: anywhere; }
.dv2-contact-badge {
  font-size: 10px;
  font-weight: 600;
  color: var(--accent);
  background: var(--accent-doux);
  padding: 1px 6px;
  border-radius: 999px;
  margin-left: 4px;
}
.dv2-contact-suivi { margin-top: 6px; padding-top: 6px; border-top: 1px dashed var(--divider); }
.dv2-contact-suivi-ligne { font-size: 11.5px; color: var(--text-secondary); line-height: 1.6; }
.dv2-contact-suivi-prochaine { font-weight: 600; color: var(--text); }
.dv2-contact-suivi-prochaine.retard { color: var(--status-refused-text); }
.dv2-contact-ouvrir {
  background: none;
  border: 1px dashed var(--divider);
  border-radius: 8px;
  width: 100%;
  padding: 8px 10px;
  font-family: var(--police-texte);
  font-size: 12.5px;
  font-weight: 600;
  color: var(--green);
  cursor: pointer;
  transition: background-color var(--dv2-dur) var(--dv2-ease-out),
              border-color var(--dv2-dur) var(--dv2-ease-out),
              transform 140ms var(--dv2-ease-out);
}
.dv2-contact-ouvrir:active { transform: scale(0.985); }
@media (hover: hover) and (pointer: fine) {
  .dv2-contact-ouvrir:hover { background: var(--accent-doux); border-color: var(--accent); }
}
/* Coordonnée cliquable : soulignée seulement au survol, pour ne pas
   transformer chaque fiche contact en bloc de liens bleus. */
.dv2-contact-lien { color: var(--green); font-weight: 500; text-decoration: none; }
.dv2-contact-lien:hover { text-decoration: underline; }
.dv2-contact-lien:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; border-radius: 3px; }
.dv2-contact-sans { color: var(--status-refused-text); }

/* Silence prolongé : une ligne, pas un bandeau. C'est une information à
   remarquer du coin de l'oeil, pas une alerte qui bloque le travail. */
.dv2-contact-silence {
  font-size: 11px;
  font-weight: 600;
  color: var(--status-followup-text);
  margin-top: 6px;
}
.dv2-contact-silence::before { content: "• "; }

/* Note libre : ressemble à du texte tant qu'on ne la touche pas, devient un
   champ au focus. Une bordure permanente ajouterait une boîte de plus par
   contact, sur une carte qui en compte déjà beaucoup. */
.dv2-contact-notes {
  width: 100%;
  margin-top: 7px;
  padding: 7px 9px;
  border: 1px solid transparent;
  border-radius: 7px;
  background: transparent;
  font-family: var(--police-texte);
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.5;
  resize: vertical;
  field-sizing: content;
  transition: border-color var(--dv2-dur) var(--dv2-ease-out),
              background-color var(--dv2-dur) var(--dv2-ease-out);
}
.dv2-contact-notes::placeholder { color: var(--text-secondary); opacity: 0.6; }
.dv2-contact-notes:hover { border-color: var(--divider); }
.dv2-contact-notes:focus {
  outline: none;
  border-color: var(--green);
  background: var(--card);
  color: var(--text);
}

/* Pile repliée : les autres interlocuteurs ne sont pas cachés, ils sont
   rangés. Le compteur dit exactement combien il y en a. */
.dv2-contact-autres-toggle {
  align-self: flex-start;
  background: none;
  border: none;
  padding: 2px 0;
  font-family: var(--police-texte);
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  cursor: pointer;
  transition: color var(--dv2-dur) var(--dv2-ease-out);
}
.dv2-contact-autres-toggle:hover { color: var(--green); }
.dv2-contact-autres-toggle:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; border-radius: 4px; }
.dv2-contact-autres { display: flex; flex-direction: column; gap: 8px; }
.dv2-contact-compacte { background: transparent; border: 1px solid var(--divider); }

.dv2-contact-formulaire { background: var(--bg); border-radius: 10px; padding: 11px 12px; margin-top: 8px; }
/* Formulaire d'ajout : une colonne, un champ par ligne. Les 4 champs se
   lisent comme une phrase (qui, quel rôle, par quel moyen, à quelle
   adresse) ; en 3 colonnes on sautait de l'un à l'autre sans ordre. */
.dv2-contact-champ { margin-bottom: 8px; }
.dv2-contact-champ label {
  display: block;
  font-size: 11px;
  font-weight: 500;
  color: var(--text-secondary);
  margin-bottom: 3px;
}
.dv2-contact-champ .dv2-contact-input { margin-bottom: 0; }
.dv2-contact-aide { font-size: 11px; color: var(--text-secondary); line-height: 1.45; margin: 2px 0 9px; text-wrap: pretty; }
.dv2-contact-input {
  width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--divider);
  border-radius: 7px;
  font-size: 12px;
  font-family: var(--police-texte);
  margin-bottom: 6px;
  background: var(--card);
  color: var(--text);
}
.dv2-contact-add {
  background: var(--accent-doux);
  color: var(--accent);
  border: none;
  border-radius: 7px;
  padding: 6px 10px;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: transform 140ms var(--dv2-ease-out);
}
.dv2-contact-add:active { transform: scale(0.97); }

/* ---------- Timeline (historique de la candidature) ----------
   Une v1 volontairement plate : date à gauche, événement à droite, un filet
   vertical pour relier les lignes. Pas de pastilles par type ni de couleurs
   par événement, ça ferait un sapin de Noël pour une information qu'on lit
   de haut en bas. */
.dv2-timeline { list-style: none; margin: 0; padding: 0 0 0 11px; border-left: 1px solid var(--divider); }
.dv2-timeline-ligne {
  display: grid;
  grid-template-columns: 42px minmax(0, 1fr);
  gap: 10px;
  align-items: baseline;
  padding: 5px 0;
}
.dv2-timeline-date {
  font-size: 11px;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.dv2-timeline-texte { font-size: 12.5px; color: var(--text); line-height: 1.4; }
.dv2-timeline-precision { display: block; font-size: 11.5px; color: var(--text-secondary); }
.dv2-timeline-vide { font-size: 12px; color: var(--text-secondary); margin: 0; line-height: 1.5; }

/* ---------- Détail léger + commentaires par relance (C2/C3) ----------
   Modale #dv2DetailOverlay (.confirm-box.externe-box, styles-index.css).
   Chaque commentaire reprend le gabarit "carte" des interlocuteurs
   (.dv2-contact-card) : même famille visuelle pour deux mini-CRM du même
   dashboard, pas deux styles de carte à retenir. */
.dv2-detail-entreprise { margin: -6px 0 2px; font-size: 13.5px; color: var(--text-secondary); }
.dv2-detail-lieu { margin: 0 0 4px; font-size: 12.5px; color: var(--text-secondary); }
.dv2-commentaire-formulaire { margin-top: 10px; }
.dv2-commentaire-formulaire label { font-size: 11.5px; color: var(--text-secondary); display: block; margin-bottom: 3px; }
.dv2-commentaire-formulaire select,
.dv2-commentaire-formulaire textarea {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--divider);
  border-radius: 8px;
  font-family: var(--police-texte);
  font-size: 13px;
  background: var(--card);
  color: var(--text);
  margin-bottom: 10px;
}
.dv2-commentaire-formulaire textarea { resize: vertical; }
.dv2-commentaire {
  background: var(--bg);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 8px;
}
.dv2-commentaire-entete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 4px;
}
.dv2-commentaire-relance { font-size: 11.5px; font-weight: 600; color: var(--green); }
.dv2-commentaire-date { font-size: 11px; color: var(--text-secondary); flex-shrink: 0; }
.dv2-commentaire-texte { margin: 0; font-size: 13px; color: var(--text); line-height: 1.5; white-space: pre-wrap; }

/* ---------- Statut, dans la carte ouverte ---------- */
.dv2-carte-statut { margin-bottom: 10px; }

/* ---------- Liste de cartes candidature ----------
   Fermée, une carte ne porte que le poste et l'entreprise : c'est ce qui
   permet d'en balayer cinquante sans fatigue. Séparation par un filet, pas
   par une ombre par carte (cinquante ombres empilées font une bouillie). */
.dv2-liste {
  border-radius: var(--dv2-radius-md);
  overflow: hidden;
  background: var(--bg);
}
.dv2-carte {
  border-bottom: 1px solid var(--divider);
  /* Liseré de statut à gauche. Il DOUBLE la pastille écrite en toutes
     lettres, il ne la remplace pas : quelqu'un qui ne distingue pas le rouge
     du vert lit "En retard" dans la pastille et ne perd aucune information.
     La couleur n'est qu'un accélérateur, pour tout le monde. */
  border-left: 4px solid transparent;
  transition: background-color var(--dv2-dur) var(--dv2-ease-out);
}
.dv2-bord-todo      { border-left-color: var(--metal); }
.dv2-bord-sent      { border-left-color: var(--blue); }
.dv2-bord-followup  { border-left-color: var(--alerte); }
.dv2-bord-interview { border-left-color: var(--entretien); }
.dv2-bord-signed    { border-left-color: var(--orange); }
.dv2-bord-refused   { border-left-color: var(--refus); }
.dv2-bord-closed    { border-left-color: var(--muted-doux); }
.dv2-liste .dv2-carte:last-child { border-bottom: none; }
@media (hover: hover) and (pointer: fine) {
  .dv2-carte:hover { background: var(--card); }
}
.dv2-carte.ouvert { background: var(--card); }

.dv2-carte-tete {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-right: 8px;
}
/* Le titre est un vrai bouton : zone de clic pleine largeur, accessible au
   clavier sans tabindex ni gestion manuelle d'Entrée/Espace. */
.dv2-carte-toggle {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  text-align: left;
  background: none;
  border: none;
  padding: 13px 4px 13px 14px;
  cursor: pointer;
  font-family: inherit;
  color: inherit;
}
.dv2-carte-toggle:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: -2px;
  border-radius: var(--dv2-radius-sm);
}
.dv2-carte-identite { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dv2-carte-poste {
  font-family: var(--police-titre);
  font-weight: 600;
  font-size: 15px;
  line-height: 1.25;
  letter-spacing: -0.01em;
  color: var(--text);
  overflow-wrap: anywhere;
}
.dv2-carte-entreprise {
  font-size: 12.5px;
  color: var(--text-secondary);
  line-height: 1.3;
}

/* Aperçu (statut + prochaine étape) : visible carte fermée seulement, la
   carte ouverte montre déjà ces informations en détail plus bas. */
.dv2-carte-apercu { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dv2-carte.ouvert .dv2-carte-apercu { display: none; }
.status-pill-mini { padding: 3px 9px; font-size: 10.5px; }
.dv2-carte-prochaine { font-size: 11.5px; color: var(--text-secondary); }
.dv2-carte-prochaine.retard { color: var(--status-refused-text); font-weight: 600; }

/* Menu 3 points + bouton "Commentaires" (C3) : tous deux présents (ouverte
   ou fermée), mais discrets tant qu'on ne s'en approche pas. Sur tactile ils
   restent visibles en permanence, faute de survol. Même gabarit pour les
   deux : deux actions de même poids, à côté l'une de l'autre. */
.dv2-carte-plus,
.dv2-carte-commentaires {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 8px;
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background-color var(--dv2-dur) var(--dv2-ease-out),
              color var(--dv2-dur) var(--dv2-ease-out),
              opacity var(--dv2-dur) var(--dv2-ease-out),
              transform 140ms var(--dv2-ease-out);
}
.dv2-carte-plus svg { width: 16px; height: 16px; fill: currentColor; }
.dv2-carte-commentaires svg { width: 16px; height: 16px; }
.dv2-carte-plus:active,
.dv2-carte-commentaires:active { transform: scale(0.92); }
.dv2-carte-plus:focus-visible,
.dv2-carte-commentaires:focus-visible { outline: 2px solid var(--green); outline-offset: 1px; }
@media (hover: hover) and (pointer: fine) {
  .dv2-carte-plus,
  .dv2-carte-commentaires { opacity: 0; }
  .dv2-carte:hover .dv2-carte-plus,
  .dv2-carte:hover .dv2-carte-commentaires,
  .dv2-carte.ouvert .dv2-carte-plus,
  .dv2-carte.ouvert .dv2-carte-commentaires,
  .dv2-carte-plus:focus-visible,
  .dv2-carte-commentaires:focus-visible,
  .dv2-carte-plus[aria-expanded="true"] { opacity: 1; }
  .dv2-carte-plus:hover,
  .dv2-carte-commentaires:hover { background: var(--track-bg); color: var(--text); }
}

.dv2-menu-carte {
  position: absolute;
  z-index: 120;
  min-width: 176px;
  background: var(--card);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(16, 24, 40, 0.16);
  padding: 5px;
  /* Sort du bouton, pas du centre : l'origine est en haut à droite, là où
     le bouton se trouve. */
  transform-origin: top right;
  transform: scale(0.95);
  opacity: 0;
  transition: transform 150ms var(--dv2-ease-out), opacity 150ms var(--dv2-ease-out);
}
.dv2-menu-carte.ouvert { transform: scale(1); opacity: 1; }
.dv2-menu-carte-item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-radius: 7px;
  padding: 8px 10px;
  font-family: var(--police-texte);
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
}
.dv2-menu-carte-item:hover { background: var(--bg); }
.dv2-menu-carte-item:focus-visible { outline: 2px solid var(--green); outline-offset: -2px; }
/* Supprimer, détaché du reste : un filet marque la frontière entre les
   actions courantes et l'action définitive. */
.dv2-menu-carte-danger {
  color: var(--status-refused-text);
  border-top: 1px solid var(--divider);
  border-radius: 0 0 7px 7px;
  margin-top: 5px;
  padding-top: 9px;
}
.dv2-menu-carte-danger:hover { background: var(--status-refused-bg); }
/* Le liseré de focus reprend la couleur de l'action : un contour vert
   autour d'un "Supprimer" envoie le signal inverse de ce qu'il fait. */
.dv2-menu-carte-danger:focus-visible { outline-color: var(--status-refused-text); }

/* ---------- Groupement du menu de statut (B2) ----------
   .menu-statut/.menu-statut-item viennent de styles-index.css (partagé avec
   index.html, non modifié) : ces deux classes n'ajoutent QUE le
   regroupement propre à ce dashboard, en plus des classes existantes,
   jamais à leur place. Le séparateur "Clos" et le grisé des statuts clos
   permettent de distinguer d'un coup d'oeil ce qui bouge encore de ce qui
   est terminé, sans dupliquer le menu en deux listes séparées. */
.menu-statut-separateur {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text-secondary);
  padding: 8px 10px 4px;
  margin-top: 2px;
  border-top: 1px solid var(--divider);
}
.menu-statut-item-clos { color: var(--text-secondary); }
.menu-statut-item-clos.actif { color: var(--text); }

.dv2-supprimer-avert {
  font-size: 12.5px;
  color: var(--status-refused-text);
  margin: -10px 0 20px;
}

/* Ouverture fluide sans hauteur figée (donc pas de contenu coupé, même
   avec plusieurs interlocuteurs) : truc CSS "grid-template-rows 0fr -> 1fr",
   qui anime une hauteur "auto" sans JS ni max-height arbitraire. */
.dv2-carte-corps {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows var(--dv2-dur) var(--dv2-ease-out),
              opacity var(--dv2-dur) var(--dv2-ease-out);
}
.dv2-carte.ouvert .dv2-carte-corps { grid-template-rows: 1fr; opacity: 1; }
.dv2-carte-corps-inner {
  overflow: hidden;
  min-height: 0;
  padding: 0 14px;
  font-size: 12.5px;
}
.dv2-carte.ouvert .dv2-carte-corps-inner { padding: 2px 14px 16px; }
.dv2-carte-section { margin-top: 16px; }

/* Récapitulatif : fait -> à faire, lu de gauche à droite comme une
   progression, pas comme deux blocs indépendants. */
.dv2-recap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  background: var(--bg);
  border-radius: 10px;
  padding: 11px 13px;
}
.dv2-carte.ouvert .dv2-recap { background: var(--bg); }
.dv2-recap-bloc { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.dv2-recap-valeur { font-size: 12.5px; font-weight: 500; line-height: 1.35; text-wrap: pretty; }
.dv2-recap-valeur.retard { color: var(--status-refused-text); font-weight: 600; }
.dv2-recap-valeur.aujourdhui { color: var(--status-followup-text); font-weight: 600; }
.dv2-recap-fleche { color: var(--text-secondary); font-size: 15px; }

/* ---------- Motif de clôture (B1) ----------
   Réutilise très largement les classes de la promesse de réponse (même
   forme : lien discret -> saisie -> état enregistré + "Retirer") : les deux
   sont des compléments optionnels d'un statut, la cohérence visuelle compte
   plus que l'indépendance des styles. Seule différence : sa couleur active
   reste neutre (--bg), un motif de clôture n'est pas une alerte comme une
   promesse en attente. */
.dv2-motif { margin-bottom: 10px; }
.dv2-motif.dv2-promesse-active { background: var(--bg); }
.dv2-motif .dv2-promesse-texte { color: var(--text); }
.dv2-motif .dv2-promesse-retirer { border-color: var(--divider); color: var(--text-secondary); }

/* ---------- Promesse de réponse ----------
   Au repos c'est un lien discret sous le récap ; une fois la promesse posée,
   le bloc prend la couleur "en attente" de la charte, parce que l'état de la
   candidature a réellement changé (le protocole est suspendu). */
.dv2-promesse { margin-top: 10px; }
.dv2-promesse-ouvrir {
  background: none;
  border: none;
  padding: 2px 0;
  font-family: var(--police-texte);
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  cursor: pointer;
  transition: color var(--dv2-dur) var(--dv2-ease-out);
}
.dv2-promesse-ouvrir:hover { color: var(--green); }
.dv2-promesse-ouvrir:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; border-radius: 4px; }
.dv2-promesse-saisie { margin-top: 7px; }
.dv2-promesse-saisie label { display: block; font-size: 11px; color: var(--text-secondary); margin-bottom: 3px; }
.dv2-promesse-ligne { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.dv2-promesse-ligne input[type="date"] {
  padding: 6px 8px;
  border: 1px solid var(--divider);
  border-radius: 7px;
  font-family: var(--police-texte);
  font-size: 12px;
  background: var(--card);
  color: var(--text);
}
.dv2-promesse-active {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--status-followup-bg);
  border-radius: 10px;
  padding: 9px 12px;
}
.dv2-promesse-texte { font-size: 12.5px; font-weight: 600; color: var(--status-followup-text); }
.dv2-promesse-sous { display: block; font-size: 11.5px; font-weight: 400; }
.dv2-promesse-retirer {
  flex: 0 0 auto;
  background: none;
  border: 1px solid var(--status-followup-text);
  color: var(--status-followup-text);
  border-radius: 7px;
  padding: 4px 10px;
  font-family: var(--police-texte);
  font-size: 11.5px;
  font-weight: 600;
  cursor: pointer;
  transition: transform 140ms var(--dv2-ease-out);
}
.dv2-promesse-retirer:active { transform: scale(0.96); }

/* La source reconnue s'affiche sous le champ lien : elle a besoin d'air en
   dessous, sinon elle se colle au label de la ligne suivante. */
#dv2ColletSource { margin: 4px 0 2px; min-height: 15px; }

.dv2-detail-section { min-width: 0; }
.dv2-detail-titre {
  font-family: var(--police-titre);
  font-size: 12.5px;
  font-weight: 600;
  margin: 0 0 8px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-secondary);
}
/* :focus-visible et non :focus, l'ouverture d'une carte déplace le focus
   ici par programme, et un cadre vert autour du titre à chaque ouverture
   ressemblerait à un champ de saisie. Le clavier, lui, garde son repère. */
.dv2-detail-titre:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; border-radius: 2px; }
.dv2-detail-label { font-size: 11px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--text-secondary); margin-bottom: 3px; }

/* ---------- Colonne droite : calendrier + tâches ---------- */
.dv2-col-side > * + * { margin-top: var(--dv2-gap-md); }
.dv2-calendrier-carte {
  background: var(--bg);
  border-radius: var(--dv2-radius-md);
  padding: 16px;
}
.dv2-taches-carte {
  background: var(--bg);
  border-radius: var(--dv2-radius-md);
  padding: 16px;
}
.dv2-taches-carte h3 {
  font-family: var(--police-titre);
  font-size: 14px;
  font-weight: 600;
  margin: 0 0 10px;
}
.dv2-tache {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid var(--divider);
  transition: opacity var(--dv2-dur) var(--dv2-ease);
}
.dv2-tache:last-child { border-bottom: none; }
.dv2-tache input[type="checkbox"] {
  margin-top: 2px;
  width: 16px; height: 16px;
  accent-color: var(--green);
  cursor: pointer;
  flex-shrink: 0;
}
.dv2-tache-corps { min-width: 0; }
/* Le titre est un vrai bouton (ouvre le détail C2), plus une portion de
   <label> qui cochait la case au passage : la zone de clic checkbox et la
   zone de clic "voir le détail" ne doivent jamais se marcher dessus. */
.dv2-tache-titre-btn {
  background: none;
  border: none;
  padding: 0;
  font-family: var(--police-texte);
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}
.dv2-tache-titre-btn:hover { color: var(--green); text-decoration: underline; }
.dv2-tache-titre-btn:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; border-radius: 3px; }
.dv2-tache-meta { font-size: 11.5px; color: var(--text-secondary); }
.dv2-tache-meta.retard { color: var(--status-refused-text); font-weight: 600; }
.dv2-tache-vide { font-size: 13px; color: var(--text-secondary); }

/* Tâche faite aujourd'hui (C1) : reste affichée, grisée, jusqu'à minuit ,
   jamais retirée d'un coup, contrairement au comportement audité. */
.dv2-tache-faite { opacity: 0.55; }
.dv2-tache-faite .dv2-tache-titre-btn { color: var(--text-secondary); text-decoration: line-through; }
.dv2-tache-faite .dv2-tache-titre-btn:hover { color: var(--green); text-decoration: line-through; }
.dv2-tache-faite input[type="checkbox"] { cursor: default; }

/* ---------- États : skeleton, erreur, vide ---------- */
.dv2-skeleton { border-radius: var(--dv2-radius-md); background: var(--bg); position: relative; overflow: hidden; }
.dv2-skeleton::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.55), transparent);
  animation: dv2-shimmer 1.3s infinite;
}
@media (prefers-reduced-motion: reduce) { .dv2-skeleton::after { animation: none; } }
@keyframes dv2-shimmer { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

.dv2-erreur {
  background: var(--status-refused-bg);
  color: var(--status-refused-text);
  border-radius: var(--dv2-radius-md);
  padding: 16px;
  font-size: 13.5px;
}
.dv2-erreur button {
  margin-left: 10px;
  background: none;
  border: 1px solid var(--status-refused-text);
  color: var(--status-refused-text);
  border-radius: 8px;
  padding: 5px 12px;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}

@media (max-width: 640px) {
  .dv2-coller-grille,
  .dv2-form-bloc .dv2-coller-grille,
  .dv2-form-bloc:first-of-type .dv2-coller-grille { grid-template-columns: 1fr; }
  .dv2-renommer-champs { grid-template-columns: 1fr; }
  /* Le récap passe en pile : la flèche horizontale n'a plus de sens, elle
     est masquée plutôt que pivotée (une flèche vers le bas entre deux blocs
     empilés n'apporte rien que l'ordre de lecture ne dise déjà). */
  .dv2-recap { grid-template-columns: 1fr; gap: 10px; }
  .dv2-recap-fleche { display: none; }
}

/* ---------- "Comment ça marche ?" (visite en 4 étapes) ---------- */
.dv2-visite-box { max-width: 340px; }
.dv2-visite-badge {
  width: 44px;
  height: 44px;
  margin: 0 auto 16px;
  border-radius: 50%;
  background: var(--accent-doux);
  color: var(--accent);
  font-family: var(--police-titre);
  font-weight: 600;
  font-size: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.dv2-visite-points {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin: 4px 0 22px;
}
.dv2-visite-point {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--divider);
}
.dv2-visite-point.actif { background: var(--green); }
.dv2-visite-actions { flex-direction: row; }
.dv2-visite-actions .btn { flex: 1; }

/* ---------- Blocs repliables dans la carte ouverte (etape 5) ----------
   Ouvrir une carte deversait auparavant statut, recap, interlocuteurs ET
   historique d'un seul bloc. Desormais l'essentiel reste visible et les deux
   sections secondaires attendent d'etre demandees. <details> natif : l'etat,
   le clavier et les lecteurs d'ecran sont geres par le navigateur. */
.dv2-bloc {
  margin-top: var(--esp-2);
  background: var(--card);
  border: 1px solid var(--divider);
  border-radius: var(--dv2-radius-sm);
}
.dv2-bloc-tete {
  display: flex;
  align-items: center;
  gap: var(--esp-1);
  padding: 11px 14px;
  cursor: pointer;
  list-style: none;
  border-radius: var(--dv2-radius-sm);
  transition: background-color var(--dv2-dur) var(--dv2-ease-out);
}
/* Le triangle par defaut de <summary> ne suit ni la charte ni la taille du
   texte : remplace par un chevron dessine, qui pivote a l'ouverture. */
.dv2-bloc-tete::-webkit-details-marker { display: none; }
.dv2-bloc-tete::after {
  content: "";
  margin-left: auto;
  width: 7px;
  height: 7px;
  border-right: 1.5px solid var(--text-secondary);
  border-bottom: 1.5px solid var(--text-secondary);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--dv2-dur) var(--dv2-ease-out);
}
.dv2-bloc[open] > .dv2-bloc-tete::after { transform: rotate(-135deg) translate(-2px, -2px); }
@media (hover: hover) and (pointer: fine) {
  .dv2-bloc-tete:hover { background: var(--survol); }
}
.dv2-bloc-tete:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.dv2-bloc-titre {
  font-family: var(--police-titre);
  font-weight: 600;
  font-size: 13.5px;
  color: var(--text);
}
.dv2-bloc-compte {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-secondary);
  background: var(--track-bg);
  border-radius: 999px;
  padding: 1px 8px;
  font-variant-numeric: tabular-nums;
}
.dv2-bloc-corps {
  padding: 0 14px 14px;
  animation: apparition var(--dur) var(--ease-out) both;
}

/* ---------- Zones de texte libre ----------
   Notes d'interlocuteur et commentaires : ce sont des endroits ou on ecrit
   une phrase, pas des champs de formulaire administratif. Meme taille de
   texte que le reste, hauteur qui suit le contenu, cadre discret au repos. */
.dv2-contact-notes,
.dv2-commentaire-formulaire textarea {
  font-size: 14px;
  line-height: 1.6;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
}
.dv2-commentaire-formulaire textarea { min-height: 76px; }
.dv2-contact-notes:focus,
.dv2-commentaire-formulaire textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--ombre-focus);
}

/* ---------- Carte candidature : plus d'air ---------- */
.dv2-carte.ouvert .dv2-carte-corps-inner { padding: 2px 14px var(--esp-2); }

/* La coque n'a plus de flou translucide (DA calme) : sans bordure, elle se
   confondait avec le fond de page. */
.dv2-shell { border: 1px solid var(--divider); }

/* ---------- Actions sur l'offre d'origine (carte ouverte) ----------
   L'annonce en ligne fait toujours foi : elle est a jour, et elle peut avoir
   ete retiree. Le bouton qui y renvoie est donc le principal, le texte
   enregistre n'est qu'un appui. */
.dv2-actions-offre { display: flex; flex-wrap: wrap; gap: var(--esp-1); margin-bottom: 12px; }
.dv2-action-offre {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--police-texte);
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: none;
  border: 1px solid var(--divider);
  border-radius: var(--radius-sm);
  padding: 7px 12px;
  background: var(--card);
  color: var(--text);
  cursor: pointer;
  transition: background-color var(--dv2-dur) var(--dv2-ease-out),
              border-color var(--dv2-dur) var(--dv2-ease-out);
}
.dv2-action-offre svg { width: 14px; height: 14px; flex: 0 0 auto; }
.dv2-action-principale { background: var(--accent-doux); border-color: var(--accent-bordure); color: var(--accent-fonce); }
@media (hover: hover) and (pointer: fine) {
  .dv2-action-principale:hover { background: var(--accent); border-color: var(--accent); color: #FFFFFF; }
  .dv2-action-resume:hover { background: var(--survol); border-color: #D1D5DB; }
}
.dv2-action-offre:active { transform: translateY(1px); }

/* ---------- Modale "Resume de l'offre" ---------- */
.dv2-resume-box { max-width: 680px; text-align: left; }
.dv2-resume-source { margin: -12px 0 var(--esp-2); font-size: 13px; color: var(--text-secondary); }
.dv2-resume-texte {
  max-height: 46vh;
  overflow-y: auto;
  background: var(--bg);
  border: 1px solid var(--divider);
  border-radius: var(--radius-sm);
  padding: var(--esp-2);
  font-size: 14px;
  line-height: 1.65;
  color: var(--text);
  /* Le texte capte garde ses sauts de ligne : c'est ce qui le rend lisible. */
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
.dv2-resume-pied { display: flex; flex-wrap: wrap; gap: var(--esp-1); margin-top: var(--esp-2); }
.dv2-resume-mention {
  margin: var(--esp-2) 0 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--text-secondary);
}

/* .btn-secondaire herite d'une largeur pleine et .btn d'un soulignement
   quand c'est un lien : les deux boutons du pied de modale se remettent
   d'aplomb ici. */
.dv2-resume-pied .btn { width: auto; flex: 0 0 auto; text-decoration: none; }

/* ==========================================================================
   Pagination : six candidatures par page
   ==========================================================================
   Une liste de quarante lignes est un mur : on scrolle, on perd sa place, et
   la colonne de droite se retrouve seule en haut d'une colonne de deux
   mètres. Six par page tient dans un écran sans scroller.

   Le compte en toutes lettres ("Candidatures 1 à 6 sur 23") vient AVANT les
   numéros : on sait où on en est avant de savoir où aller. */
.dv2-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--esp-2);
  margin-top: var(--esp-3);
  padding-top: var(--esp-2);
  border-top: 1px solid var(--line);
}
.dv2-pagination-compte {
  margin: 0;
  font-size: var(--t-interface);
  color: var(--muted-doux);
}
.dv2-pagination-boutons {
  display: flex;
  align-items: center;
  gap: var(--esp-0-5);
  flex-wrap: wrap;
}

.dv2-page-num,
.dv2-page-fleche {
  min-width: 34px;
  height: 34px;
  padding: 0 var(--esp-1);
  border: 1px solid var(--line);
  border-radius: var(--r-champ);
  background: var(--surface);
  color: var(--muted);
  font-family: var(--police);
  font-size: var(--t-interface);
  font-weight: var(--graisse-moyen);
  cursor: pointer;
  transition: background var(--dur-court) var(--ease-sortie),
              color var(--dur-court) var(--ease-sortie),
              border-color var(--dur-court) var(--ease-sortie);
}
.dv2-page-num { font-family: var(--police-chiffres); }

.dv2-page-num:hover:not(.courante),
.dv2-page-fleche:hover:not([disabled]) {
  background: var(--surface-survol);
  border-color: var(--metal);
  color: var(--ink);
}
.dv2-page-num:focus-visible,
.dv2-page-fleche:focus-visible {
  outline: none;
  box-shadow: var(--focus-anneau);
}

/* La page courante est un aplat bleu plein : c'est le seul repère qui compte
   dans une rangée de chiffres tous pareils. */
.dv2-page-num.courante {
  background: var(--blue);
  border-color: var(--blue);
  color: var(--sur-bleu);
  cursor: default;
}

.dv2-page-fleche[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
}

.dv2-page-trou {
  padding: 0 var(--esp-0-5);
  color: var(--muted-doux);
  font-size: var(--t-interface);
}

@media (max-width: 620px) {
  /* Sur téléphone, "Précédent / Suivant" suffit : dix numéros de 34 px ne
     tiennent pas sur 375 px de large sans se marcher dessus. */
  .dv2-pagination { justify-content: center; }
  .dv2-page-num:not(.courante) { display: none; }
}

/* --------------------------------------------------------------------------
   Utilitaires nés du passage de la CSP en mode bloquant
   --------------------------------------------------------------------------
   Une CSP stricte refuse les attributs style="..." écrits dans le HTML. Les
   cinq qui restaient dans index.html sont devenus ces classes. Rien de neuf
   visuellement : ce sont exactement les mêmes déclarations, déplacées.
   L'état caché reste surchargeable par le JavaScript, qui continue d'écrire
   element.style.display = 'block' (une propriété posée par script n'est pas
   concernée par la CSP, et une valeur en ligne l'emporte sur une classe).
   -------------------------------------------------------------------------- */
.dv2-cache { display: none; }
.dv2-largeur-auto { width: auto; }
.dv2-coller-erreur { color: var(--status-refused-text); }

/* Les trois tailles des blocs gris d'attente. Elles étaient écrites en
   attribut style= dans le JavaScript qui les injecte, ce qu'une CSP stricte
   refuse. Mêmes valeurs, simplement nommées. */
.dv2-skeleton-carte { height: 104px; border-radius: var(--r-carte); }
.dv2-skeleton-liste { height: 220px; }
.dv2-skeleton-taches { height: 80px; }
