/* =====================================================================
   Vigie Privée · Espace client

   Reprend strictement les variables de la landing : mêmes couleurs,
   mêmes familles typographiques, même vocabulaire visuel. Un client
   qui passe de la page publique à son espace ne doit pas avoir
   l'impression de changer de site.
   ===================================================================== */


/* La page occupe toute la hauteur : le pied de page reste en bas même
   sur un contenu court. Le reste de body vit dans base.css. */
body.vp-app{display:flex;flex-direction:column;min-height:100vh}



.vp-nav{display:flex;align-items:center;gap:20px;flex-wrap:wrap}
.vp-nav a {
  position: relative;
  color: #b8ccdf;
  font-size: .9rem;
  font-weight: 600;
  white-space: nowrap;
  padding: 6px 0;
}

.vp-nav a:hover {
  color: #fff;
  text-decoration: none
}

.vp-nav a.is-active {
  color: #fff
}

.vp-nav a.is-active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 2px;
  background: var(--faisceau);
  border-radius: 1px;
}
.vp-nav-form{margin:0}

/* Bandeau d'environnement : le garde-fou qui évite de croire
   qu'on regarde la production. */
/* Pastille d'environnement.
   Fixe en bas à droite plutôt qu'en bandeau : le garde-fou doit
   rester visible en permanence sans manger la page ni détourner
   l'attention du contenu. */
.vp-env-tag {
  position: fixed;
  left: 16px;
  bottom: 16px;
  z-index: 900;
  display: flex;
  align-items: center;
  gap: 7px;
  background: var(--ambre);
  color: #fff;
  border-radius: 999px;
  padding: 6px 13px 6px 10px;
  font-family: 'IBM Plex Mono', monospace;
  font-size: .66rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  box-shadow: 0 4px 14px rgba(8, 26, 46, .25);
  opacity: .85;
  transition: opacity .15s;
  pointer-events: none;
}

.vp-env-tag:hover {
  opacity: 1
}

.vp-env-tag-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #fff;
  opacity: .9;
}

/* ---------- Corps ---------- */

.vp-main {
  flex: 1;
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 36px 22px 56px
}

/* Une page pleine largeur déborde la gouttière commune. */
body.vp-app:has(.vp-panel-full) .vp-main {
  max-width: 1320px
}

.vp-panel{
  background:var(--blanc);border:1px solid var(--ligne);border-radius:var(--r);
  padding:32px 34px;max-width:560px;margin:0 auto;box-shadow:var(--shadow);
}

.vp-panel-wide {
  max-width: 880px
}

/* Le tableau de bord n'est pas un formulaire : il porte des grilles,
   des listes de domaines et bientôt une timeline. Il occupe donc
   toute la largeur disponible, sans cadre, contrairement aux pages
   de saisie qui restent centrées et resserrées. */
.vp-panel-full {
  max-width: none;
  width: 100%;
  background: transparent;
  border: 0;
  box-shadow: none;
  padding: 0;
}
.vp-panel-error{text-align:center;max-width:480px}

.vp-error-code{
  font-family:'IBM Plex Mono',monospace;font-size:3rem;font-weight:600;
  color:var(--acier);margin:0 0 6px;line-height:1;
}

.vp-title{font-size:1.6rem;font-weight:800;margin:0 0 8px;color:var(--nuit)}
.vp-subtitle{color:var(--gris);margin:0 0 28px;font-size:.98rem}

/* ---------- Formulaires ---------- */

.vp-form-inline .vp-link-button:hover{color:var(--acier)}

/* ---------- Boutons ---------- */

/* ---------- Choix du forfait ---------- */

.vp-plan-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:12px}

.vp-plan-card{
  position:relative;display:flex;flex-direction:column;gap:5px;
  border:1.5px solid var(--ligne);border-radius:10px;padding:16px 18px;
  cursor:pointer;background:var(--blanc);
  transition:border-color .15s, box-shadow .15s;
}
.vp-plan-card:hover{border-color:var(--acier)}
.vp-plan-card input{position:absolute;opacity:0;pointer-events:none}

.vp-plan-card.is-selected{
  border-color:var(--nuit);
  box-shadow:0 0 0 3px rgba(8,26,46,.08);
}

.vp-plan-name{font-family:'Archivo',sans-serif;font-weight:800;font-size:1rem;color:var(--nuit)}
.vp-plan-price{font-family:'Archivo',sans-serif;font-weight:800;font-size:1.5rem;color:var(--nuit);line-height:1.1}
.vp-plan-price small{font-family:'Inter',sans-serif;font-weight:400;font-size:.72rem;color:var(--gris)}
.vp-plan-terms{color:var(--gris);font-size:.79rem;line-height:1.55;margin-top:4px}

/* ---------- Tableau de bord ---------- */

/* Dans un module, la grille occupe la hauteur offerte : les compteurs
   se répartissent au lieu de s'empiler contre le haut.
   Les paddings sont resserrés de quelques pixels : le pas de la
   grille est de 24 px, on ne peut pas ajuster plus finement par la
   hauteur du module. */
.vp-module .vp-stat-grid{height:100%;align-content:center}
.vp-module .vp-stat{padding:14px 16px}
.vp-module .vp-stat-jetons{margin-top:4px}

.vp-stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px}

.vp-stat {
  background: var(--blanc);
  border: 1px solid var(--ligne);
  border-left: 3px solid var(--acier);
  border-radius: 0 10px 10px 0;
  padding: 20px 22px;
  box-shadow: var(--shadow);
}

.vp-stat-label{
  display:block;font-family:'IBM Plex Mono',monospace;font-size:.66rem;
  text-transform:uppercase;letter-spacing:.12em;color:var(--acier);font-weight:600;
}
.vp-stat-value{
  display:block;font-family:'Archivo',sans-serif;font-weight:800;
  font-size:1.7rem;color:var(--nuit);margin-top:6px;letter-spacing:-.02em;
}
.vp-stat-note{display:block;font-size:.76rem;color:var(--gris-clair);margin-top:2px}

.vp-empty{text-align:center;padding:28px 0}
.vp-empty p{color:var(--gris);margin:0 0 8px}
.vp-empty .vp-button{margin-top:16px;width:auto}

/* ---------- Messages ---------- */

/* ---------- Adaptations ---------- */

/* ---------- Menu replié ---------- */

.vp-burger{
  display:none;
  flex-direction:column;justify-content:center;gap:5px;
  width:40px;height:36px;padding:0 8px;
  background:none;border:0;cursor:pointer;
  flex-shrink:0;
}

.vp-burger span{
  display:block;height:2px;width:100%;border-radius:1px;
  background:#b8ccdf;
  transition:transform .2s, opacity .2s;
}

/* Les trois barres se croisent quand le menu est ouvert : la même
   icône sert à fermer. */
.vp-burger[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.vp-burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.vp-burger[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
@media (max-width:640px){
  .vp-main{padding:24px 16px 40px}
  .vp-panel{padding:24px 20px}
  .vp-title{font-size:1.35rem}
  .vp-code-input{font-size:1.35rem !important;letter-spacing:.35em}
  .vp-header-inner{padding:8px 16px}
  .vp-brand img{height:32px}
  .vp-brand-baseline{display:none}
  /* Le menu se replie derrière une icône : quatre entrées sur une
     ligne de téléphone se compriment jusqu'à devenir illisibles. */
  .vp-burger{display:flex}

  /* L'en-tête se fixe sur mobile : avec le menu replié, il devient la
     seule barre de navigation. Sur bureau il reste statique — les
     liens y sont déjà visibles, et la hauteur est précieuse sur un
     tableau de bord. */
  .vp-header.vp-on-dark{
    position:sticky;top:0;z-index:50;
  }

  /* Le menu se pose par-dessus la page plutôt que de déplier
     l'en-tête : il surgit, il ne pousse rien. */
  .vp-header-inner{position:relative}

  .vp-nav{
    display:none;
    position:absolute;
    top:calc(100% + 8px);
    right:14px;
    min-width:220px;
    flex-direction:column;
    align-items:stretch;
    gap:0;
    margin:0;
    padding:6px;
    background:var(--ardoise);
    border:1px solid rgba(255,255,255,.12);
    border-radius:12px;
    box-shadow:0 12px 32px rgba(8,26,46,.45);
    z-index:60;
  }
  .vp-nav.is-ouvert{display:flex}

  .vp-nav a,.vp-nav .vp-nav-form{
    padding:12px 14px;
    border-radius:8px;
  }
  .vp-nav a{border-bottom:1px solid rgba(255,255,255,.06)}
  .vp-nav a:last-of-type{border-bottom:0}

  .vp-nav a,.vp-nav .vp-link-button{font-size:.9rem}

  /* Le soulignement de l'entrée active n'a plus de sens en colonne :
     un fond marqué se lit mieux. */
  .vp-nav a.is-active::after{display:none}
  .vp-nav a.is-active{
    background:rgba(255,255,255,.08);
    color:#fff;
  }

  .vp-nav-form{
    border-top:1px solid rgba(255,255,255,.1);
    margin-top:4px;padding-top:12px;
  }
  .vp-nav .vp-link-button{padding:0;text-align:left}
  .vp-actions .vp-button{width:100%}
}

@media (prefers-reduced-motion: reduce){
  *{animation:none !important;transition:none !important}
}


/* ---------- Encart d'appel à l'action ---------- */

.vp-callout {
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
  background: var(--faisceau-pale);
  border: 1px solid #b9dcf2;
  border-left: 4px solid var(--acier);
  border-radius: 0 10px 10px 0;
  padding: 20px 24px;
  margin: 0 0 28px;
}

.vp-callout-body {
  flex: 1;
  min-width: 260px
}

.vp-callout-title {
  font-size: 1.05rem;
  font-weight: 800;
  color: var(--nuit);
  margin: 0 0 6px
}

.vp-callout p {
  margin: 0;
  font-size: .9rem;
  color: var(--gris);
  line-height: 1.55
}

.vp-callout .vp-button {
  width: auto;
  flex-shrink: 0
}

/* ---------- Compteurs neutralisés tant qu'aucun forfait n'est actif ---------- */

.vp-stat-grid-muted .vp-stat {
  border-left-color: var(--ligne);
  opacity: .65
}

.vp-stat-grid-muted .vp-stat-value {
  color: var(--gris-clair)
}

.vp-stat.is-full {
  border-left-color: var(--ambre);
  background: var(--ambre-bg)
}

.vp-stat-note-alert {
  color: var(--ambre);
  font-weight: 600
}

/* ---------- Sélecteur de nombre de sites ---------- */

.vp-sitepicker {
  background: var(--brume);
  border: 1px solid var(--ligne);
  border-radius: 10px;
  padding: 18px 20px;
  margin: 0 0 24px;
}

.vp-sitepicker label {
  display: block;
  font-size: .88rem;
  font-weight: 600;
  margin-bottom: 10px
}

.vp-sitepicker-row {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap
}

.vp-sitepicker input {
  width: 110px;
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  padding: 11px 14px;
  font: inherit;
  font-size: 1.1rem;
  font-weight: 700;
  text-align: center;
  background: var(--blanc);
  color: var(--nuit);
}

.vp-sitepicker input:focus {
  outline: none;
  border-color: var(--acier);
  box-shadow: 0 0 0 4px rgba(45, 106, 148, .14)
}

.vp-sitepicker-hint {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .76rem;
  color: var(--acier);
  line-height: 1.5;
}

/* ---------- Cartes de forfait dans l'espace client ---------- */

.vp-plan-grid-wide {
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 16px;
  align-items: stretch
}

.vp-plan-offer {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 6px;
  background: var(--blanc);
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  padding: 20px 20px 18px;
  transition: border-color .15s, box-shadow .15s;
}

.vp-plan-offer.is-fit {
  border-color: var(--acier);
  box-shadow: 0 0 0 3px rgba(45, 106, 148, .1)
}

/* Le forfait en cours n'est pas une offre : il est neutralisé
   visuellement pour que l'œil aille aux cartes actionnables. */
.vp-plan-offer.is-current {
  border-color: var(--vert-ligne);
  background: var(--vert-bg);
  box-shadow: none;
}

.vp-plan-offer.is-current .vp-plan-price {
  color: var(--vert)
}

.vp-plan-offer.is-current .vp-plan-name {
  color: #155e3a
}

.vp-plan-badge {
  position: absolute;
  top: -10px;
  left: 16px;
  font-family: 'IBM Plex Mono', monospace;
  font-size: .6rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  background: var(--vert);
  color: #fff;
  border-radius: 3px;
  padding: 4px 9px;
}

.vp-plan-badge-fit {
  background: var(--acier);
  opacity: 0;
  transition: opacity .18s
}

.vp-plan-offer.is-fit .vp-plan-badge-fit {
  opacity: 1
}

.vp-plan-scope {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .72rem;
  color: var(--gris-clair);
  letter-spacing: .04em
}

.vp-plan-offer .vp-plan-terms {
  list-style: none;
  margin: 12px 0 16px;
  padding: 12px 0 0;
  border-top: 1px solid var(--ligne);
  display: grid;
  gap: 6px
}

.vp-plan-offer .vp-plan-terms li {
  font-size: .8rem;
  color: var(--gris);
  line-height: 1.45
}

.vp-plan-offer .vp-plan-terms li.is-plus {
  color: var(--encre);
  font-weight: 600
}

.vp-plan-offer .vp-plan-terms li.is-plus::before {
  content: "+ ";
  color: var(--ambre);
  font-weight: 700
}

.vp-plan-offer .vp-form {
  margin-top: auto
}

.vp-plan-offer .vp-button {
  width: 100%
}

.vp-plan-state {
  margin-top: auto;
  font-size: .78rem;
  color: var(--gris-clair);
  line-height: 1.5;
  padding-top: 4px;
}

.vp-plan-state-blocked {
  color: var(--ambre);
  background: var(--ambre-bg);
  border: 1px solid var(--ambre-ligne);
  border-radius: 6px;
  padding: 9px 11px;
}

/* ---------- Listes de définition ---------- */

.vp-fieldset-legend {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--acier);
  padding: 0 0 10px;
  border-bottom: 1px solid var(--ligne);
  margin-bottom: 18px;
}

.vp-deflist {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 8px 24px;
  margin: 0
}

/* Le terme s'aligne comme sa définition : sans cela, un dd qui
   contient un bouton se centre alors que le dt reste en haut. */
.vp-deflist dt{
  display:flex;align-items:center;
  font-size:.82rem;color:var(--gris-clair);font-weight:600;
  min-height:32px;
}

.vp-deflist dd {
  margin: 0;
  font-size: .92rem;
  color: var(--encre);
  font-weight: 600
}

@media (max-width:520px) {
  .vp-deflist {
    grid-template-columns: 1fr;
    gap: 2px 0
  }

  .vp-deflist dd {
    margin-bottom: 12px
  }

  .vp-callout .vp-button {
    width: 100%
  }
}
.vp-plan-current {
  margin-top: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  background: var(--vert);
  color: #fff;
  border-radius: 10px;
  padding: 12px 18px;
  font-family: 'Archivo', sans-serif;
  font-weight: 700;
  font-size: .92rem;
}

.vp-plan-current-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: rgba(255, 255, 255, .22);
  font-size: .72rem;
}

.vp-recap {
  border: 1px solid var(--ligne);
  border-radius: 10px;
  margin: 0 0 20px;
  overflow: hidden;
}

.vp-recap-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 18px;
  font-size: .92rem;
  color: var(--gris);
}

.vp-recap-row+.vp-recap-row {
  border-top: 1px solid var(--ligne)
}

.vp-recap-row strong {
  color: var(--encre);
  font-family: 'Archivo', sans-serif
}

.vp-recap-row-strong {
  background: var(--faisceau-pale)
}

.vp-recap-row-strong strong {
  font-size: 1.25rem;
  color: var(--nuit)
}



/* Modale alignée sur l'identité, Bootstrap ne devant pas imposer la sienne. */
/* ---------- Liste des domaines surveillés ---------- */

.vp-domaines-section {
  margin: 32px 0 0
}

.vp-domaines-titre {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .14em;
  color: var(--acier);
  padding: 0 0 10px;
  border-bottom: 1px solid var(--ligne);
  margin: 0 0 16px;
}

.vp-domaines {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 10px
}

.vp-domaine {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  background: var(--blanc);
  border: 1px solid var(--ligne);
  border-left: 3px solid var(--vert);
  border-radius: 0 10px 10px 0;
  padding: 16px 18px;
  box-shadow: var(--shadow);
}

.vp-domaine.is-pending {
  border-left-color: var(--ambre);
  background: var(--ambre-bg)
}
/* ---------- Domaine en cours d'analyse ----------
   Le balayage anime la bordure existante plutôt que d'ajouter un
   élément : la ligne garde exactement la même hauteur, rien ne saute
   quand l'analyse démarre ou s'achève. */

/* La carte entière change d'état, pas seulement sa bordure : un fond
   bleuté et un halo signalent qu'il se passe quelque chose, même
   quand le regard n'est pas sur la ligne. */
/* Violet : le seul ton absent de la palette. Il dit « en cours » sans
   se confondre avec un statut — le bleu sert partout, l'ambre à
   l'attente, le vert à l'acquis, le rouge à l'alerte. */
.vp-domaine.is-scanning {
  border-left-color: transparent;
  border-color: #d8cdf0;
  background: linear-gradient(100deg, #f6f2fd 0%, #fbf9ff 55%, var(--blanc) 100%);
  box-shadow: 0 2px 14px rgba(99, 66, 168, .12);
}

/* La bordure porte le niveau d'exposition, pas le statut : tous les
   domaines sont vérifiés, ça n'apprend rien. Le score, lui, est la
   seule information qui appelle une action. */
.vp-domaine.is-bon{border-left-color:var(--vert)}
.vp-domaine.is-moyen{border-left-color:var(--ambre);background:linear-gradient(90deg,var(--ambre-bg),var(--blanc) 55%)}
.vp-domaine.is-faible{border-left-color:var(--rouge);background:linear-gradient(90deg,var(--rouge-bg),var(--blanc) 55%)}

.vp-domaine-score.is-bon{color:var(--vert)}
.vp-domaine-score.is-moyen{color:var(--ambre)}
.vp-domaine-score.is-faible{color:var(--rouge)}
.vp-domaine-score small{opacity:.55}


.vp-domaine.is-scanning .vp-domaine-nom{color:#4a2f7a}
.vp-domaine.is-scanning .vp-domaine-score{color:#6342a8;opacity:.5}
.vp-domaine.is-scanning .vp-domaine-etat-encours{color:#6342a8}
.vp-domaine.is-scanning .vp-domaine-etat-encours::before{background:#6342a8}

/* Rail horizontal en pied de carte : la ligne balaie la largeur, ce
   qui laisse le regard suivre la progression au lieu de le contraindre
   à un mouvement vertical sur 3 pixels. */
.vp-domaine.is-scanning::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: #ece5f8;
}

.vp-domaine.is-scanning::after {
  content: "";
  position: absolute;
  bottom: 0;
  height: 2px;
  width: 32%;
  background: linear-gradient(90deg,
    transparent,
    rgba(99, 66, 168, .35) 20%,
    #6342a8 55%,
    #a084d8 80%,
    transparent);
  box-shadow: 0 0 8px rgba(99, 66, 168, .5);
  animation: vp-scan-sweep 2.1s cubic-bezier(.45, 0, .55, 1) infinite alternate;
}

@keyframes vp-scan-sweep {
  from { left: -6% }
  to   { left: 74% }
}

/* Le libellé pulse doucement, à contretemps du balayage : deux
   rythmes différents donnent une impression de travail en cours
   plutôt que de clignotement mécanique. */
.vp-domaine.is-scanning .vp-domaine-etat-encours {
  animation: vp-scan-pulse 2.6s ease-in-out infinite;
}

@keyframes vp-scan-pulse {

  0%,
  100% {
    opacity: 1
  }

  50% {
    opacity: .45
  }
}

/* Le point qui précède le libellé complète l'indication sans peser. */
.vp-domaine-etat-encours::before {
  content: "";
  display: inline-block;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--acier);
  margin-right: 7px;
  vertical-align: middle;
}

@media (prefers-reduced-motion: reduce) {
  .vp-domaine.is-scanning::after {
    animation: none;
    top: 33%
  }

  .vp-domaine.is-scanning .vp-domaine-etat-encours {
    animation: none
  }
}
.vp-domaine-main {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0
}

.vp-domaine-nom {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: 1rem;
  color: var(--nuit);
  word-break: break-all;
}

.vp-domaine-etat {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .7rem;
  letter-spacing: .05em;
  color: var(--gris-clair);
}

.vp-domaine-etat-attente {
  color: var(--ambre);
  font-weight: 600
}

.vp-domaine-etat-encours {
  color: var(--acier)
}

.vp-domaine-side {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-shrink: 0
}

.vp-domaine-score {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: 1.5rem;
  color: var(--nuit);
  line-height: 1;
}

.vp-domaine-score small {
  font-size: .7rem;
  font-weight: 400;
  color: var(--gris-clair)
}

.vp-button-small {
  padding: 8px 16px;
  font-size: .84rem;
  width: auto
}

.vp-domaine-retirer {
  background: none;
  border: 0;
  padding: 0 2px;
  cursor: pointer;
  color: var(--gris-clair);
  font-size: 1.4rem;
  line-height: 1;
  transition: color .15s;
}

.vp-domaine-retirer:hover {
  color: var(--rouge)
}

.vp-domaines-vide {
  text-align: center;
  padding: 32px 20px;
  background: var(--blanc);
  border: 1px dashed var(--ligne);
  border-radius: 10px;
}

.vp-domaines-vide p {
  margin: 0 0 4px;
  color: var(--gris)
}

@media (max-width:560px) {
  .vp-domaine {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px
  }

  .vp-domaine-side {
    width: 100%;
    justify-content: space-between
  }
}
/* ---------- Fil d'Ariane ---------- */

.vp-fil {
  font-size: .82rem;
  color: var(--gris-clair);
  margin: 0 0 16px
}

.vp-fil span {
  margin: 0 8px;
  opacity: .6
}

/* ---------- En-tête d'une analyse ---------- */

.vp-run-tete {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 28px;
  flex-wrap: wrap;
  margin: 0 0 28px;
}

.vp-run-scores-tete {
  display: flex;
  gap: 12px;
  flex-wrap: wrap
}

/* Le rapport prend la même forme que les blocs de score : il s'aligne
   sur eux plutôt que d'occuper une ligne à lui seul. */
.vp-run-pdf{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  min-width:96px;padding:16px 18px;
  background:var(--blanc);border:1.5px dashed var(--ligne);border-radius:10px;
  color:var(--gris);text-decoration:none;
  transition:border-color .15s, background .15s, color .15s;
}
.vp-run-pdf:hover{
  border-color:var(--rouge);background:var(--rouge-bg);
  color:var(--rouge);text-decoration:none;
}
.vp-run-pdf i{font-size:1.6rem;color:var(--rouge);margin-bottom:8px}
.vp-run-pdf span{
  font-family:'IBM Plex Mono',monospace;font-size:.64rem;font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;
}

.vp-score-bloc {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 104px;
  padding: 16px 20px;
  background: var(--blanc);
  border: 1px solid var(--ligne);
  border-radius: 10px;
}

.vp-score-bloc-principal {
  background: var(--nuit);
  border-color: var(--nuit)
}

.vp-score-bloc-principal .vp-score-n {
  color: #fff
}

.vp-score-bloc-principal .vp-score-l {
  color: var(--faisceau)
}

.vp-score-n {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: 2.3rem;
  color: var(--nuit);
  line-height: 1
}

.vp-score-l {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .64rem;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--gris-clair);
  margin-top: 6px;
}

.vp-score-delta {
  font-size: .68rem;
  margin-top: 6px;
  font-weight: 600;
  text-align: center
}

.vp-score-delta.is-up {
  color: #7fd6a2
}

.vp-score-delta.is-down {
  color: #ffb4ae
}

/* ---------- Répartition par gravité ---------- */

.vp-gravites {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
  margin: 0 0 32px
}

.vp-gravite {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 16px 18px;
  border-radius: 0 10px 10px 0;
  background: var(--blanc);
  border: 1px solid var(--ligne);
  border-left: 3px solid var(--gris-clair);
}

.vp-gravite-n {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: 1.7rem;
  line-height: 1;
  color: var(--nuit)
}

.vp-gravite-l {
  font-size: .78rem;
  color: var(--gris)
}

/* Échelle de gravité : couleurs injectées par run.php (var(--g-*)),
   source unique = citadelle-core SignalCatalog::PALETTE_GRAVITE.
   Les valeurs de repli reproduisent la palette du socle au cas où le
   bloc <style> ne serait pas rendu. */
.vp-gravite-critique {
  border-left-color: var(--g-critique, var(--rouge));
  background: var(--g-critique-bg, var(--rouge-bg))
}

.vp-gravite-critique .vp-gravite-n {
  color: var(--g-critique, var(--rouge))
}

.vp-gravite-eleve {
  border-left-color: var(--g-eleve, var(--orange));
  background: var(--g-eleve-bg, var(--orange-bg))
}

.vp-gravite-eleve .vp-gravite-n {
  color: var(--g-eleve, var(--orange))
}

.vp-gravite-modere {
  border-left-color: var(--g-modere, var(--ambre));
  background: var(--g-modere-bg, var(--ambre-bg))
}

.vp-gravite-modere .vp-gravite-n {
  color: var(--g-modere, var(--ambre))
}

.vp-gravite-ok {
  border-left-color: var(--g-conforme, var(--vert));
  background: var(--g-conforme-bg, var(--vert-bg))
}

.vp-gravite-ok .vp-gravite-n {
  color: var(--g-conforme, var(--vert))
}

/* Un compteur à zéro reste affiché mais s'efface : l'absence de
   constat critique est une information, pas un vide. */
.vp-gravite.is-zero {
  background: var(--blanc);
  border-left-color: var(--ligne);
  opacity: .55
}

.vp-gravite.is-zero .vp-gravite-n {
  color: var(--gris-clair)
}

/* ---------- Signaux ---------- */

.vp-section-titre {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: 1.25rem;
  color: var(--nuit);
  margin: 0 0 20px;
}

.vp-famille {
  margin: 0 0 26px
}

.vp-famille-titre {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: 'IBM Plex Mono', monospace;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--acier);
  padding: 0 0 10px;
  border-bottom: 1px solid var(--ligne);
  margin: 0 0 12px;
}

.vp-famille-compte {
  background: var(--acier);
  color: #fff;
  border-radius: 999px;
  padding: 2px 8px;
  font-size: .62rem;
  letter-spacing: 0;
}

.vp-signal {
  background: var(--blanc);
  border: 1px solid var(--ligne);
  border-left: 3px solid var(--gris-clair);
  border-radius: 0 10px 10px 0;
  margin: 0 0 8px;
  overflow: hidden;
}

.vp-signal-critique {
  border-left-color: var(--g-critique, var(--rouge))
}

.vp-signal-eleve {
  border-left-color: var(--g-eleve, var(--orange))
}

.vp-signal-modere {
  border-left-color: var(--g-modere, var(--ambre))
}

.vp-signal summary {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 14px 18px;
  cursor: pointer;
  list-style: none;
}

.vp-signal summary::-webkit-details-marker {
  display: none
}

.vp-signal summary::after {
  content: "+";
  margin-left: auto;
  color: var(--gris-clair);
  font-family: 'Archivo', sans-serif;
  font-size: 1.2rem;
  line-height: 1;
  transition: transform .2s;
}

.vp-signal[open] summary::after {
  content: "−"
}

.vp-signal-gravite {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .58rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 3px;
  color: #fff;
  background: var(--gris-clair);
}

.vp-signal-critique .vp-signal-gravite {
  background: var(--g-critique, var(--rouge))
}

.vp-signal-eleve .vp-signal-gravite {
  background: var(--g-eleve, var(--orange))
}

.vp-signal-modere .vp-signal-gravite {
  background: var(--g-modere, var(--ambre))
}

.vp-signal-libelle {
  font-weight: 700;
  font-size: .94rem;
  color: var(--nuit)
}

.vp-signal-valeur {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .72rem;
  color: var(--gris);
  background: var(--brume);
  border-radius: 3px;
  padding: 3px 8px;
}

.vp-signal-corps {
  padding: 0 18px 18px;
  display: grid;
  gap: 14px
}

.vp-signal-face-titre {
  display: block;
  font-family: 'IBM Plex Mono', monospace;
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--gris-clair);
  margin-bottom: 5px;
}

.vp-signal-face p {
  margin: 0;
  font-size: .9rem;
  line-height: 1.62;
  color: var(--gris)
}

.vp-signal-face-impact {
  border-left: 2px solid var(--ambre-ligne);
  padding-left: 14px
}

.vp-signal-face-remede {
  background: var(--vert-bg);
  border: 1px solid var(--vert-ligne);
  border-radius: 8px;
  padding: 14px 16px;
}

.vp-signal-face-remede .vp-signal-face-titre {
  color: var(--vert)
}

.vp-signal-face-remede p {
  color: #155e3a
}

/* ---------- Points conformes ---------- */

.vp-conformes {
  background: var(--blanc);
  border: 1px solid var(--ligne);
  border-radius: 10px;
  padding: 2px 20px;
  margin: 24px 0 0;
}

.vp-conformes summary {
  cursor: pointer;
  list-style: none;
  padding: 14px 0;
  font-family: 'Archivo', sans-serif;
  font-weight: 700;
  font-size: .94rem;
  color: var(--vert);
}

.vp-conformes summary::-webkit-details-marker {
  display: none
}

.vp-conformes summary::before {
  content: "✓ ";
  font-weight: 400
}

.vp-conformes-liste {
  list-style: none;
  margin: 0 0 16px;
  padding: 12px 0 0;
  border-top: 1px solid var(--ligne);
  display: grid;
  gap: 10px
}

.vp-conformes-liste li {
  display: flex;
  flex-direction: column;
  gap: 2px
}

.vp-conforme-libelle {
  font-weight: 600;
  font-size: .86rem;
  color: var(--encre)
}

.vp-conforme-constat {
  font-size: .82rem;
  color: var(--gris-clair);
  line-height: 1.5
}

/* ---------- Chronologie des analyses ---------- */

.vp-runs {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
  counter-reset: run
}

.vp-runs-vide {
  text-align: center;
  padding: 20px 0
}

/* Le bouton vit hors du lien : imbriquer un bouton dans un lien
   produit un HTML invalide et un comportement imprévisible au clic. */
.vp-run{position:relative}

/* Discret mais toujours visible : un bouton qui n'apparaît qu'au
   survol ne se trouve pas, et n'existe pas du tout au toucher. */
.vp-run-retirer{
  position:absolute;top:50%;right:8px;transform:translateY(-50%);
  width:28px;height:28px;border-radius:7px;
  background:none;border:0;padding:0;cursor:pointer;
  color:var(--gris-clair);font-size:1.2rem;line-height:1;
  transition:color .15s, background .15s;
}

.vp-run-retirer:hover,
.vp-run-retirer:focus-visible{color:var(--rouge);background:var(--rouge-bg)}

.vp-run-lien {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  background: var(--blanc);
  border: 1px solid var(--ligne);
  border-radius: 10px;
  /* Le bouton de suppression est posé en absolu sur la ligne : le lien
     lui réserve sa place, sinon le dernier libellé passe dessous. */
  padding: 12px 46px 12px 16px;
  text-decoration: none;
  color: inherit;
  transition: border-color .15s, transform .12s;
}

.vp-run-lien:hover {
  border-color: var(--acier);
  transform: translateX(2px);
  text-decoration: none
}
.vp-run-date {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .78rem;
  color: var(--gris);
  min-width: 112px;
  flex-shrink: 0;
}

.vp-run-date small {
  display: block;
  font-size: .68rem;
  color: var(--gris-clair)
}

.vp-run-domaine {
  font-weight: 600;
  font-size: .88rem;
  color: var(--nuit);
  flex: 1;
  min-width: 140px
}

.vp-run-scores {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-left: auto
}

.vp-run-score {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: 1.3rem;
  color: var(--nuit)
}

.vp-run-sous {
  font-size: .72rem;
  color: var(--gris-clair);
  white-space: nowrap
}

.vp-run-delta {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .76rem;
  font-weight: 700;
  padding: 3px 9px;
  border-radius: 3px;
  min-width: 44px;
  text-align: center;
}

.vp-run-delta.is-up {
  color: var(--vert);
  background: var(--vert-bg)
}

.vp-run-delta.is-down {
  color: var(--rouge);
  background: var(--rouge-bg)
}

.vp-run-delta.is-flat,
.vp-run-delta.is-first {
  color: var(--gris-clair);
  background: var(--brume)
}

.vp-run-type {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .64rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--gris-clair);
  min-width: 88px;
  text-align: right;
}

@media (max-width:640px) {
  .vp-run-tete {
    flex-direction: column;
    gap: 18px
  }

  .vp-run-scores-tete {
    width: 100%
  }

  .vp-score-bloc {
    flex: 1;
    min-width: 0;
    padding: 14px 6px
  }

  /* « Souveraineté » en capitales espacées dépasse la largeur d'un
     tiers d'écran. L'espacement se resserre plutôt que de tronquer :
     le mot doit rester lisible en entier. */
  .vp-score-bloc .vp-score-l {
    font-size: .52rem;
    letter-spacing: 0;
    text-align: center;
    line-height: 1.25;
    word-break: break-word;
    hyphens: auto;
  }

  .vp-score-bloc .vp-score-n {
    font-size: 1.9rem
  }

  

  .vp-run-scores {
    margin-left: 0
  }

  .vp-run-type {
    display: none
  }
}

@media print {

  .vp-header,
  .vp-footer,
  .vp-env-tag,
  .vp-fil {
    display: none
  }

  .vp-signal {
    break-inside: avoid
  }

  .vp-signal-corps {
    display: grid !important
  }
}

.vp-runs-section {
  margin: 32px 0 0
}

.vp-runs-tete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px
}

.vp-runs-filtre {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .7rem;
  color: var(--acier);
  background: var(--faisceau-pale);
  border-radius: 3px;
  padding: 4px 10px;
}
.vp-domaine-scan {
  background: none;
  border: 1px solid var(--ligne);
  border-radius: 8px;
  width: 32px;
  height: 32px;
  cursor: pointer;
  color: var(--acier);
  font-size: 1rem;
  line-height: 1;
  transition: border-color .15s, transform .3s;
}

.vp-domaine-scan:hover {
  border-color: var(--acier);
  transform: rotate(180deg)
}

.vp-domaine-scan[disabled] {
  opacity: .4;
  cursor: progress
}

.vp-signal-penalite {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .72rem;
  font-weight: 700;
  color: var(--rouge);
  background: var(--rouge-bg);
  border: 1px solid #f2c9c6;
  border-radius: 3px;
  padding: 3px 8px;
  white-space: nowrap;
}

/* ---------- Modales de confirmation ---------- */


/* Un solde qui ne couvre pas l'action doit se voir avant que le
   client ne clique sur un bouton qui refuserait. */
.vp-solde-insuffisant{color:var(--rouge) !important}
.vp-modal-cout-ligne strong.vp-solde-insuffisant{font-size:1.1rem}
.vp-stat-note-bonus {
  color: var(--vert);
  font-weight: 600
}

/* ---------- Bloc analyse : sélecteur + courbes ---------- */

.vp-analyse-section {
  margin: 32px 0 0
}

.vp-analyse-tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin: 0 0 16px;
}

.vp-analyse-tete .vp-domaines-titre {
  margin: 0;
  border: 0;
  padding: 0
}

/* ---------- Sélecteur de domaine ---------- */

.vp-selecteur {
  position: relative
}

.vp-selecteur-bouton {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--blanc);
  border: 1.5px solid var(--ligne);
  border-radius: 10px;
  padding: 9px 14px;
  cursor: pointer;
  font-family: 'Inter', sans-serif;
  font-size: .88rem;
  font-weight: 600;
  color: var(--nuit);
  min-width: 210px;
  justify-content: space-between;
  transition: border-color .15s;
}

.vp-selecteur-bouton:hover {
  border-color: var(--acier)
}

.vp-selecteur-bouton[aria-expanded="true"] {
  border-color: var(--acier);
  box-shadow: 0 0 0 3px rgba(45, 106, 148, .1)
}

.vp-selecteur-chevron {
  color: var(--gris-clair);
  font-size: .7rem;
  transition: transform .2s
}

.vp-selecteur-bouton[aria-expanded="true"] .vp-selecteur-chevron {
  transform: rotate(180deg)
}

.vp-selecteur-panneau {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 60;
  width: 320px;
  max-width: 88vw;
  background: var(--blanc);
  border: 1px solid var(--ligne);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(8, 26, 46, .16);
  overflow: hidden;
}

.vp-selecteur-recherche {
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--ligne);
  padding: 13px 16px;
  font: inherit;
  font-size: .88rem;
  background: var(--brume);
  color: var(--encre);
}

.vp-selecteur-recherche:focus {
  outline: none;
  background: var(--blanc)
}

.vp-selecteur-recherche::placeholder {
  color: var(--gris-clair)
}

.vp-selecteur-liste {
  list-style: none;
  margin: 0;
  padding: 6px;
  max-height: 290px;
  overflow-y: auto;
}

.vp-selecteur-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  background: none;
  border: 0;
  border-radius: 8px;
  padding: 10px 12px;
  cursor: pointer;
  text-align: left;
  font: inherit;
  transition: background .12s;
}

.vp-selecteur-item:hover {
  background: var(--brume)
}

.vp-selecteur-item.is-active {
  background: var(--faisceau-pale)
}

.vp-selecteur-item.is-active .vp-selecteur-nom {
  color: var(--acier)
}

.vp-selecteur-nom {
  font-size: .88rem;
  font-weight: 600;
  color: var(--nuit);
  word-break: break-all
}

.vp-selecteur-meta {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .68rem;
  color: var(--gris-clair);
  white-space: nowrap;
  flex-shrink: 0;
}

.vp-selecteur-score {
  font-family: 'Archivo', sans-serif;
  font-weight: 800;
  font-size: .88rem;
  border-radius: 6px;
  padding: 3px 9px;
  flex-shrink: 0;
}

.vp-score-bon {
  color: var(--vert);
  background: var(--vert-bg)
}

.vp-score-moyen {
  color: var(--ambre);
  background: var(--ambre-bg)
}

.vp-score-faible {
  color: var(--rouge);
  background: var(--rouge-bg)
}

.vp-selecteur-vide {
  margin: 0;
  padding: 14px 16px;
  font-size: .84rem;
  color: var(--gris-clair);
  text-align: center;
}

/* ---------- Cadre du graphique ---------- */

.vp-graphe-cadre {
  background: var(--blanc);
  border: 1px solid var(--ligne);
  border-radius: 12px;
  padding: 20px 22px;
  box-shadow: var(--shadow);
}

.vp-graphe-zone {
  position: relative;
  min-height: 260px
}

.vp-graphe-vide {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  padding: 0 30px;
  text-align: center;
  font-size: .88rem;
  color: var(--gris-clair);
  line-height: 1.6;
}
/* ---------- Tableau de bord en une colonne ----------
   Gridstack place les modules ; on ne touche qu'à leur hauteur, qu'il
   exprime en cellules et qui tronquerait le contenu. */

/* Gridstack place les modules en absolu, avec une hauteur exprimée en
   cellules. Sur une colonne, cette hauteur ne correspond plus au
   contenu : trop grande pour les analyses, trop courte pour les
   quotas. On rend la colonne au flux normal.

   Le conteneur perd sa hauteur calculée en même temps, sinon il
   garderait la place de la grille absolue. */
.grid-stack.is-mobile{
  height:auto !important;
  display:flex;flex-direction:column;gap:14px;
}

.grid-stack.is-mobile > .grid-stack-item{
  position:relative !important;
  left:auto !important;top:auto !important;
  width:100% !important;height:auto !important;
  min-height:0 !important;
  padding:0 !important;
}

.grid-stack.is-mobile .grid-stack-item-content{
  position:relative !important;
  inset:auto !important;
  height:auto !important;
  overflow:visible !important;
}

.grid-stack.is-mobile .vp-module{height:auto}
.grid-stack.is-mobile .vp-module-corps{max-height:none;overflow:visible}

/* Le graphique occupe la place restante d'un module à hauteur fixe.
   En hauteur automatique, `flex:1` ne prend rien et la zone
   s'effondre : il lui faut une hauteur explicite. */
.grid-stack.is-mobile .vp-module .vp-graphe-zone{
  flex:none;
  height:260px;
}

/* Trois cartes empilées occupent un écran entier pour trois chiffres.
   Sur mobile, chaque compteur devient une ligne : ce qu'on lit à
   gauche, ce qu'on mesure à droite. */
.grid-stack.is-mobile .vp-stat-grid{
  display:flex;flex-direction:column;gap:0;
}

.grid-stack.is-mobile .vp-stat{
  display:grid;
  grid-template-columns:1fr auto;
  grid-template-areas:
    "label valeur"
    "notes valeur";
  align-items:center;
  column-gap:16px;row-gap:2px;
  padding:14px 16px;
  border-radius:0;
  border:0;
  border-bottom:1px solid var(--ligne);
  border-left:3px solid var(--acier);
  box-shadow:none;
}
.grid-stack.is-mobile .vp-stat:last-child{border-bottom:0}

.grid-stack.is-mobile .vp-stat-label{grid-area:label;margin:0}

.grid-stack.is-mobile .vp-stat-value{
  grid-area:valeur;
  font-size:1.5rem;
  text-align:right;
  white-space:nowrap;
}

/* Les notes secondaires se rangent sous le libellé, en une seule
   ligne : deux notes empilées annuleraient le gain de place. */
.grid-stack.is-mobile .vp-stat-note,
.grid-stack.is-mobile .vp-stat-jetons{
  grid-area:notes;
  margin:0;
  font-size:.72rem;
}

.grid-stack.is-mobile .vp-stat-jetons{
  display:flex;align-items:center;gap:8px;flex-wrap:wrap;
}

/* Deux éléments dans la même zone se superposeraient : la note de
   remise à zéro passe après le bloc jetons. */
.grid-stack.is-mobile .vp-stat:has(.vp-stat-jetons){
  grid-template-areas:
    "label valeur"
    "jetons valeur"
    "notes notes";
}
.grid-stack.is-mobile .vp-stat:has(.vp-stat-jetons) .vp-stat-jetons{grid-area:jetons}
.grid-stack.is-mobile .vp-stat:has(.vp-stat-jetons) .vp-stat-note:last-child{
  grid-area:notes;margin-top:4px;
}

.grid-stack.is-mobile [data-runs-liste],
.grid-stack.is-mobile [data-domaines-liste]{
  max-height:420px;
  overflow-y:auto;
  -webkit-overflow-scrolling:touch;
}

@media (max-width:640px) {
  .vp-analyse-tete {
    flex-direction: column;
    align-items: stretch
  }

  .vp-selecteur-bouton {
    width: 100%
  }

  .vp-selecteur-panneau {
    width: 100%;
    right: auto;
    left: 0
  }

  .vp-graphe-cadre {
    padding: 16px 12px
  }
}

/* ---------- Tableau de bord modulaire ---------- */

.vp-dash-tete {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  margin: 0 0 24px;
}

.vp-dash-outils {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap
}

/* « Disposition d'origine » ressemblait à du texte : c'est une action
   destructive, elle doit se voir comme telle sans concurrencer
   l'enregistrement. */
.vp-dash-edition .vp-link-button{
  padding:8px 14px;
  border:1px dashed var(--ligne);border-radius:8px;
  font-family:'Archivo',sans-serif;font-weight:600;font-size:.82rem;
  transition:border-color .15s, color .15s, background .15s;
}
.vp-dash-edition .vp-link-button:hover{
  border-color:var(--ambre);color:var(--ambre);background:var(--ambre-bg);
}

.vp-dash-edition{
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap
}

.grid-stack {
  margin: 0 -10px 0 -10px
}

.grid-stack-item-content {
  inset: 10px !important;
  overflow: visible;
}

.grid-stack-item-content {
  inset: 10px !important;
  overflow: visible;
}

.vp-module {
  display: flex;
  flex-direction: column;
  background: var(--blanc);
  border: 1px solid var(--ligne);
  border-radius: 12px;
  box-shadow: var(--shadow);
  overflow: hidden;
  position: absolute;
  inset: 0;
}

.vp-module-tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 18px 12px;
  border-bottom: 1px solid var(--ligne);
  flex-shrink: 0;
  transition: background .15s;
}

/* Toute la barre de titre devient la prise : plus facile à attraper
   qu'une icône de quelques pixels, surtout au doigt. */
.grid-stack.is-editing .vp-module-tete {
  cursor: grab;
  background: var(--brume);
}

.grid-stack.is-editing .vp-module-tete:hover {
  background: var(--faisceau-pale)
}

.grid-stack.is-editing .vp-module-tete:active {
  cursor: grabbing
}

.vp-module-titre {
  font-family: 'IBM Plex Mono', monospace;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--acier);
  margin: 0;
}

/* La poignée n'est plus la zone de prise mais l'indice visuel qui
   signale qu'on peut saisir : elle reste inerte aux clics, la barre
   entière s'en charge. */
.vp-module-poignee {
  color: var(--acier);
  font-size: .9rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity .18s;
}

.grid-stack.is-editing .vp-module-poignee {
  opacity: 1
}

.vp-module-corps {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 16px 18px 18px;
}

.vp-module-note {
  margin: 14px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--ligne);
  font-size: .82rem;
  color: var(--ambre);
}

.vp-module-action {
  width: 100%;
  margin: 14px 0 0;
  padding: 11px;
  background: none;
  border: 1.5px dashed var(--ligne);
  border-radius: 10px;
  color: var(--acier);
  font-family: 'Archivo', sans-serif;
  font-weight: 700;
  font-size: .88rem;
  cursor: pointer;
  transition: border-color .15s, background .15s;
}

.vp-module-action:hover {
  border-color: var(--acier);
  background: var(--faisceau-pale)
}

/* ---------- Mode édition ---------- */

.grid-stack.is-editing .vp-module {
  border-color: var(--acier);
  box-shadow: 0 0 0 2px rgba(45, 106, 148, .12);
}

.grid-stack.is-editing .vp-module-corps {
  opacity: .55;
  pointer-events: none;
  user-select: none;
}

.grid-stack-item.ui-draggable-dragging .vp-module {
  box-shadow: 0 16px 40px rgba(8, 26, 46, .24);
  transform: rotate(.4deg);
}

.grid-stack .grid-stack-placeholder>.placeholder-content {
  background: rgba(45, 106, 148, .08);
  border: 2px dashed var(--acier);
  border-radius: 12px;
}

/* ---------- Graphique dans un module ---------- */

/* Le module devient une colonne flex : le sélecteur garde sa taille
   naturelle, le graphique prend tout ce qui reste. Sans cela, le
   canvas à 100 % de hauteur débordait toujours de la hauteur du
   sélecteur, et l'ascenseur ne disparaissait jamais quelle que soit
   la taille du bloc. */
.vp-module-corps:has(.vp-graphe-zone) {
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.vp-module .vp-selecteur {
  margin: 0 0 14px;
  flex-shrink: 0
}

.vp-module .vp-selecteur-bouton {
  width: 100%
}

.vp-module .vp-graphe-zone {
  position: relative;
  flex: 1;
  min-height: 0;
}

/* Chart.js gère le dimensionnement : le canvas doit pouvoir rétrécir
   sous sa taille intrinsèque, ce que `position:absolute` garantit. */
.vp-module .vp-graphe-zone canvas {
  position: absolute;
  inset: 0;
}

@media (max-width:900px) {
  .vp-dash-tete {
    flex-direction: column
  }

  /* Réorganiser n'a pas de sens quand la disposition est imposée : la
     grille est en une colonne, et rien de ce qu'on y déplacerait ne
     serait conservé. */
  .vp-dash-outils {
    display: none
  }

  .vp-module-poignee {
    display: none
  }

  .vp-module-corps {
    overflow-y: visible
  }
}

@media (prefers-reduced-motion: reduce) {
  .vp-toast {
    transition: opacity .01s
  }

  .vp-toast.is-visible {
    transform: none
  }
}
.vp-module-outils {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0
}

.vp-module-ajout {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  background: var(--nuit);
  border: 0;
  border-radius: 8px;
  color: #fff;
  font-family: 'Archivo', sans-serif;
  font-size: 1.15rem;
  font-weight: 400;
  line-height: 1;
  cursor: pointer;
  transition: transform .3s cubic-bezier(.34, 1.28, .44, 1), filter .15s;
}

.vp-module-ajout:hover {
  filter: brightness(1.35);
  transform: rotate(90deg)
}

/* Gridstack utilise .vp-module-tete comme prise : un bouton qui s'y
   trouve doit rester cliquable, sinon le clic déclenche un glisser. */
.grid-stack.is-editing .vp-module-ajout {
  opacity: .35;
  pointer-events: none;
}

/* ---------- Achat de jetons ---------- */

.vp-jetons-solde{
  margin:0 0 16px;padding:10px 14px;
  background:var(--vert-bg);border:1px solid var(--vert-ligne);border-radius:8px;
  font-size:.86rem;font-weight:600;color:#155e3a;
}

.vp-packs{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin:0 0 16px}

.vp-pack{
  position:relative;display:flex;flex-direction:column;align-items:center;
  gap:2px;padding:22px 16px 18px;
  background:var(--blanc);border:1.5px solid var(--ligne);border-radius:12px;
  transition:border-color .15s, transform .15s;
}
.vp-pack:hover{border-color:var(--acier);transform:translateY(-2px)}
.vp-pack.is-featured{border-color:var(--nuit);box-shadow:0 0 0 3px rgba(8,26,46,.07)}

.vp-pack-badge{
  position:absolute;top:-10px;left:50%;transform:translateX(-50%);
  font-family:'IBM Plex Mono',monospace;font-size:.58rem;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;white-space:nowrap;
  background:var(--nuit);color:#fff;border-radius:3px;padding:4px 10px;
}

.vp-pack-quantite{
  font-family:'Archivo',sans-serif;font-weight:800;font-size:2.2rem;
  color:var(--nuit);line-height:1;
}
.vp-pack-unite{
  font-family:'IBM Plex Mono',monospace;font-size:.64rem;
  letter-spacing:.12em;text-transform:uppercase;color:var(--gris-clair);
}

.vp-pack-prix{
  font-family:'Archivo',sans-serif;font-weight:800;font-size:1.25rem;
  color:var(--acier);margin-top:12px;
}
.vp-pack-unitaire{font-size:.72rem;color:var(--gris-clair)}

.vp-pack-form{width:100%;margin-top:14px}
.vp-pack .vp-button{width:100%;padding:10px;font-size:.86rem}

.vp-pack-indispo{
  margin-top:14px;font-size:.76rem;color:var(--gris-clair);text-align:center;
}

.vp-packs-note{margin:0;padding-top:14px;border-top:1px solid var(--ligne)}

@media (max-width:640px){
  .vp-packs{grid-template-columns:1fr;gap:10px}
  .vp-pack{flex-direction:row;align-items:center;justify-content:space-between;
           flex-wrap:wrap;padding:16px 18px;gap:10px}
  .vp-pack-badge{position:static;transform:none;order:-1;width:100%}
  .vp-pack-quantite{font-size:1.6rem}
  .vp-pack-prix{margin-top:0}
  .vp-pack-form{width:auto;margin-top:0}
}
.vp-stat-jetons{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:6px;
}
.vp-stat-jetons .vp-stat-note{margin:0}

/* Sur une ligne de définition, le bouton s'aligne sur la ligne de
   base du texte et paraît tomber. Le centrage vertical demande que le
   conteneur porte l'alignement, pas le bouton. */
.vp-deflist dd{display:flex;align-items:center;gap:10px;flex-wrap:wrap}

.vp-jetons-btn{
  display:inline-flex;align-items:center;gap:5px;
  padding:5px 12px;border-radius:999px;
  background:var(--faisceau-pale);border:1px solid #b9dcf2;
  color:var(--acier);font-family:'Archivo',sans-serif;
  font-weight:700;font-size:.74rem;cursor:pointer;
  transition:background .15s, border-color .15s;
}
.vp-jetons-btn:hover{background:var(--acier);border-color:var(--acier);color:#fff}
.vp-jetons-btn span{font-size:.95rem;line-height:1}

/* ---------- Chronologie de facturation ---------- */

.vp-chrono{list-style:none;margin:0;padding:0;position:relative}

/* Le trait vertical relie les mouvements : il matérialise la
   continuité d'un compte plutôt qu'une suite de lignes sans lien. */
.vp-chrono::before{
  content:"";position:absolute;left:74px;top:8px;bottom:8px;
  width:1px;background:var(--ligne);
}

.vp-chrono-jour{
  font-family:'IBM Plex Mono',monospace;font-size:.64rem;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--gris-clair);
  padding:18px 0 8px 96px;
}
.vp-chrono-jour:first-child{padding-top:0}

.vp-chrono-item{
  position:relative;display:flex;align-items:center;gap:14px;
  padding:11px 0 11px 0;
}

.vp-chrono-heure{
  width:60px;flex-shrink:0;text-align:right;
  font-family:'IBM Plex Mono',monospace;font-size:.72rem;color:var(--gris-clair);
}

.vp-chrono-point{
  position:absolute;left:70px;
  width:9px;height:9px;border-radius:50%;
  background:var(--blanc);border:2px solid var(--gris-clair);
  z-index:1;
}
.vp-chrono-facture .vp-chrono-point{border-color:var(--acier)}
.vp-chrono-credit .vp-chrono-point{border-color:var(--vert)}
.vp-chrono-depense .vp-chrono-point{border-color:var(--ligne);background:var(--ligne)}

.vp-chrono-corps{
  flex:1;min-width:0;display:flex;flex-direction:column;gap:1px;
  padding-left:36px;
}
.vp-chrono-titre{font-size:.9rem;font-weight:600;color:var(--encre)}
.vp-chrono-detail{font-size:.76rem;color:var(--gris-clair)}

.vp-chrono-valeurs{
  display:flex;align-items:center;gap:14px;flex-shrink:0;
}

.vp-chrono-jetons{
  font-family:'IBM Plex Mono',monospace;font-size:.76rem;font-weight:700;
  padding:3px 9px;border-radius:3px;white-space:nowrap;
}
.vp-chrono-jetons.is-plus{color:var(--vert);background:var(--vert-bg)}
.vp-chrono-jetons.is-moins{color:var(--gris-clair);background:var(--brume)}

.vp-chrono-montant{
  font-family:'Archivo',sans-serif;font-weight:800;font-size:.94rem;
  color:var(--nuit);white-space:nowrap;min-width:64px;text-align:right;
}

.vp-chrono-pdf{
  width:30px;flex-shrink:0;text-align:center;
  color:var(--acier);font-size:1.05rem;
  transition:color .15s, transform .15s;
}
a.vp-chrono-pdf:hover{color:var(--rouge);transform:scale(1.12);text-decoration:none}

/* Facture antérieure au suivi en base : l'icône reste, grisée et
   inerte, plutôt que de laisser un vide inexpliqué. */
.vp-chrono-pdf.is-absent{color:var(--ligne);cursor:default}
.vp-chrono-pdf.is-vide{color:transparent}

@media (max-width:640px){
  .vp-chrono::before,.vp-chrono-point{display:none}
  .vp-chrono-jour{padding-left:0}
  .vp-chrono-item{flex-wrap:wrap;gap:8px;padding:12px 0;
                  border-bottom:1px solid var(--ligne)}
  .vp-chrono-heure{width:auto;text-align:left}
  .vp-chrono-corps{padding-left:0;flex-basis:100%;order:-1}
  .vp-chrono-valeurs{margin-left:auto}
}
/* ---------- Résiliation ---------- */

.vp-resil-alerte{
  background:var(--ambre-bg);border:1px solid var(--ambre-ligne);
  border-left:3px solid var(--ambre);border-radius:0 10px 10px 0;
  padding:14px 18px;margin:0 0 18px;
}
.vp-resil-alerte-titre{
  display:block;font-family:'Archivo',sans-serif;font-weight:800;
  font-size:.94rem;color:var(--ambre);margin-bottom:5px;
}
.vp-resil-alerte p{margin:0;font-size:.86rem;color:#7a4a12;line-height:1.55}

/* La résiliation est assumée : un bouton net, distingué par sa
   bordure et poussé à droite. Le rouge plein reste réservé à la
   confirmation dans la modale, là où il avertit vraiment. */
.vp-actions-compte{align-items:center}


@media (max-width:640px){
  .vp-button-sortie{margin-left:0;width:100%}
}

.vp-resil-encours{
  display:flex;align-items:flex-start;gap:14px;flex-wrap:wrap;
  background:var(--ambre-bg);border:1px solid var(--ambre-ligne);
  border-left:3px solid var(--ambre);border-radius:0 10px 10px 0;
  padding:16px 18px;margin:18px 0 0;
}
.vp-resil-encours-corps{flex:1;min-width:220px}
.vp-resil-encours-titre{
  display:block;font-family:'Archivo',sans-serif;font-weight:800;
  font-size:.94rem;color:var(--ambre);margin-bottom:4px;
}
.vp-resil-encours p{margin:0;font-size:.84rem;color:#7a4a12;line-height:1.55}
.vp-resil-encours form{margin:0;flex-shrink:0}
/* ---------- Surcharges de l'espace client ----------
   Ces règles diffèrent volontairement du socle : dans un formulaire,
   l'action principale occupe toute la largeur, alors qu'elle reste
   dimensionnée à son contenu sur la landing. */

.vp-button-primary{width:100%}
.vp-actions .vp-button-primary{width:auto}
.vp-actions-compte{align-items:center}
.vp-button-sortie{margin-left:auto}

@media (max-width:640px){
  .vp-button-sortie{margin-left:0;width:100%}
}
/* ---------- Saisie du code en six cases ----------
   Le collage doit fonctionner : un client copie son code depuis
   l'e-mail, il ne le retape pas chiffre par chiffre. Le JavaScript
   répartit la valeur collée sur les six cases. */

.vp-code-label{text-align:center}

.vp-code-cases{
  display:flex;align-items:center;justify-content:center;gap:9px;
  margin:6px 0 0;
}

.vp-code-cases input{
  width:52px;height:62px;padding:0;
  border:1.5px solid var(--ligne);border-radius:12px;
  background:var(--blanc);
  font-family:'IBM Plex Mono',monospace;font-size:1.7rem;font-weight:600;
  text-align:center;color:var(--nuit);
  transition:border-color .15s, box-shadow .15s, transform .12s;
}

.vp-code-cases input:focus{
  outline:none;border-color:var(--acier);
  box-shadow:0 0 0 4px rgba(45,106,148,.14);
  transform:translateY(-1px);
}

.vp-code-cases input.is-rempli{border-color:var(--acier);background:var(--faisceau-pale)}

.vp-code-tiret{
  width:12px;height:2px;border-radius:1px;
  background:var(--ligne);flex-shrink:0;
}

.vp-code-cases.is-invalide input{
  border-color:var(--rouge);
  animation:vp-code-secousse .4s;
}

@keyframes vp-code-secousse{
  0%,100%{transform:translateX(0)}
  25%{transform:translateX(-4px)}
  75%{transform:translateX(4px)}
}

@media (max-width:480px){
  .vp-code-cases{gap:6px}
  .vp-code-cases input{width:42px;height:52px;font-size:1.4rem}
  .vp-code-tiret{width:8px}
}

/* ---------- Appareils reconnus ---------- */

.vp-appareils-tete{
  display:flex;align-items:baseline;justify-content:space-between;
  gap:16px;margin:22px 0 12px;
}

.vp-appareils-titre{
  font-family:'IBM Plex Mono',monospace;font-size:.66rem;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--gris-clair);
}

.vp-appareils-tete .vp-form-inline{margin:0;text-align:right}

.vp-appareils{list-style:none;margin:0;padding:0;display:grid;gap:8px}

.vp-appareil{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  background:var(--blanc);border:1px solid var(--ligne);
  border-radius:10px;padding:13px 16px;
}
.vp-appareil.is-courant{border-color:#b9dcf2;background:var(--faisceau-pale)}

.vp-appareil-corps{display:flex;flex-direction:column;gap:2px;min-width:0}

.vp-appareil-nom{
  display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  font-size:.9rem;font-weight:600;color:var(--encre);
}

.vp-appareil-badge{
  font-family:'IBM Plex Mono',monospace;font-size:.58rem;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;
  background:var(--acier);color:#fff;border-radius:3px;padding:3px 8px;
}

.vp-appareil-detail{font-size:.76rem;color:var(--gris-clair);line-height:1.45}

.vp-appareil form{margin:0;flex-shrink:0}

.vp-appareil-retirer{
  background:none;border:0;padding:0 4px;cursor:pointer;
  color:var(--gris-clair);font-size:1.35rem;line-height:1;
  transition:color .15s;
}
.vp-appareil-retirer:hover{color:var(--rouge)}

@media (max-width:560px){
  .vp-appareil{align-items:flex-start}
}
/* ---------- Renvoi de code ----------
   Ce n'est pas une action secondaire : c'est la seule issue quand
   l'e-mail n'arrive pas. Elle mérite un bouton, pas un lien discret. */

.vp-renvoi{
  display:flex;align-items:center;justify-content:space-between;gap:18px;
  flex-wrap:wrap;margin:24px 0 0;padding:16px 18px;
  background:var(--brume);border:1px solid var(--ligne);border-radius:10px;
}

.vp-renvoi-texte{
  flex:1;min-width:200px;margin:0;
  font-size:.82rem;color:var(--gris);line-height:1.5;
}

.vp-renvoi form{margin:0;flex-shrink:0}
.vp-renvoi .vp-button{width:auto}
.vp-renvoi .vp-button i{font-size:.8em}

/* Le compte à rebours évite de cliquer dans le vide : le serveur
   refuse un second envoi dans la minute qui suit. */
.vp-renvoi .vp-button[disabled]{opacity:.5;cursor:not-allowed}

/* ---------- Page compte : sommaire latéral ---------- */

.vp-compte{
  display:grid;grid-template-columns:210px 1fr;
  gap:28px;align-items:start;
  max-width:1080px;margin:0 auto;
}

/* Le sommaire suit le défilement : la page est longue, et perdre le
   repère de navigation à mi-parcours oblige à remonter. */
.vp-sommaire{
  position:sticky;top:26px;
  display:flex;flex-direction:column;gap:2px;
  background:var(--blanc);border:1px solid var(--ligne);
  border-radius:12px;padding:16px 14px;box-shadow:var(--shadow);
}

.vp-sommaire-titre{
  font-family:'IBM Plex Mono',monospace;font-size:.62rem;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--gris-clair);
  padding:0 10px 12px;margin-bottom:6px;border-bottom:1px solid var(--ligne);
}

.vp-sommaire-lien{
  display:flex;align-items:center;gap:10px;
  padding:9px 11px;border-radius:8px;
  font-size:.86rem;font-weight:600;color:var(--gris);
  transition:background .15s, color .15s;
}
.vp-sommaire-lien:hover{background:var(--brume);color:var(--nuit);text-decoration:none}
.vp-sommaire-lien i{width:15px;text-align:center;font-size:.82rem;color:var(--gris-clair)}

.vp-sommaire-lien.is-active{background:var(--faisceau-pale);color:var(--acier)}
.vp-sommaire-lien.is-active i{color:var(--acier)}

.vp-sommaire-pied{
  margin-top:12px;padding-top:12px;border-top:1px solid var(--ligne);
  display:flex;flex-direction:column;gap:3px;padding-left:11px;
}
.vp-sommaire-forfait{
  font-family:'Archivo',sans-serif;font-weight:800;font-size:.88rem;color:var(--nuit);
}
.vp-sommaire-solde{font-size:.74rem;color:var(--gris-clair)}

.vp-panel-compte{
  max-width:none;margin:0;
  background:none;border:0;box-shadow:none;padding:0;
}

/* Chaque section devient une carte : les traits de séparation
   suffisaient sur une page courte, pas sur quatre sections dont l'une
   déroule un historique. */
.vp-panel-compte .vp-fieldset{
  background:var(--blanc);
  border:1px solid var(--ligne);
  border-radius:14px;
  padding:24px 26px;
  margin:0 0 16px;
  box-shadow:var(--shadow);
}

.vp-panel-compte .vp-fieldset-legend{
  border-bottom:1px solid var(--ligne);
  margin-bottom:20px;
}

.vp-panel-compte .vp-title,
.vp-panel-compte .vp-subtitle{padding-left:2px}

@media (max-width:640px){
  .vp-panel-compte .vp-fieldset{padding:20px 18px;border-radius:12px}
}

/* Le défilement vers une ancre doit s'arrêter sous ce qui reste
   affiché : le sommaire seul sur bureau, l'en-tête et le sommaire
   empilés sur mobile. */
.vp-fieldset[id]{scroll-margin-top:26px}

@media (max-width:900px){
  .vp-fieldset[id]{scroll-margin-top:124px}
}

/* ---------- Historique replié ---------- */

.vp-chrono-item.is-masque,
.vp-chrono-jour.is-masque{display:none}
.vp-chrono.is-deplie .is-masque{display:flex}
.vp-chrono.is-deplie li.vp-chrono-jour.is-masque{display:block}

.vp-chrono-plus{
  width:100%;margin-top:14px;padding:11px;
  background:none;border:1.5px dashed var(--ligne);border-radius:10px;
  color:var(--acier);font-family:'Archivo',sans-serif;
  font-weight:700;font-size:.84rem;cursor:pointer;
  transition:border-color .15s, background .15s;
}
.vp-chrono-plus:hover{border-color:var(--acier);background:var(--faisceau-pale)}

/* ---------- Changement d'adresse en attente ---------- */

.vp-email-attente{
  display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap;
  margin-left:10px;padding:4px 10px;border-radius:6px;
  background:var(--ambre-bg);border:1px solid var(--ambre-ligne);
  font-size:.74rem;font-weight:400;color:var(--ambre);
}
.vp-email-attente .vp-link-button{
  font-size:.74rem;color:var(--ambre);text-decoration:underline;
}
.vp-email-attente .vp-link-button:hover{color:#7a4a12}

@media (max-width:900px){
  .vp-compte{grid-template-columns:1fr;gap:18px}

  /* Sur mobile, le sommaire devient une barre horizontale — mais elle
     reste collée en haut : sur une page longue, perdre le repère de
     navigation oblige à remonter. */
  .vp-sommaire{
    position:sticky;top:56px;z-index:40;
    flex-direction:row;overflow-x:auto;
    gap:6px;padding:10px;
    border-radius:0 0 12px 12px;
    box-shadow:0 4px 14px rgba(8,26,46,.08);
  }
  .vp-sommaire-titre,.vp-sommaire-pied{display:none}
  .vp-sommaire-lien{white-space:nowrap;padding:8px 12px}
  .vp-sommaire-lien i{display:none}
}
/* =====================================================================
   Aide contextuelle

   Identité visuelle unique : ampoule + violet. Ce ton n'existe nulle
   part ailleurs dans l'interface, donc dès qu'il apparaît, le client
   sait qu'on l'accompagne plutôt qu'on l'alerte.

   Deux variantes :
     .vp-aide            bloc pleine largeur, pour un état vide
     .vp-aide-inline     encart discret au fil de la page
   ===================================================================== */

:root{
  --aide:#6342a8;
  --aide-clair:#a084d8;
  --aide-bg:#f6f2fd;
  --aide-bg-pale:#fbf9ff;
  --aide-ligne:#d8cdf0;
  --aide-encre:#4a2f7a;
}

.vp-aide{
  position:relative;overflow:hidden;
  background:linear-gradient(135deg, var(--aide-bg) 0%, var(--aide-bg-pale) 60%, var(--blanc) 100%);
  border:1.5px solid var(--aide-ligne);border-radius:14px;
  padding:32px 34px;margin:0 0 4px;
}

/* Halo décoratif : donne du relief sans peser sur la lecture. */
.vp-aide::before{
  content:"";position:absolute;top:-90px;right:-70px;
  width:240px;height:240px;border-radius:50%;
  background:radial-gradient(circle, rgba(99,66,168,.10), transparent 68%);
  pointer-events:none;
}

.vp-aide-tete{
  position:relative;display:flex;align-items:flex-start;gap:16px;
  margin:0 0 22px;
}

.vp-aide-pastille{
  flex-shrink:0;
  width:46px;height:46px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--aide);color:#fff;font-size:1.2rem;
  box-shadow:0 4px 14px rgba(99,66,168,.28);
}

/* L'ampoule respire : le mouvement attire l'œil sans agiter la page. */
.vp-aide-pastille i{animation:vp-aide-lueur 3.4s ease-in-out infinite}

@keyframes vp-aide-lueur{
  0%,100%{opacity:1;transform:scale(1)}
  50%{opacity:.72;transform:scale(.93)}
}

.vp-aide-titre{
  font-family:'Archivo',sans-serif;font-weight:800;font-size:1.3rem;
  color:var(--aide-encre);margin:0 0 6px;line-height:1.25;
}

.vp-aide-intro{margin:0;font-size:.96rem;color:var(--gris);line-height:1.6;max-width:60ch}

/* ---------- Étapes ---------- */

.vp-aide-etapes{
  position:relative;list-style:none;margin:0 0 26px;padding:0;
  display:grid;gap:14px;counter-reset:aide;
}

.vp-aide-etape{
  display:flex;align-items:flex-start;gap:14px;
  background:rgba(255,255,255,.7);
  border:1px solid var(--aide-ligne);border-radius:10px;
  padding:14px 18px;
}

.vp-aide-etape::before{
  counter-increment:aide;content:counter(aide);
  flex-shrink:0;width:26px;height:26px;border-radius:50%;
  background:var(--aide);color:#fff;
  font-family:'Archivo',sans-serif;font-size:.82rem;font-weight:800;
  display:flex;align-items:center;justify-content:center;
}

.vp-aide-etape-corps{display:flex;flex-direction:column;gap:2px;min-width:0}
.vp-aide-etape-titre{font-weight:700;font-size:.94rem;color:var(--nuit)}
.vp-aide-etape-detail{font-size:.85rem;color:var(--gris);line-height:1.55}

/* ---------- Appel à l'action ---------- */

.vp-aide-pied{
  position:relative;display:flex;align-items:center;gap:18px;
  flex-wrap:nowrap;
}

.vp-aide-fleches{
  display:flex;align-items:center;gap:5px;color:var(--aide-clair);
  font-size:1.15rem;flex-shrink:0;
}

/* Les trois flèches partent en cascade : le décalage crée un
   glissement du regard vers le bouton, là où une animation
   simultanée ferait clignoter. */
.vp-aide-fleches i{animation:vp-aide-pointe 1.6s ease-in-out infinite}
.vp-aide-fleches i:nth-child(2){animation-delay:.18s}
.vp-aide-fleches i:nth-child(3){animation-delay:.36s}

@keyframes vp-aide-pointe{
  0%,100%{transform:translateX(0);opacity:.35}
  50%{transform:translateX(6px);opacity:1}
}

.vp-aide .vp-button-primary{
  background:var(--aide);border-color:var(--aide);
  box-shadow:0 4px 16px rgba(99,66,168,.3);
}
.vp-aide .vp-button-primary:hover{filter:brightness(1.15)}

.vp-aide-note{
  margin:20px 0 0;padding-top:16px;border-top:1px solid var(--aide-ligne);
  font-size:.8rem;color:var(--gris-clair);line-height:1.55;
}
.vp-aide-note strong{color:var(--aide-encre)}

/* ---------- Variante inline ---------- */

.vp-aide-inline{
  display:flex;align-items:flex-start;gap:13px;
  background:var(--aide-bg);border:1px solid var(--aide-ligne);
  border-left:3px solid var(--aide);border-radius:0 10px 10px 0;
  padding:13px 16px;margin:16px 0;
}

.vp-aide-inline-ico{
  flex-shrink:0;color:var(--aide);font-size:.95rem;margin-top:2px;
}
.vp-aide-inline p{margin:0;font-size:.86rem;color:var(--gris);line-height:1.55}
.vp-aide-inline strong{color:var(--aide-encre)}

@media (max-width:640px){
  .vp-aide{padding:24px 20px}
  .vp-aide-titre{font-size:1.12rem}
  .vp-aide-tete{gap:12px}
  .vp-aide-pastille{width:38px;height:38px;font-size:1rem}
  .vp-aide-pied{flex-direction:column;align-items:stretch}
  .vp-aide-fleches{display:none}
  .vp-aide .vp-button{width:100%}
}

@media (prefers-reduced-motion: reduce){
  .vp-aide-pastille i,.vp-aide-fleches i{animation:none}
  .vp-aide-fleches i{opacity:1}
}
/* ---------- Jetons illimités ----------
   Le compte Créateur n'a pas un solde très élevé : il n'en a pas.
   Le symbole le dit mieux qu'un nombre. */

.vp-stat-note-infini{
  display:inline-flex;align-items:center;gap:6px;
  color:var(--aide);font-weight:600;
}

.vp-infini{
  font-size:1.35rem;line-height:1;font-weight:400;
  display:inline-block;
}

/* Le symbole respire lentement : présent sans réclamer l'attention. */
.vp-stat-note-infini .vp-infini{animation:vp-infini-souffle 4s ease-in-out infinite}

@keyframes vp-infini-souffle{
  0%,100%{opacity:1;transform:scale(1)}
  50%{opacity:.6;transform:scale(1.12)}
}

.vp-jetons-btn-infini{
  background:var(--aide-bg);border-color:var(--aide-ligne);color:var(--aide);
}
.vp-jetons-btn-infini:hover{background:var(--aide);border-color:var(--aide);color:#fff}

/* L'infini part en vrille quand on insiste. */
.vp-infini.is-vrille{animation:vp-infini-vrille .9s cubic-bezier(.34,1.28,.44,1)}

@keyframes vp-infini-vrille{
  0%{transform:rotate(0) scale(1)}
  35%{transform:rotate(180deg) scale(1.6)}
  70%{transform:rotate(360deg) scale(.85)}
  100%{transform:rotate(360deg) scale(1)}
}

.vp-jetons-btn-infini.is-lasse{opacity:.45;cursor:not-allowed}
/* L'option d'effacement définitif se détache du texte : c'est un choix
   irréversible, il ne doit pas se confondre avec l'explication qui
   précède. */
.vp-retrait-option{
  margin:20px 0 0 !important;
  padding:14px 16px;
  background:var(--rouge-bg);
  border:1px solid #f2c9c6;
  border-left:3px solid var(--rouge);
  border-radius:0 10px 10px 0;
}

.vp-retrait-option label{
  align-items:flex-start;
  color:#7a2520 !important;
  margin:0;
}

.vp-retrait-option input{
  margin-top:3px;
  accent-color:var(--rouge);
}

.vp-retrait-option strong{color:var(--rouge)}
.vp-retrait-option span{line-height:1.5;font-size:.84rem}

.vp-abandon-ico{
  text-align:center;color:var(--acier);font-size:2.4rem;margin:0 0 18px;
}
/* La case reste inactive tant que le texte n'a pas été ouvert : sans
   explication, le client croit à un dysfonctionnement. */
.vp-cgv-note{
  display:flex;align-items:center;gap:8px;
  margin:8px 0 0;padding:8px 12px;
  background:var(--ambre-bg);border:1px solid var(--ambre-ligne);
  border-radius:8px;font-size:.8rem;color:#7a4a12;
}
.vp-cgv-note i{font-size:.72rem;color:var(--ambre)}

/* La case grisée doit se voir comme inactive, pas comme absente. */
.vp-field-check input[disabled]{cursor:not-allowed;opacity:.5}
.vp-field-check:has(input[disabled]) label{color:var(--gris-clair)}

/* Un rappel visible à l'endroit du manque, plutôt qu'un message en
   haut de page qu'il faut aller chercher. */
.vp-field-check.is-manquant{
  background:var(--rouge-bg);border-radius:8px;
  padding:8px 12px;margin-left:-12px;margin-right:-12px;
  animation:vp-code-secousse .4s;
}
.vp-field-check.is-manquant label{color:var(--rouge)}
/* ---------- Paiement en échec ----------
   Un incident de paiement inquiète : le bandeau doit se voir, mais
   dire ce qui se passe et ce qu'on peut faire plutôt que d'alarmer.
   Le client n'a rien fait de mal — c'est sa banque qui a refusé. */

.vp-impaye{
  display:flex;align-items:center;gap:20px;flex-wrap:wrap;
  background:var(--ambre-bg);border:1px solid var(--ambre-ligne);
  border-left:4px solid var(--ambre);border-radius:0 12px 12px 0;
  padding:20px 24px;margin:0 0 24px;
}

.vp-impaye-ico{
  flex-shrink:0;
  width:46px;height:46px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--ambre);color:#fff;font-size:1.15rem;
  animation:vp-impaye-pulse 2.6s ease-in-out infinite;
}

/* Une pulsation lente : elle attire l'œil sans clignoter. Un bandeau
   qui clignote se fait ignorer comme une publicité. */
@keyframes vp-impaye-pulse{
  0%,100%{box-shadow:0 0 0 0 rgba(180,83,9,.4)}
  50%{box-shadow:0 0 0 9px rgba(180,83,9,0)}
}

.vp-impaye-corps{flex:1;min-width:260px}

.vp-impaye-titre{
  display:block;font-family:'Archivo',sans-serif;font-weight:800;
  font-size:1.02rem;color:var(--ambre);margin-bottom:6px;
}

.vp-impaye p{margin:0 0 6px;font-size:.88rem;color:#7a4a12;line-height:1.55}
.vp-impaye-detail{font-size:.82rem !important;opacity:.85}

.vp-impaye .vp-button{flex-shrink:0}

@media (max-width:640px){
  .vp-impaye{flex-direction:column;align-items:flex-start;gap:14px}
  .vp-impaye .vp-button{width:100%}
}
/* ---------- Résiliation en cours ----------
   Rappeler ce qui va être perdu, sans retenir de force : un client
   qui se sent piégé ne revient jamais. Le ton reste factuel, et le
   bouton propose plutôt qu'il ne supplie. */

.vp-retour{
  display:flex;align-items:center;gap:20px;flex-wrap:wrap;
  background:linear-gradient(120deg, var(--faisceau-pale) 0%, #f4f9fd 60%, var(--blanc) 100%);
  border:1px solid #b9dcf2;border-left:4px solid var(--acier);
  border-radius:0 12px 12px 0;padding:20px 24px;margin:0 0 24px;
}

.vp-retour-ico{
  flex-shrink:0;
  width:46px;height:46px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--acier);color:#fff;font-size:1.15rem;
}

.vp-retour-corps{flex:1;min-width:260px}

.vp-retour-titre{
  display:block;font-family:'Archivo',sans-serif;font-weight:800;
  font-size:1.02rem;color:var(--ardoise);margin-bottom:6px;
}

.vp-retour p{margin:0 0 6px;font-size:.88rem;color:var(--gris);line-height:1.55}
.vp-retour-detail{font-size:.82rem !important;color:var(--gris-clair) !important}

.vp-retour form{margin:0;flex-shrink:0}

@media (max-width:640px){
  .vp-retour{flex-direction:column;align-items:flex-start;gap:14px}
  .vp-retour form,.vp-retour .vp-button{width:100%}
}
/* Le bouton d'engagement respire : collé au texte explicatif, il
   s'atteint avant d'avoir été lu. */
.vp-form-confirmer{margin-top:26px}
/* Un crédit se distingue d'un débit : le même chiffre en noir laisserait
   croire à un prélèvement. */
.vp-credit{color:var(--vert)}
/* Le badge est une action secondaire : discrète, mais qui se colore
   quand il est actif — le client voit d'un coup d'œil lesquels de ses
   domaines l'affichent. */
/* Le badge actif doit se voir dans une ligne qui porte déjà un nom, un
   score, une date et deux autres boutons. Une nuance de couleur s'y
   perd : il faut un fond. */
.vp-domaine-badge{
  display:inline-flex;align-items:center;justify-content:center;
  width:30px;height:30px;border-radius:8px;
  background:none;border:1px solid transparent;padding:0;cursor:pointer;
  color:var(--gris-clair);font-size:.82rem;
  transition:color .15s, background .15s, border-color .15s;
}
.vp-domaine-badge:hover{
  color:var(--acier);background:var(--brume);border-color:var(--ligne);
}

.vp-domaine-badge.is-actif{
  color:#fff;
  background:var(--acier);
  border-color:var(--acier);
}
.vp-domaine-badge.is-actif:hover{
  background:var(--ardoise);border-color:var(--ardoise);color:#fff;
}

/* ---------- Paramétrage du badge ---------- */

.vp-badge-domaine{
  font-family:'IBM Plex Mono',monospace;font-size:.8rem;font-weight:400;
  color:var(--acier);margin-left:10px;
}

.vp-badge-apercus{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
  gap:12px;margin:0 0 24px;
}

.vp-badge-choix{
  display:flex;flex-direction:column;align-items:center;gap:10px;
  padding:16px 12px;cursor:pointer;
  background:var(--blanc);border:1.5px solid var(--ligne);border-radius:12px;
  transition:border-color .15s, background .15s;
}
.vp-badge-choix:hover{border-color:#c5d5e5}
.vp-badge-choix.is-choisi{border-color:var(--acier);background:var(--faisceau-pale)}

/* La vignette sombre reçoit un fond clair, sinon le badge sombre se
   confondrait avec la carte qui le présente. */
.vp-badge-vignette{
  display:flex;align-items:center;justify-content:center;
  min-height:56px;padding:4px;border-radius:8px;
}
.vp-badge-vignette.is-sombre{background:var(--brume)}
.vp-badge-vignette img{display:block;max-width:100%;height:auto}

.vp-badge-nom{
  font-family:'IBM Plex Mono',monospace;font-size:.66rem;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--gris-clair);
}
.vp-badge-choix.is-choisi .vp-badge-nom{color:var(--acier)}

.vp-badge-code{
  font-family:'IBM Plex Mono',monospace !important;
  font-size:.76rem !important;line-height:1.6;
  background:var(--brume) !important;color:var(--gris) !important;
  resize:none;
}

.vp-badge-actions{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:10px;
}
.vp-badge-actions .vp-button{width:auto}

.vp-badge-compteur{
  margin:20px 0 0;padding-top:16px;border-top:1px solid var(--ligne);
  font-size:.82rem;color:var(--gris-clair);
}
.vp-badge-compteur i{color:var(--acier);margin-right:6px}
.vp-badge-compteur strong{color:var(--encre)}

/* Les cases du badge portent une explication : le libellé seul ne dit
   pas ce que le visiteur verra. */
#modalBadge .vp-field-check label{align-items:flex-start}
#modalBadge .vp-field-check span{line-height:1.5}

/* L'activation commande tout le reste : elle se place en tête et
   n'est pas une option parmi d'autres. */
.vp-badge-interrupteur{
  background:var(--brume);border:1.5px solid var(--ligne);
  border-radius:12px;padding:16px 20px;margin:0 0 22px;
  transition:border-color .2s, background .2s;
}
.vp-badge-interrupteur.is-actif{
  background:var(--vert-bg);border-color:var(--vert-ligne);
}

.vp-badge-interrupteur label{
  display:flex;align-items:center;gap:16px;cursor:pointer;margin:0;
}
.vp-badge-interrupteur input{position:absolute;opacity:0;pointer-events:none}

.vp-badge-bascule{
  flex-shrink:0;position:relative;
  width:46px;height:26px;border-radius:13px;
  background:var(--ligne);transition:background .2s;
}
.vp-badge-bascule::after{
  content:"";position:absolute;top:3px;left:3px;
  width:20px;height:20px;border-radius:50%;background:#fff;
  box-shadow:0 1px 3px rgba(8,26,46,.25);
  transition:transform .2s;
}
.vp-badge-interrupteur.is-actif .vp-badge-bascule{background:var(--vert)}
.vp-badge-interrupteur.is-actif .vp-badge-bascule::after{transform:translateX(20px)}

.vp-badge-etat-texte strong{display:block;font-size:.94rem;color:var(--nuit)}
.vp-badge-etat-texte span{font-size:.82rem;color:var(--gris);line-height:1.5}

/* Désactivé, tout reste visible mais inerte : le client voit ce qu'il
   obtiendrait sans pouvoir agir à moitié. */
.vp-badge-zone{transition:opacity .2s}
.vp-badge-zone.is-inactif{opacity:.45;pointer-events:none}

/* Même forme que le bloc PDF : les deux actions s'alignent avec les
   scores plutôt que d'occuper une ligne à elles seules. */
.vp-run-suppr-bloc{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  min-width:88px;padding:16px 18px;
  background:var(--blanc);border:1.5px dashed var(--ligne);border-radius:10px;
  color:var(--gris-clair);cursor:pointer;
  transition:border-color .15s, background .15s, color .15s;
}
.vp-run-suppr-bloc:hover{
  border-color:var(--rouge);background:var(--rouge-bg);color:var(--rouge);
}
.vp-run-suppr-bloc i{font-size:1.4rem;margin-bottom:8px}
.vp-run-suppr-bloc span{
  font-family:'IBM Plex Mono',monospace;font-size:.64rem;font-weight:600;
  letter-spacing:.12em;text-transform:uppercase;
}
/* ---------- Échéances ----------
   Une date qui approche ne se lit pas dans un score. Le module reste
   affiché même quand tout va bien : l'absence d'échéance proche est
   une information rassurante, pas un vide à masquer. */

/* --- Tout va bien --- */

.vp-echeances-ok{
  display:flex;align-items:center;gap:20px;
  height:100%;padding:8px 4px;
}

.vp-echeances-ok-ico{
  flex-shrink:0;
  width:56px;height:56px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--vert-bg);color:var(--vert);font-size:1.5rem;
}

.vp-echeances-ok-titre{
  display:block;font-family:'Archivo',sans-serif;font-weight:800;
  font-size:1.05rem;color:var(--vert);margin-bottom:5px;
}

.vp-echeances-ok p{
  margin:0;font-size:.88rem;color:var(--gris);line-height:1.55;max-width:62ch;
}

/* --- Une échéance approche --- */

.vp-echeances{list-style:none;margin:0;padding:0;display:grid;gap:10px}

.vp-echeance{
  display:flex;align-items:stretch;gap:18px;
  background:var(--blanc);border:1px solid var(--ligne);
  border-left:3px solid var(--gris-clair);
  border-radius:0 10px 10px 0;padding:14px 18px;
}

/* Le compte à rebours porte la gravité : c'est le nombre qu'on lit en
   premier, pas le libellé. */
.vp-echeance-compte{
  flex-shrink:0;width:74px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding-right:18px;border-right:1px solid var(--ligne);
}

.vp-echeance-n{
  font-family:'Archivo',sans-serif;font-weight:800;font-size:1.9rem;
  line-height:1;color:var(--gris);
}

.vp-echeance-u{
  font-family:'IBM Plex Mono',monospace;font-size:.6rem;font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;color:var(--gris-clair);
  margin-top:5px;text-align:center;line-height:1.3;
}

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

.vp-echeance-titre{
  font-family:'Archivo',sans-serif;font-weight:800;font-size:.96rem;
  color:var(--nuit);
}

.vp-echeance-date{
  font-family:'IBM Plex Mono',monospace;font-size:.76rem;color:var(--gris);
}

.vp-echeance-consigne{
  font-size:.84rem;color:var(--gris);line-height:1.5;margin-top:3px;
}

/* La date peut avoir plusieurs semaines entre deux analyses. Le dire
   vaut mieux que de laisser croire à une surveillance continue. */
.vp-echeance-constat{
  font-size:.74rem;color:var(--gris-clair);line-height:1.45;
  margin-top:6px;padding-top:6px;border-top:1px dashed var(--ligne);
}

/* --- Les trois niveaux --- */

.vp-echeance.is-proche{
  border-left-color:var(--ambre);
  background:linear-gradient(90deg, var(--ambre-bg), var(--blanc) 60%);
}
.vp-echeance.is-proche .vp-echeance-n{color:var(--ambre)}

.vp-echeance.is-critique{
  border-left-color:var(--rouge);
  background:linear-gradient(90deg, var(--rouge-bg), var(--blanc) 60%);
}
.vp-echeance.is-critique .vp-echeance-n{color:var(--rouge)}
.vp-echeance.is-critique .vp-echeance-titre{color:var(--rouge)}

/* Une échéance dépassée n'est plus un avertissement mais un constat :
   le fond plein le dit sans détour. */
.vp-echeance.is-expire{
  border-color:var(--rouge);border-left-color:var(--rouge);
  background:var(--rouge-bg);
}
.vp-echeance.is-expire .vp-echeance-n,
.vp-echeance.is-expire .vp-echeance-titre{color:var(--rouge)}
.vp-echeance.is-expire .vp-echeance-compte{border-right-color:#f2c9c6}

@media (max-width:640px){
  .vp-echeances-ok{flex-direction:column;text-align:center;gap:14px}

  .vp-echeance{gap:14px;padding:12px 14px}
  .vp-echeance-compte{width:60px;padding-right:14px}
  .vp-echeance-n{font-size:1.5rem}
}

/* ---------- Alerte d'échéance ---------- */

.vp-modal-alerte .modal-body{padding:32px 34px 24px;text-align:center}

.vp-alerte-ico{
  width:66px;height:66px;border-radius:50%;margin:0 auto 20px;
  display:flex;align-items:center;justify-content:center;
  background:var(--rouge-bg);color:var(--rouge);font-size:1.8rem;
}

.vp-alerte-titre{
  font-family:'Archivo',sans-serif;font-weight:800;font-size:1.2rem;
  color:var(--nuit);margin:0 0 20px;line-height:1.3;
}

.vp-alerte-liste{
  list-style:none;margin:0 0 20px;padding:0;display:grid;gap:8px;
  text-align:left;
}

.vp-alerte-liste li{
  padding:12px 16px;
  background:var(--rouge-bg);border:1px solid #f2c9c6;
  border-left:3px solid var(--rouge);border-radius:0 8px 8px 0;
}

.vp-alerte-domaine{
  display:block;font-family:'IBM Plex Mono',monospace;
  font-size:.86rem;font-weight:600;color:var(--nuit);
}

.vp-alerte-quoi{
  display:block;font-size:.82rem;color:#7a2520;margin-top:2px;
}
.vp-alerte-quoi strong{color:var(--rouge)}

.vp-alerte-consigne{
  margin:0 0 14px;font-size:.9rem;color:var(--gris);line-height:1.55;
  text-align:left;
}

.vp-alerte-note{
  margin:0;padding-top:14px;border-top:1px solid var(--ligne);
  font-size:.8rem;color:var(--gris-clair);line-height:1.5;text-align:left;
}

.vp-modal-alerte .modal-footer{justify-content:center;border-top:0;padding-top:0}
.vp-modal-alerte .modal-footer .vp-button{min-width:180px}

/* ---------- Échéances dans le détail d'une analyse ----------
   De l'information la plupart du temps, une alerte quand la date
   approche. Le contraste suit l'urgence : discret par défaut, il ne
   doit pas concurrencer les scores. */

.vp-run-echeances{
  display:flex;gap:12px;flex-wrap:wrap;margin:0 0 24px;
}

.vp-run-echeance{
  display:flex;align-items:baseline;gap:12px;
  padding:10px 16px;
  background:var(--brume);border:1px solid var(--ligne);
  border-radius:8px;
}

.vp-run-echeance-label{
  font-family:'IBM Plex Mono',monospace;font-size:.64rem;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--gris-clair);
}

.vp-run-echeance-date{
  font-family:'IBM Plex Mono',monospace;font-size:.86rem;font-weight:600;
  color:var(--encre);
}

.vp-run-echeance-reste{font-size:.78rem;color:var(--gris-clair)}

/* --- Quand la date approche --- */

.vp-run-echeance.is-proche{
  background:var(--ambre-bg);border-color:var(--ambre-ligne);
  border-left:3px solid var(--ambre);
}
.vp-run-echeance.is-proche .vp-run-echeance-label,
.vp-run-echeance.is-proche .vp-run-echeance-reste{color:var(--ambre)}
.vp-run-echeance.is-proche .vp-run-echeance-date{color:#7a4a12}

.vp-run-echeance.is-critique,
.vp-run-echeance.is-expire{
  background:var(--rouge-bg);border-color:#f2c9c6;
  border-left:3px solid var(--rouge);
}
.vp-run-echeance.is-critique .vp-run-echeance-label,
.vp-run-echeance.is-critique .vp-run-echeance-reste,
.vp-run-echeance.is-critique .vp-run-echeance-date,
.vp-run-echeance.is-expire .vp-run-echeance-label,
.vp-run-echeance.is-expire .vp-run-echeance-reste,
.vp-run-echeance.is-expire .vp-run-echeance-date{color:var(--rouge)}

.vp-run-echeance.is-expire{border-color:var(--rouge)}

@media (max-width:640px){
  .vp-run-echeance{width:100%;justify-content:space-between}
}
/* La ligne mène à sa dernière analyse : le curseur le dit avant le
   clic, et un léger relief au survol confirme qu'il se passera
   quelque chose. */
.vp-domaine.is-cliquable{cursor:pointer}
.vp-domaine.is-cliquable:hover{border-color:var(--acier)}

/* Le compteur d'affichages est ce qui donne envie de garder le badge :
   il se lit dès l'ouverture, pas en pied de fenêtre. */
.vp-badge-interrupteur{
  display:flex;align-items:center;justify-content:space-between;gap:20px;
}
.vp-badge-interrupteur label{flex:1;min-width:0}

.vp-badge-vues{
  flex-shrink:0;text-align:right;padding-left:20px;
  border-left:1px solid var(--ligne);
}

.vp-badge-vues-n{
  display:block;font-family:'Archivo',sans-serif;font-weight:800;
  font-size:1.5rem;color:var(--nuit);line-height:1;
}
.vp-badge-vues-l{
  font-family:'IBM Plex Mono',monospace;font-size:.6rem;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--gris-clair);
}

.vp-badge-interrupteur.is-actif .vp-badge-vues-n{color:var(--vert)}
.vp-badge-interrupteur.is-actif .vp-badge-vues{border-left-color:var(--vert-ligne)}

@media (max-width:560px){
  .vp-badge-interrupteur{flex-direction:column;align-items:stretch;gap:14px}
  .vp-badge-vues{
    padding-left:0;padding-top:14px;text-align:left;
    border-left:0;border-top:1px solid var(--ligne);
  }
}

/* Le badge se rappelle discrètement : c'est une information sur le
   domaine, pas sur l'analyse qu'on est venu lire. */
.vp-run-badge{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;
  padding:11px 16px;margin:0 0 20px;
  background:var(--faisceau-pale);border:1px solid #b9dcf2;
  border-radius:8px;font-size:.84rem;color:var(--ardoise);
}
.vp-run-badge i{color:var(--acier)}
.vp-run-badge-texte{flex:1;min-width:180px}
.vp-run-badge-texte strong{color:var(--nuit)}
.vp-run-badge-lien{font-size:.8rem;white-space:nowrap}