/*
 * Tokens de la charte Frennly — docs/charte.md.
 *
 * Le thème sombre est la référence : ses valeurs sont celles du :root de
 * frennly.com, reprises telles quelles. Le thème clair en est dérivé.
 * Aucune couleur n'est écrite ailleurs que dans ce fichier.
 */

/* ------------------------------------------------------------------ *
 * Le trait des bordures Tailwind
 *
 * Tailwind tourne ici SANS préflight — décision du point 02, pour qu'il ne
 * réécrive pas la typographie et les marges de la charte. Or c'est le préflight
 * qui pose « border-style: solid » sur tous les éléments, et l'utilitaire
 * « border » ne règle QUE l'épaisseur : sans lui, un `border border-bordure`
 * calcule une bordure d'un pixel, de la bonne couleur, et de style « none » —
 * donc invisible. Toutes les pastilles de formats et de systèmes, le contour des
 * cartes et le filet sous les en-têtes de tableau étaient ainsi sans trait.
 *
 * Ces deux déclarations sont exactement la règle de bordure du préflight, et
 * rien d'autre. Les deux vont ensemble : « solid » seul ferait calculer
 * l'épaisseur par défaut — « medium », soit trois pixels — à chaque élément de la
 * page. La feuille de Tailwind est injectée APRÈS celle-ci, et ses utilitaires
 * reprennent donc la main sur l'épaisseur, côté par côté.
 *
 * La couleur n'est pas touchée : « currentColor » est déjà la valeur initiale, et
 * les rares bordures sans classe de couleur du portail la reçoivent par « :class ».
 * ------------------------------------------------------------------ */

*,
::before,
::after {
  border-width: 0;
  border-style: solid;
}

/* ------------------------------------------------------------------ *
 * Thème sombre — valeurs par défaut
 * ------------------------------------------------------------------ */

:root,
:root[data-theme="sombre"] {
  --couleur-fond: #0F0F0F;
  --couleur-surface: #1A1A1A;
  --couleur-surface-2: #1C1C21;
  --couleur-surface-3: #1F1F1F;

  --couleur-bordure: #262626;
  --couleur-bordure-2: #232329;
  --couleur-bordure-3: #333333;

  --couleur-texte: #B3B3B2;
  --couleur-texte-fort: #FFFFFF;
  --couleur-texte-discret: #676665;
  --couleur-texte-nav: #81807E;

  /* Vert : action primaire, état « en ligne », traitement IA. Jamais en texte. */
  --couleur-accent: #00FF00;
  --couleur-sur-accent: #000000;

  /*
   * L'accent en halo, pour la pastille qui bat pendant un traitement.
   *
   * Il existe parce qu'une variable CSS ne s'interpole pas dans une notation
   * rgba() : « rgba(var(--couleur-accent), 0.35) » ne produit rien. La teinte est
   * donc déclarée une fois, alpha comprise, comme --couleur-surbrillance juste
   * en dessous. À tenir en accord avec --couleur-accent si celui-ci change.
   */
  --couleur-accent-halo: rgba(0, 255, 0, 0.35);

  /* Mint : tout ce qui est technique — coulisses, citations, sous le capot. */
  --couleur-technique: #9EFFE8;

  /*
   * Le faisceau du schéma des connecteurs, moitié « avec connecteur ». Sur fond
   * noir c'est l'accent lui-même ; en clair il devient le mint assombri, le vert
   * pur disparaissant sur blanc à cette épaisseur de trait. Un jeton plutôt qu'une
   * classe dupliquée : le schéma ne connaît qu'une couleur.
   */
  --couleur-faisceau: #00FF00;

  /* Surbrillance des portions masquées par l'anonymisation (démonstration). */
  --couleur-surbrillance: rgba(158, 255, 232, 0.16);
  --couleur-surbrillance-bordure: rgba(158, 255, 232, 0.45);

  /* Alerte : erreur d'appel, service injoignable. */
  --couleur-alerte: #E5484D;

  /*
   * Vigilance : une faute qui coûte moins cher que l'alerte. Sur les relevés du viseur,
   * elle porte la carte manquée — Frennly rapproche la carte et le viseur reprend —,
   * quand le rouge porte le faux positif, qui envoie une photo devant le prospect.
   */
  --couleur-vigilance: #F5B942;

  /* Texte accentué et liens : le vert n'est pas lisible en texte. */
  --couleur-lien: #9EFFE8;
  --couleur-lien-survol: #00FF00;

  /*
   * Aplat de signature — moitié gauche de l'écran de connexion. En sombre c'est
   * le fond du portail ; en clair c'est un navy, sinon les deux moitiés seraient
   * deux blancs. Les trois valeurs « sur-signature » sont les tirages du texte
   * qui se pose dessus, et non de nouvelles couleurs de la charte.
   */
  --couleur-signature: #0F0F0F;
  --couleur-sur-signature: #FFFFFF;
  --couleur-sur-signature-texte: #B3B3B2;
  --couleur-sur-signature-icone: #81807E;
  --couleur-sur-signature-discret: #676665;

  /* Fond des champs de saisie : en creux du panneau qui les porte. */
  --couleur-champ-fond: #0F0F0F;

  /*
   * Voiles de modale — tiroir Coulisses et barre globale.
   *
   * Ils restent sombres dans les deux registres : un voile qui éclaircirait la page
   * ne se lirait pas comme une mise en retrait. Mais ils sont déclarés par thème,
   * et non une fois pour les deux, parce que le même noir n'y produit pas le même
   * effet — mesuré le 2026-09-03 : 45 % de noir ôte 7 niveaux au fond sombre et
   * 110 au fond clair. Le jour où Frennly veut adoucir le clair, c'est une ligne.
   *
   * Deux poids : le voile ordinaire laisse la page derrière lisible — c'est le
   * tiroir, où l'écran commenté reste le sujet ; le voile fort prend l'écran, pour
   * la barre globale qui attend une saisie.
   */
  --couleur-voile: rgba(0, 0, 0, 0.45);
  --couleur-voile-fort: rgba(0, 0, 0, 0.62);

  --ombre-flottant: 0 12px 32px rgba(0, 0, 0, 0.6);
  --ombre-tiroir: -24px 0 60px rgba(0, 0, 0, 0.55);

  color-scheme: dark;
}

/* ------------------------------------------------------------------ *
 * Thème clair — dérivé du sombre, validé le 2026-09-01
 *
 * Le vert #00FF00 n'est conservé qu'en aplat, avec du texte noir dessus
 * (bouton d'envoi, pastille d'état). En texte sur blanc il est illisible :
 * les liens et le texte accentué passent en navy.
 * ------------------------------------------------------------------ */

:root[data-theme="clair"] {
  --couleur-fond: #F2F3F5;
  --couleur-surface: #FFFFFF;
  --couleur-surface-2: #F7F8FA;
  --couleur-surface-3: #EDEFF2;

  --couleur-bordure: #E5E7EB;
  --couleur-bordure-2: #E9EBEF;
  --couleur-bordure-3: #D8DCE2;

  --couleur-texte: #3A3A3A;
  --couleur-texte-fort: #112337;
  --couleur-texte-discret: #686E77;
  --couleur-texte-nav: #686E77;

  --couleur-accent: #00FF00;
  --couleur-sur-accent: #000000;

  /*
   * Même halo qu'en sombre : la pastille qu'il entoure est le même vert dans les
   * deux registres, un halo assombri ne serait plus le sien. Il porte moins sur
   * fond clair que sur fond noir — à revoir avec Frennly si la pastille ne se voit
   * pas assez en vidéoprojection.
   */
  --couleur-accent-halo: rgba(0, 255, 0, 0.35);

  /* Le mint disparaît sur blanc : même rôle, teinte assombrie. */
  --couleur-technique: #0E7C6B;

  /* Le vert pur ne se voit pas en trait de 1,2 px sur blanc : le faisceau prend le mint assombri. */
  --couleur-faisceau: #0E7C6B;

  /* Surbrillance des portions masquées, lisible sur fond clair. */
  --couleur-surbrillance: rgba(14, 124, 107, 0.14);
  --couleur-surbrillance-bordure: rgba(14, 124, 107, 0.40);

  --couleur-alerte: #C42B30;

  /* Descendu en clair : l'ambre du sombre passe pour du jaune pâle sur fond blanc. */
  --couleur-vigilance: #A66A00;

  --couleur-lien: #112337;
  --couleur-lien-survol: #204CE5;

  /*
   * Navy validé le 2026-09-01. Les libellés posés dessus sont des blancs
   * atténués : les gris de la charte disparaîtraient sur ce fond.
   */
  --couleur-signature: #112337;
  --couleur-sur-signature: #FFFFFF;
  --couleur-sur-signature-texte: rgba(255, 255, 255, 0.88);
  --couleur-sur-signature-icone: rgba(255, 255, 255, 0.55);
  --couleur-sur-signature-discret: rgba(255, 255, 255, 0.45);

  /* En clair le champ ne se creuse pas : c'est sa bordure qui le dessine. */
  --couleur-champ-fond: #FFFFFF;

  /*
   * Voiles repris à l'identique du sombre — un voile reste un voile —, mais leur
   * effet est bien plus marqué ici (voir la mesure notée dans le bloc sombre) :
   * c'est le seul endroit à toucher pour l'adoucir, et rien d'autre ne bougera.
   */
  --couleur-voile: rgba(0, 0, 0, 0.45);
  --couleur-voile-fort: rgba(0, 0, 0, 0.62);

  --ombre-flottant: 0 12px 32px rgba(17, 35, 55, 0.18);
  --ombre-tiroir: -24px 0 60px rgba(17, 35, 55, 0.16);

  color-scheme: light;
}

/* ------------------------------------------------------------------ *
 * Marque blanche — /auto-diagnostic-white, point 18c
 *
 * Une couche de MARQUE posée sur un registre de couleur, et non un
 * troisième registre : la page est en data-theme="clair" comme une autre,
 * et data-variante n'ôte que l'accent de Frennly. C'est ce qui garde le
 * widget anti-robot monté en « light » — auto-diagnostic.js lit data-theme,
 * et une troisième valeur l'aurait peint en sombre sur une page claire, sur
 * le seul élément que le prospect est obligé de cliquer.
 *
 * CE BLOC DOIT RESTER ÉCRIT APRÈS LE REGISTRE CLAIR. Les deux sélecteurs
 * ont la même spécificité : à égalité, c'est l'ordre qui tranche.
 *
 * Trois tokens suffisent, et c'est un relevé, pas une estimation : ce sont
 * les seules variables de marque qu'atteignent cet écran et son viseur de
 * carte de visite. L'ambre du point de vigilance et le rouge d'alerte
 * restent — ils ne disent aucune marque.
 *
 * Les valeurs sont relevées sur le bouton de mon-score-ia.fr, le site qui
 * relaie ce formulaire : le visiteur ne doit pas sentir qu'il a changé de
 * domaine.
 * ------------------------------------------------------------------ */

:root[data-variante="neutre"] {
  --couleur-accent: #16544B;
  --couleur-sur-accent: #EFF1EE;
  --couleur-accent-halo: rgba(22, 84, 75, 0.35);
}

/* ------------------------------------------------------------------ *
 * Rayons, typographie
 * ------------------------------------------------------------------ */

:root {
  --rayon-champ: 10px;
  --rayon-bouton: 12px;
  --rayon-carte: 14px;
  --rayon-bloc: 16px;
  --rayon-cta: 20px;
  --rayon-section: 24px;
  --rayon-pilule: 100px;

  --police-titre: "Jost", "Century Gothic", Futura, system-ui, sans-serif;
  --police-texte: "Roboto Flex", "Helvetica Neue", Arial, system-ui, sans-serif;
  --police-mono: "Roboto Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --police-nav: "Ubuntu", "Segoe UI", system-ui, sans-serif;
}

/* ------------------------------------------------------------------ *
 * Base
 * ------------------------------------------------------------------ */

* {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  background: var(--couleur-fond);
  color: var(--couleur-texte);
  font-family: var(--police-texte);
  -webkit-font-smoothing: antialiased;
}

/*
 * La transition ne s'applique qu'après le premier rendu : sans cela, la bascule
 * de thème appliquée avant peinture provoquerait un fondu au chargement.
 */
body.transitions-actives,
body.transitions-actives * {
  transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}

.titre {
  font-family: var(--police-titre);
}

.mono {
  font-family: var(--police-mono);
}

.nav {
  font-family: var(--police-nav);
}

a {
  color: var(--couleur-lien);
  text-decoration: none;
}

a:hover {
  color: var(--couleur-lien-survol);
}

svg {
  display: block;
}

/*
 * Filet : aucune image ne sort de son contenant. Les écrans posent déjà « w-full »
 * là où il faut, mais ces classes viennent de Tailwind — et le jour où Tailwind
 * manque, la capture du canevas reprenait sa taille naturelle et poussait la page à
 * 1 400 px de large sur un téléphone. Mesuré le 2026-09-04, JavaScript coupé.
 */
img {
  max-width: 100%;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

:focus-visible {
  outline: 2px solid var(--couleur-accent);
  outline-offset: 2px;
}

/* Masque les éléments Alpine.js tant que le composant n'est pas initialisé. */
[x-cloak] {
  display: none !important;
}

/* ------------------------------------------------------------------ *
 * Navigation latérale
 * ------------------------------------------------------------------ */

/*
 * La marque renvoie a l'accueil : elle reste discrete au repos, et ne se signale
 * comme cliquable qu'au survol, avec le meme fond que les entrees de navigation.
 */
.marque-lien {
  transition: background-color 120ms ease;
}

.marque-lien:hover {
  background: var(--couleur-surface);
}

.entree-nav {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  height: 44px;
  padding: 0 12px;
  border-radius: var(--rayon-bouton);
  color: var(--couleur-texte-nav);
  font-family: var(--police-nav);
  font-size: 14.5px;
}

.entree-nav:hover {
  background: var(--couleur-surface);
  color: var(--couleur-texte-fort);
}

.entree-nav--active {
  background: var(--couleur-surface);
  color: var(--couleur-texte-fort);
}

.entree-nav--active::before {
  content: "";
  position: absolute;
  left: 0;
  top: 12px;
  bottom: 12px;
  width: 2px;
  border-radius: 2px;
  background: var(--couleur-accent);
}

/*
 * Module pas encore livre : l'entree reste un lien, elle mene a un ecran
 * d'attente. Seule l'opacite dit qu'elle est en retrait ; lui retirer le survol
 * la ferait passer pour morte alors qu'elle est cliquable.
 */
.entree-nav--inactive {
  opacity: 0.55;
}

/*
 * Entree rangee sous une autre. Le retrait cale son icone sous le LIBELLE du
 * parent (12 px de retrait + 19 px d'icone + 11 px d'ecart), la seule position
 * ou le rang se lit sans trait de guidage : le filet vertical est deja pris par
 * l'ecran courant, et deux filets a gauche se liraient l'un pour l'autre.
 * La ligne est aussi plus basse et un demi-point plus petite, pour que le
 * groupe se lise comme un bloc et non comme deux entrees de meme rang.
 */
.entree-nav--sous {
  height: 38px;
  padding-left: 42px;
  font-size: 14px;
}

/*
 * Sous-menu : masqué par défaut, il se déplie au survol du groupe — un simple
 * pointeur, disponible dès qu'un appareil a une souris — et le bouton en fait
 * de même au clic, seul recours d'un écran tactile qui n'a pas de survol à
 * donner. `groupe-entree--ouverte` porte les deux : Alpine la pose au clic, et
 * elle vaut aussi pour l'ouverture par défaut d'un groupe dont une sous-entrée
 * est l'écran courant.
 */
.groupe-entree__ligne {
  display: flex;
  align-items: center;
  gap: 2px;
}

.groupe-entree__ligne .entree-nav {
  flex: 1 1 auto;
  min-width: 0;
}

.groupe-entree__bouton {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: var(--rayon-bouton);
  color: var(--couleur-texte-discret);
}

.groupe-entree__bouton:hover {
  background: var(--couleur-surface);
  color: var(--couleur-texte-fort);
}

.groupe-entree__bouton svg {
  transition: transform 120ms ease;
}

.groupe-entree__sous {
  display: none;
  flex-direction: column;
  gap: 3px;
}

.groupe-entree--ouverte .groupe-entree__sous {
  display: flex;
}

.groupe-entree--ouverte .groupe-entree__bouton svg {
  transform: rotate(180deg);
}

@media (hover: hover) {
  .groupe-entree:hover .groupe-entree__sous,
  .groupe-entree:focus-within .groupe-entree__sous {
    display: flex;
  }

  .groupe-entree:hover .groupe-entree__bouton svg,
  .groupe-entree:focus-within .groupe-entree__bouton svg {
    transform: rotate(180deg);
  }
}

.groupe-nav {
  font-family: var(--police-nav);
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--couleur-texte-discret);
  padding: 20px 12px 8px;
}

.compteur-nav {
  font-family: var(--police-mono);
  font-size: 11px;
  color: var(--couleur-texte-discret);
  background: var(--couleur-surface);
  border: 1px solid var(--couleur-bordure);
  border-radius: var(--rayon-pilule);
  padding: 2px 8px;
}

/* ------------------------------------------------------------------ *
 * Boutons de l'en-tête
 * ------------------------------------------------------------------ */

.bouton-entete {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  height: 40px;
  padding: 0 12px;
  flex: none;
  border: 1px solid var(--couleur-bordure);
  background: var(--couleur-surface);
  border-radius: var(--rayon-bouton);
  color: var(--couleur-texte);
}

.bouton-entete:hover {
  border-color: var(--couleur-bordure-3);
  color: var(--couleur-texte-fort);
}

.bouton-entete--carre {
  width: 40px;
  padding: 0;
}

/* Pastille verte : l'écran courant expose des informations techniques. */
.pastille-coulisses {
  position: absolute;
  top: -4px;
  right: -4px;
  width: 9px;
  height: 9px;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-accent);
  box-shadow: 0 0 0 3px var(--couleur-fond);
}

/* ------------------------------------------------------------------ *
 * Coque des petits écrans — téléphone et tablette portrait
 * ------------------------------------------------------------------ */

/*
 * Le portail est bâti comme une application : une barre latérale de 244 px, un
 * en-tête, et un contenu qui défile seul dans une coque en « overflow: hidden ».
 * Sur un téléphone de 390 px, cette barre mangeait 244 px et il en restait 146
 * pour le contenu — qui n'était pas repoussé mais ROGNÉ par la coque, donc perdu
 * sans même une barre de défilement pour le signaler. Mesuré le 2026-09-04 :
 * 428 px de contenu coupés sur l'accueil du module Plateforme.
 *
 * Sous 900 px, la barre latérale sort donc du flux et devient un tiroir. Le seuil
 * est celui de l'écran de connexion, plus bas dans ce fichier : le portail n'a
 * aucune raison d'avoir deux ruptures. À 901 px il reste 657 px de contenu, ce
 * qui tient ; à 900 px le tiroir en rend 900.
 *
 * Deux mises en page, et non une :
 *
 * - SANS JavaScript, la barre reste dans le flux et passe en bandeau au-dessus du
 *   contenu. C'est moins élégant, mais la navigation reste atteignable — alors
 *   qu'un tiroir sans son bouton l'aurait rendue inaccessible. Le portail prend
 *   déjà cette précaution pour Tailwind, pour Alpine et pour le sélecteur de
 *   registre ; le jour où le réseau d'un client bloque les deux CDN, on perd la
 *   bascule de thème, pas le menu.
 *
 * - AVEC JavaScript — classe « js » posée par le script en ligne du gabarit, que
 *   nul blocage de CDN ne peut atteindre —, la barre devient un tiroir ouvert par
 *   le bouton de l'en-tête.
 *
 * Les sélecteurs portent « html:not(.js) » et « .js » plutôt qu'une classe seule :
 * Tailwind injecte sa feuille APRÈS celle-ci, et à spécificité égale c'est lui qui
 * l'emporterait sur « h-full » et « overflow-hidden ». Deux classes suffisent à
 * reprendre la main.
 */

/* Hors petit écran, la barre est déjà là : le bouton n'a rien à ouvrir. */
.bouton-navigation {
  display: none;
}

@media (max-width: 900px) {

  /* Repli sans JavaScript : la coque s'empile, la barre devient un bandeau. */
  html:not(.js) .coque-portail {
    flex-direction: column;
    height: auto;
    min-height: 100%;
    overflow: visible;
  }

  html:not(.js) .barre-laterale {
    width: 100%;
    border-right: 0;
    border-bottom: 1px solid var(--couleur-bordure);
  }

  /* Mise en page servie dans tous les autres cas : le tiroir. */
  .js .bouton-navigation {
    display: flex;
  }

  /*
   * L'en-tête reste au-dessus du tiroir, et le tiroir commence sous lui.
   *
   * Un tiroir pleine hauteur, celui de la première version, recouvrait le bouton
   * qui venait de l'ouvrir : la croix de fermeture était peinte derrière, et il ne
   * restait que le clic sur le voile pour refermer — un geste qui se devine, ce
   * qu'on ne demande pas à quelqu'un qui présente le portail devant un client. Ici
   * la croix reste visible, avec la bascule de thème et les Coulisses.
   *
   * Le décalage vaut la hauteur de l'en-tête, « h-16 » de Tailwind, soit 64 px.
   * L'en-tête doit être positionné pour que z-index le concerne : sans « relative »,
   * un élément « fixed » lui passerait devant quelle que soit la valeur.
   */
  .js .entete-portail {
    position: relative;
    z-index: 46;
  }

  .js .barre-laterale {
    position: fixed;
    top: 64px;
    left: 0;
    bottom: 0;
    z-index: 45;
    /*
     * 262 px plutôt que 244 : hors du flux, la barre n'enlève plus rien au contenu,
     * et deux lignes de libellé — « Plateforme d'automatisation » — tiennent mieux.
     * Le plafond en vw laisse voir le contenu derrière, ce qui dit que le tiroir
     * est un calque et non un écran de plus.
     */
    width: 262px;
    max-width: 84vw;
    border-right: 1px solid var(--couleur-bordure-3);
    box-shadow: var(--ombre-tiroir);
    transform: translateX(-100%);
    /*
     * « visibility » et pas seulement « transform ». Une barre simplement décalée
     * hors de l'écran reste dans l'ordre de tabulation et dans l'arbre
     * d'accessibilité : la première pression sur Tab partait sur une quinzaine de
     * liens invisibles — la barre PRÉCÈDE l'en-tête dans le document —, et un lecteur
     * d'écran énonçait toute la navigation pendant que le bouton venait d'annoncer
     * « aria-expanded="false" ». Les deux autres panneaux du portail, le tiroir
     * Coulisses et la palette, se ferment par x-show, donc par « display: none » :
     * celui-ci n'avait aucune raison de faire autrement.
     *
     * Le délai de 180 ms sur « visibility » la laisse visible le temps que le tiroir
     * finisse de sortir de l'écran ; sans lui, il disparaîtrait d'un coup au lieu de
     * glisser. La transition est redonnée sur l'état déplié, sans délai cette fois :
     * à l'ouverture, la barre doit être visible tout de suite.
     */
    visibility: hidden;
    transition: transform 180ms ease, visibility 0s 180ms;
  }

  .js .barre-laterale--depliee {
    transform: none;
    visibility: visible;
    transition: transform 180ms ease, visibility 0s 0s;
  }

  /* Le voile s'arrête lui aussi sous l'en-tête, qui reste net et cliquable. */
  .voile-navigation {
    position: fixed;
    top: 64px;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 44;
    background: var(--couleur-voile);
  }

  /*
   * L'en-tête se resserre : 26 px de chaque côté sur 390 px de large, c'est un
   * septième de l'écran donné à du vide.
   *
   * DEUX classes, et non « .entete-portail » seul : la vue porte « px-[26px] », que
   * Tailwind rend avec la même spécificité et dans une feuille injectée APRÈS
   * celle-ci. Écrite avec un sélecteur simple, la règle ne s'appliquait pas — sans
   * rien casser, ce qui est exactement ce qui la rendait difficile à voir.
   */
  .coque-portail .entete-portail {
    padding-left: 14px;
    padding-right: 14px;
  }

  /*
   * Une réserve au bas de la zone de défilement, pour la pastille de l'assistant.
   * Elle flotte en bas à droite sur tous les écrans ; sur un grand écran elle
   * survole une marge, sur un téléphone elle recouvrait la dernière ligne de la
   * page — constaté sur l'accueil du module Plateforme, où elle masquait la phrase
   * d'exemple. La réserve vaut la pastille, 56 px, plus son écart au bord.
   *
   * Elle se pose sur l'élément qui défile VRAIMENT, écran par écran, et non sur
   * « main » comme jusqu'au 2026-09-14. La plupart des écrans tiennent leur propre
   * hauteur avec « h-full », c'est à dire 100 % de la boîte de CONTENU de main : une
   * marge basse posée là leur retirait 84 px, si bien que l'écran s'arrêtait au-dessus
   * du bord — une bande morte en bas, et la dernière ligne coupée au lieu de défiler.
   * C'est ce que montraient l'accueil et la liste des assistants sur téléphone.
   *
   * DEUX classes pour la même raison que l'en-tête ci-dessus : les vues portent déjà
   * « pb-10 » ou « pb-[26px] », que Tailwind rend avec la même spécificité dans une
   * feuille injectée après celle-ci.
   */
  .coque-portail .reserve-pastille {
    padding-bottom: 84px;
  }
}

/*
 * Au-delà du seuil, le voile n'a plus rien à couvrir. La règle est nécessaire même
 * si app.js referme le tiroir au franchissement : entre le redimensionnement et
 * l'exécution du script, le voile resterait peint en travers de l'écran.
 */
@media (min-width: 901px) {
  .voile-navigation {
    display: none !important;
  }
}

/* Un tiroir qui glisse n'apporte rien à qui a demandé moins de mouvement. */
@media (prefers-reduced-motion: reduce) {
  .js .barre-laterale {
    transition: none;
  }
}

/*
 * Bandeau qui se fait glisser — employé par le schéma « ce qu'est une automatisation »
 * du module Plateforme.
 *
 * Un dessin large ne peut pas être mis à l'échelle indéfiniment : ramené à 320 px, le
 * schéma affichait ses libellés en cinq pixels de haut. Il garde donc sa taille et se
 * fait glisser du doigt. Restait à le dire, sans écrire « faites glisser » sous chaque
 * dessin : ce sont les quatre dégradés ci-dessous.
 *
 * Les deux premiers sont attachés au CONTENU (« local ») : ils suivent le défilement
 * et viennent recouvrir l'ombre du bord qu'on vient d'atteindre. Les deux derniers
 * sont attachés au CADRE (« scroll ») : ils restent collés aux bords. Résultat, une
 * ombre n'apparaît que du côté où il reste quelque chose à voir — et rien du tout
 * quand le dessin tient en entier. Aucune ligne de JavaScript, et donc aucune mesure
 * à refaire au redimensionnement.
 *
 * L'ordre des couches compte : en CSS, la première image de fond est peinte AU-DESSUS
 * des suivantes. Les masques viennent donc avant les ombres.
 *
 * Les masques restent OPAQUES sur leurs douze premiers pixels avant de s'éteindre, et
 * l'ombre n'en fait que neuf. Un masque qui se dégraderait dès le bord ne couvrirait
 * l'ombre qu'aux deux tiers, et il en restait un liseré visible sur grand écran, là où
 * il n'y a précisément rien à faire glisser — relevé à la capture du 2026-09-04.
 */
.bandeau-glissant {
  overflow-x: auto;
  background-image:
    linear-gradient(to right, var(--couleur-surface) 12px, transparent 30px),
    linear-gradient(to left, var(--couleur-surface) 12px, transparent 30px),
    linear-gradient(to right, var(--couleur-bordure-3), transparent),
    linear-gradient(to left, var(--couleur-bordure-3), transparent);
  background-position: left center, right center, left center, right center;
  background-size: 30px 100%, 30px 100%, 9px 100%, 9px 100%;
  background-repeat: no-repeat;
  background-attachment: local, local, scroll, scroll;
}

/* ------------------------------------------------------------------ *
 * Panneau Coulisses
 * ------------------------------------------------------------------ */

.voile-coulisses {
  position: fixed;
  inset: 0;
  background: var(--couleur-voile);
  z-index: 40;
}

.tiroir-coulisses {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 460px;
  max-width: 92vw;
  z-index: 50;
  display: flex;
  flex-direction: column;
  background: var(--couleur-surface);
  border-left: 1px solid var(--couleur-bordure-3);
  box-shadow: var(--ombre-tiroir);
}

.ligne-coulisses {
  display: flex;
  gap: 14px;
  padding: 10px 0;
  border-bottom: 1px solid var(--couleur-bordure);
  font-size: 13px;
}

.ligne-coulisses dt {
  flex: none;
  width: 118px;
  color: var(--couleur-texte-discret);
}

.ligne-coulisses dd {
  margin: 0;
  flex: 1;
  min-width: 0;
  color: var(--couleur-texte);
  overflow-wrap: anywhere;
}

.valeur-technique {
  font-family: var(--police-mono);
  font-size: 12px;
  color: var(--couleur-technique);
}

.titre-coulisses {
  font-family: var(--police-nav);
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--couleur-texte-discret);
  margin: 24px 0 6px;
}

/* ------------------------------------------------------------------ *
 * Blocs communs aux écrans
 * ------------------------------------------------------------------ */

.carte {
  background: var(--couleur-surface);
  border: 1px solid var(--couleur-bordure);
  border-radius: var(--rayon-carte);
}

/*
 * Dernière tuile de la galerie des cas clients. Elle ne porte pas de réalisation :
 * elle dit que la liste montrée n'est pas la liste complète. Fond transparent et
 * trait pointillé pour qu'elle se lise d'un coup d'oeil comme une fin de liste et
 * non comme une carte de plus.
 *
 * Le trait s'écrit ici plutôt qu'en classes Tailwind : preflight est désactivé dans
 * la configuration du layout, et « border » seul n'y pose aucun style de trait.
 */
.carte-suite {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 190px;
  padding: 24px;
  text-align: center;
  background: transparent;
  border: 1px dashed var(--couleur-bordure-3);
  border-radius: var(--rayon-carte);
  color: var(--couleur-texte-discret);
}

/*
 * La tuile est un lien vers les réalisations du site Frennly. Comme la carte d'outil,
 * elle fixe sa couleur au survol : sans cette règle, « a:hover » l'emporterait et la
 * ferait virer au vert d'accent, qui ne se pose jamais en texte. Le trait se fonce
 * d'un cran, assez pour se signaler comme cliquable sans devenir une carte de plus.
 */
.carte-suite:hover,
.carte-suite:focus-visible {
  border-color: var(--couleur-texte-discret);
  color: var(--couleur-texte-fort);
}

.pilule {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--couleur-texte);
  background: var(--couleur-surface);
  border: 1px solid var(--couleur-bordure);
  border-radius: var(--rayon-pilule);
  padding: 8px 15px;
}

.pilule:hover {
  border-color: var(--couleur-bordure-3);
  color: var(--couleur-texte-fort);
}

/*
 * Tronque un texte à deux lignes, points de suite compris. Sert les résumés des
 * cartes de tickets, où une hauteur fixe garde la liste lisible.
 */
.clamp2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/*
 * Surbrillance d'une portion masquée par l'anonymisation. Elle dit, sans le crier,
 * « ceci a été remplacé pour la démonstration » : un fond ténu et un souligné pointillé
 * mint, la même teinte que tout ce qui relève des coulisses. Le texte reste lisible,
 * la couleur ne change pas — c'est un repère, pas une alarme.
 */
.anonymise {
  background: var(--couleur-surbrillance);
  border-bottom: 1px dotted var(--couleur-surbrillance-bordure);
  border-radius: 3px;
  padding: 0 3px;
  color: inherit;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/*
 * Action discrète sur une note ou dans la zone de réponse (Gestion support) :
 * « Corriger et reformuler », « Simplifier ». En retrait, elle ne concurrence pas
 * les deux livrables verts de l'écran.
 */
.action-note {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  padding: 0 11px;
  border-radius: var(--rayon-pilule);
  border: 1px solid var(--couleur-bordure-3);
  background: var(--couleur-surface-3);
  font-size: 12px;
  color: var(--couleur-technique);
}

.etat-ok {
  color: var(--couleur-texte-fort);
}

.point-etat {
  width: 8px;
  height: 8px;
  border-radius: var(--rayon-pilule);
  flex: none;
}

.point-etat--ok {
  background: var(--couleur-accent);
}

.point-etat--ko {
  background: var(--couleur-alerte);
}

.bloc-erreur {
  background: var(--couleur-surface);
  border: 1px solid var(--couleur-alerte);
  border-radius: var(--rayon-carte);
  color: var(--couleur-texte);
}

pre.brut {
  font-family: var(--police-mono);
  font-size: 12px;
  line-height: 1.55;
  color: var(--couleur-technique);
  background: var(--couleur-surface-3);
  border: 1px solid var(--couleur-bordure);
  border-radius: var(--rayon-champ);
  padding: 12px 14px;
  margin: 0;
  max-height: 260px;
  overflow: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* ------------------------------------------------------------------ *
 * Rangée d'outils de l'accueil : carte, picot d'aide, infobulle
 *
 * Le picot n'est ni vert ni mint : le vert est réservé à l'action primaire
 * et à l'état « en ligne », le mint au technique. Une aide n'est ni l'un ni
 * l'autre, elle se tient dans les gris de la charte.
 * ------------------------------------------------------------------ */

/*
 * La rangée elle-même. Elle ne tient sur une seule ligne qu'à partir de 1100 px :
 * en dessous, sept cartes en ligne tombent sous les 50 px de large et leurs
 * libellés se chevauchent. Le nombre de colonnes du grand écran vient de la vue,
 * par « --outils » : la rangée suit le registre sans qu'on retouche cette feuille.
 */
.rangee-outils {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px;
  width: 100%;
  max-width: 1116px;
}

@media (min-width: 640px) {
  .rangee-outils {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 1100px) {
  .rangee-outils {
    grid-template-columns: repeat(var(--outils, 7), minmax(0, 1fr));
  }
}

/*
 * La carte est un lien : sans cette règle elle hériterait de la couleur des
 * liens, et virerait au vert au survol en thème sombre.
 */
.carte-outil {
  color: var(--couleur-texte);
}

.carte-outil:hover,
.carte-outil:focus-visible {
  border-color: var(--couleur-bordure-3);
  color: var(--couleur-texte-fort);
}

/*
 * Le picot est un frère du lien, jamais son enfant : un bouton imbriqué dans un
 * lien serait du HTML invalide, et il doit rester atteignable au clavier.
 * Dimensionné pour se voir en vidéoprojection sans devenir le sujet de l'écran.
 */
.picot-aide {
  position: absolute;
  top: 8px;
  left: 8px;
  width: 19px;
  height: 19px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-pilule);
  background: var(--couleur-surface-3);
  /*
   * Le gris de la navigation, et non celui du texte discret : un vidéoprojecteur
   * délave les noirs, et le disque disparaîtrait derrière son propre fond.
   */
  color: var(--couleur-texte-nav);
  font-family: var(--police-nav);
  font-size: 12px;
  line-height: 1;
}

.picot-aide:hover,
.picot-aide:focus-visible {
  border-color: var(--couleur-texte-discret);
  color: var(--couleur-texte-fort);
}

/*
 * Le même picot, mais posé dans le flux au lieu d'être collé au coin d'une carte :
 * il suit alors un titre, à la façon d'un appel de note.
 */
.picot-aide--en-ligne {
  position: static;
  flex: none;
}

/*
 * Le bénéfice de l'outil, posé au-dessus de la carte — arbitrage du 2026-09-01.
 *
 * D'où la largeur, qui n'est pas décorative : la rangée de cartes est à 76 px des
 * questions proposées, et une infobulle de trois lignes les recouvre. À cette
 * largeur la plus longue des sept phrases en tient deux, et rien n'est masqué.
 * C'est le chiffre à revoir si les textes s'allongent.
 *
 * Elle déborde sur les cartes voisines : c'est voulu, une carte est trop
 * étroite pour porter une phrase.
 */
.infobulle {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  z-index: 30;
  width: max-content;
  max-width: min(380px, calc(100vw - 80px));
  transform: translateX(-50%);
  padding: 11px 13px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-carte);
  background: var(--couleur-surface);
  box-shadow: var(--ombre-flottant);
  color: var(--couleur-texte);
  font-size: 12.5px;
  line-height: 18px;
  text-align: left;
}

/* Aux deux extrémités de la rangée, centrée, elle sortirait de l'écran. */
.infobulle--debut {
  left: 0;
  transform: none;
}

.infobulle--fin {
  left: auto;
  right: 0;
  transform: none;
}

/*
 * Le bec. Un carré tourné dont on ne garde que les deux arêtes tournées vers la
 * carte : les deux autres passeraient un trait au milieu de l'infobulle.
 */
.infobulle::after {
  content: "";
  position: absolute;
  bottom: -5px;
  left: 50%;
  width: 9px;
  height: 9px;
  margin-left: -5px;
  border-right: 1px solid var(--couleur-bordure-3);
  border-bottom: 1px solid var(--couleur-bordure-3);
  background: var(--couleur-surface);
  transform: rotate(45deg);
}

.infobulle--debut::after {
  left: 18px;
  margin-left: 0;
}

.infobulle--fin::after {
  left: auto;
  right: 18px;
  margin-left: 0;
}

/*
 * Le même calage, mais rendu à la grille. Tant que la rangée est une ligne, la vue
 * sait laquelle des cartes est la première et laquelle est la dernière, et pose
 * elle-même « --debut » et « --fin ». Repliée en grille, ce n'est plus la position
 * dans le registre qui compte mais la colonne : la carte de gauche cale son
 * infobulle à gauche, celle de droite à droite, celle du milieu reste centrée.
 * Sans cela, l'infobulle d'une carte de bord sort de l'écran par le côté.
 */
@media (max-width: 639px) {
  .rangee-outils > *:nth-child(odd) .infobulle {
    left: 0;
    right: auto;
    transform: none;
  }

  .rangee-outils > *:nth-child(odd) .infobulle::after {
    left: 18px;
    right: auto;
    margin-left: 0;
  }

  .rangee-outils > *:nth-child(even) .infobulle {
    left: auto;
    right: 0;
    transform: none;
  }

  .rangee-outils > *:nth-child(even) .infobulle::after {
    left: auto;
    right: 18px;
    margin-left: 0;
  }
}

@media (min-width: 640px) and (max-width: 1099px) {
  .rangee-outils > *:nth-child(3n + 1) .infobulle {
    left: 0;
    right: auto;
    transform: none;
  }

  .rangee-outils > *:nth-child(3n + 1) .infobulle::after {
    left: 18px;
    right: auto;
    margin-left: 0;
  }

  .rangee-outils > *:nth-child(3n + 2) .infobulle {
    left: 50%;
    right: auto;
    transform: translateX(-50%);
  }

  .rangee-outils > *:nth-child(3n + 2) .infobulle::after {
    left: 50%;
    right: auto;
    margin-left: -5px;
  }

  .rangee-outils > *:nth-child(3n) .infobulle {
    left: auto;
    right: 0;
    transform: none;
  }

  .rangee-outils > *:nth-child(3n) .infobulle::after {
    left: auto;
    right: 18px;
    margin-left: 0;
  }
}

/*
 * Ouverture vers le bas, pour un picot posé en haut d'écran : au-dessus, l'infobulle
 * chevaucherait l'en-tête et sortirait de la fenêtre. Le bec passe donc en haut.
 */
.infobulle--bas {
  top: calc(100% + 10px);
  bottom: auto;
}

.infobulle--bas::after {
  top: -5px;
  bottom: auto;
  border-right: 0;
  border-bottom: 0;
  border-top: 1px solid var(--couleur-bordure-3);
  border-left: 1px solid var(--couleur-bordure-3);
}

/* ------------------------------------------------------------------ *
 * Estimation du gain : pastille et encart de calcul (point 17)
 *
 * La pastille prend la place de « Gain constaté : [À CHIFFRER] » sur la
 * rangée de pastilles d'une fiche d'outil. Elle est donc taillée sur ses
 * voisines — même hauteur, même graisse, même gris — à une différence près,
 * qui est la seule qu'on veuille : elle porte un vrai trait, parce que c'est
 * la seule de la rangée sur laquelle on clique. Ses voisines sont peintes
 * par des utilitaires Tailwind, qui ne posent aucun trait ici : le portail
 * tourne sans preflight, « border » n'y règle qu'une épaisseur, et le style
 * reste à « none ». D'où ces classes complètes plutôt que des utilitaires.
 *
 * Ni vert ni mint, comme le picot du 04b : le vert est réservé à l'action
 * primaire et à l'état « en ligne », le mint au technique. Un calcul
 * d'estimation n'est ni l'un ni l'autre.
 * ------------------------------------------------------------------ */

.pastille-estimation {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-pilule);
  background: var(--couleur-surface-3);
  /*
   * Le gris de la navigation, et non celui du texte discret : un
   * vidéoprojecteur délave les noirs, et la pastille disparaîtrait derrière
   * son propre fond. Même raison qu'au picot du 04b.
   */
  color: var(--couleur-texte-nav);
  font-family: var(--police-mono);
  font-size: 11px;
  line-height: 1.4;
}

.pastille-estimation:hover,
.pastille-estimation:focus-visible {
  border-color: var(--couleur-texte-discret);
  color: var(--couleur-texte-fort);
}

/* Le repli sans JavaScript : un chiffre figé, donc rien qui invite au clic. */
.pastille-estimation--figee {
  color: var(--couleur-texte-discret);
  cursor: default;
}

/*
 * L'encart s'ouvre VERS LE BAS. La rangée de pastilles est à mi-carte, et une
 * carte d'automatisation peut être la première d'une liste qui commence sous
 * l'en-tête : ouvert vers le haut, l'encart chevaucherait la barre de titre.
 */
.encart-estimation {
  position: absolute;
  top: calc(100% + 9px);
  left: 0;
  z-index: 30;
  width: 320px;
  max-width: min(320px, calc(100vw - 64px));
  padding: 15px 16px 13px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-carte);
  background: var(--couleur-surface);
  box-shadow: var(--ombre-flottant);
  text-align: left;
}

/* Le bec, repris de l'infobulle du 04b : deux arêtes d'un carré tourné. */
.encart-estimation::after {
  content: "";
  position: absolute;
  top: -5px;
  left: 22px;
  width: 9px;
  height: 9px;
  border-top: 1px solid var(--couleur-bordure-3);
  border-left: 1px solid var(--couleur-bordure-3);
  background: var(--couleur-surface);
  transform: rotate(45deg);
}

/*
 * L'encart accroché par sa DROITE, pour une pastille posée en bout de ligne.
 *
 * Ce n'est pas une variante de goût : la pastille est poussée à droite sur cinq des
 * sept écrans porteurs — ligne de titre de la Recherche IA, de la fiche de devis, de
 * la carte de visite, en-tête d'un agent, et sous le champ de la Gestion support.
 * Ancré à gauche comme sur une vitrine, l'encart sortait alors de la fenêtre et se
 * faisait couper en deux : vu à la capture du 2026-09-09, sur l'écran du support.
 *
 * Le côté est déclaré par l'appelant et non devine ici : c'est l'écran qui sait où il
 * pose sa pastille, et une bascule au chargement ferait sauter l'encart sous les yeux
 * du prospect.
 */
.encart-estimation--fin {
  left: auto;
  right: 0;
}

.encart-estimation--fin::after {
  left: auto;
  right: 22px;
}

/*
 * La tâche remplacée. C'est la phrase que le prospect doit reconnaître comme
 * la sienne : elle est donc en tête, et dans la couleur forte.
 */
.encart-estimation__tache {
  margin: 0 0 15px;
  color: var(--couleur-texte-fort);
  font-family: var(--police-nav);
  font-size: 13px;
  line-height: 1.4;
}

.curseur-estimation {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 0 10px;
  margin-bottom: 13px;
}

.curseur-estimation__intitule {
  color: var(--couleur-texte-discret);
  font-size: 11.5px;
  line-height: 1.3;
}

.curseur-estimation__valeur {
  color: var(--couleur-texte-fort);
  font-size: 12px;
  text-align: right;
  white-space: nowrap;
}

/*
 * La glissière. « appearance: none » enlève le rendu du système, y compris la
 * piste : c'est donc le fond de l'élément qui la peint, et le curseur est
 * dessiné à part pour chacun des deux moteurs — il n'existe aucun sélecteur
 * commun à WebKit et Gecko pour cette poignée.
 */
.curseur-estimation__glissiere {
  grid-column: 1 / -1;
  width: 100%;
  height: 4px;
  margin: 9px 0 0;
  padding: 0;
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-bordure-3);
  cursor: pointer;
}

/*
 * La poignée est le seul élément vert de l'encart, et c'est cohérent avec la
 * charte : c'est la commande qu'on manipule, donc l'action primaire de ce
 * panneau. Dimensionnée pour se saisir à la souris en vidéoprojection.
 */
.curseur-estimation__glissiere::-webkit-slider-thumb {
  appearance: none;
  -webkit-appearance: none;
  width: 15px;
  height: 15px;
  border: 0;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-accent);
}

.curseur-estimation__glissiere::-moz-range-thumb {
  width: 15px;
  height: 15px;
  border: 0;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-accent);
}

/*
 * Les deux lignes de résultat, séparées des curseurs par un trait : c'est ce
 * qui distingue ce qu'on règle de ce qu'on lit.
 */
.encart-estimation__resultat {
  margin: 0;
  color: var(--couleur-texte);
  font-size: 13px;
  line-height: 1.7;
}

.encart-estimation__resultat:first-of-type {
  margin-top: 14px;
  padding-top: 13px;
  border-top: 1px solid var(--couleur-bordure);
}

.encart-estimation__nombre {
  color: var(--couleur-texte-fort);
  font-family: var(--police-titre);
  font-size: 17px;
  letter-spacing: -0.2px;
}

/*
 * Le coût horaire, replié. Il ne change pas d'un outil à l'autre : le
 * déplier une fois suffit pour le rendez-vous entier, l'onglet le retient.
 */
.encart-estimation__pied {
  margin-top: 13px;
  padding-top: 12px;
  border-top: 1px solid var(--couleur-bordure);
}

.encart-estimation__reglage {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--couleur-texte-discret);
  font-size: 11.5px;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 3px;
}

.encart-estimation__reglage:hover,
.encart-estimation__reglage:focus-visible {
  color: var(--couleur-texte-fort);
}

.encart-estimation__champ {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-top: 9px;
}

.encart-estimation__champ span {
  color: var(--couleur-texte-discret);
  font-size: 11.5px;
}

.encart-estimation__champ input {
  width: 72px;
  padding: 5px 8px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-champ);
  background: var(--couleur-champ-fond);
  color: var(--couleur-texte-fort);
  font-size: 12px;
}

/*
 * La ligne qui dit ce que l'encart n'est pas. Elle n'est pas une précaution
 * d'avocat : le portail ne possède aucun gain mesuré, et la seule façon
 * honnête d'afficher un chiffre est de dire d'où il vient. Elle reste donc à
 * l'écran, sous le résultat, et ne se replie pas.
 */
.encart-estimation__cadre {
  margin: 12px 0 0;
  color: var(--couleur-texte-discret);
  font-size: 11px;
  line-height: 1.45;
}

/* ------------------------------------------------------------------ *
 * Écran de connexion
 *
 * Le seul écran rendu hors du gabarit : ni barre latérale, ni en-tête, ni
 * panneau Coulisses. Il se passe donc aussi de Tailwind, d'où des classes
 * complètes ici plutôt que des utilitaires dans la vue.
 * ------------------------------------------------------------------ */

.ecran-connexion {
  height: 100%;
  display: flex;
  background: var(--couleur-surface);
}

.aplat-signature {
  width: 640px;
  flex: none;
  display: flex;
  flex-direction: column;
  padding: 44px 56px;
  background: var(--couleur-signature);
  /*
   * Même liseré que la barre latérale du portail. Il n'est pas décoratif : en
   * thème sombre, #0F0F0F et #1A1A1A ne se distinguent pas sur un
   * vidéoprojecteur, qui délave les noirs, et l'écran scindé n'en serait plus un.
   */
  border-right: 1px solid var(--couleur-bordure);
}

.aplat-signature__marque {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}

.marque-sous-titre {
  font-size: 10px;
  letter-spacing: 0.9px;
  text-transform: uppercase;
  color: var(--couleur-sur-signature-discret);
}

/*
 * Ce que contient le portail. Volontairement sans pastille ni survol : la liste
 * ne doit pas se lire comme une navigation, on n'est pas encore entré.
 */
.contenu-portail {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 26px;
}

.groupe-portail__titre {
  margin-bottom: 14px;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--couleur-sur-signature-discret);
}

.groupe-portail__entrees {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.entree-portail {
  display: flex;
  align-items: center;
  gap: 16px;
  font-size: 15px;
  color: var(--couleur-sur-signature-texte);
}

.entree-portail svg {
  color: var(--couleur-sur-signature-icone);
}

.panneau-connexion {
  flex: 1;
  min-width: 0;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
  background: var(--couleur-surface);
}

.bouton-theme {
  position: absolute;
  top: 26px;
  right: 26px;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-bouton);
  background: var(--couleur-surface-3);
  color: var(--couleur-texte);
}

.bouton-theme:hover {
  color: var(--couleur-texte-fort);
}

/* L'icône suit le thème en CSS : aucun clignotement au chargement. */
:root[data-theme="clair"] .icone-theme--sombre,
:root[data-theme="sombre"] .icone-theme--clair {
  display: none;
}

/* Le mot-symbole de la marque suit le même principe : deux fichiers, jamais un filtre. */
:root[data-theme="clair"] .marque-mot--sombre,
:root[data-theme="sombre"] .marque-mot--clair {
  display: none;
}

/*
 * Le formulaire portait « l'ombre de formulaire » de la charte,
 * 10px 10px 50px rgba(0, 98, 255, 0.03) — un bleu qui n'appartient à aucune des deux
 * palettes et ne porte aucun jeton. Retirée le 2026-09-03, après mesure : elle
 * déplace le fond d'un seul niveau sur 255, en clair comme en sombre, c'est-à-dire
 * rien de visible, et moins que rien en vidéoprojection.
 *
 * Elle n'y était pas à sa place : sur frennly.com cette ombre porte une carte, alors
 * qu'ici le formulaire n'a pas de fond — il se pose à même le panneau. Y mettre
 * --ombre-flottant ne serait pas mieux : on verrait l'ombre d'une carte absente.
 * Si Frennly veut ce halo de marque à la connexion, il faut d'abord donner une
 * surface au formulaire ; c'est une décision de maquette, pas de jeton.
 */
.formulaire-connexion {
  width: 364px;
  max-width: 100%;
  display: flex;
  flex-direction: column;
}

.titre-connexion {
  margin: 0 0 26px;
  font-size: 28px;
  font-weight: 300;
  letter-spacing: -0.2px;
  color: var(--couleur-texte-fort);
}

.champs-connexion {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.champ-connexion {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.champ-connexion__libelle {
  font-size: 13px;
  color: var(--couleur-texte);
}

.champ-connexion__saisie {
  height: 50px;
  padding: 0 16px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-champ);
  background: var(--couleur-champ-fond);
  color: var(--couleur-texte-fort);
  font-family: var(--police-texte);
  font-size: 15px;
}

.champ-connexion__saisie:focus {
  border-color: var(--couleur-texte-discret);
  outline: none;
}

/*
 * Le vert du portail est conservé comme marque de focus, mais posé à l'intérieur
 * du champ : le liseré par défaut, décalé de 2 px, doublait la bordure et le
 * champ au premier plan se lisait comme une alerte.
 */
.champ-connexion__saisie:focus-visible {
  border-color: var(--couleur-accent);
  outline: 2px solid var(--couleur-accent);
  outline-offset: -1px;
}

.bouton-primaire {
  height: 50px;
  margin-top: 26px;
  border-radius: var(--rayon-bouton);
  background: var(--couleur-accent);
  color: var(--couleur-sur-accent);
  font-size: 15px;
  font-weight: 500;
}

.bouton-primaire:hover {
  filter: brightness(0.94);
}

.bande-erreur {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: -6px 0 20px;
  padding: 13px 15px;
  border: 1px solid var(--couleur-alerte);
  border-radius: var(--rayon-carte);
  background: var(--couleur-surface-3);
  font-size: 13px;
  line-height: 1.45;
  color: var(--couleur-texte);
}

.bande-erreur__icone {
  flex: none;
  color: var(--couleur-alerte);
}

/*
 * Sous 900 px l'aplat passe au-dessus du formulaire et perd la liste : sur un
 * téléphone, sept libellés avant le champ de saisie repousseraient la connexion
 * hors de l'écran.
 */
@media (max-width: 900px) {
  .ecran-connexion {
    flex-direction: column;
  }

  .aplat-signature {
    width: auto;
    flex: none;
    gap: 0;
    padding: 26px;
  }

  .contenu-portail {
    display: none;
  }

  .panneau-connexion {
    flex: 1;
    padding: 26px;
    align-items: flex-start;
  }

  .bouton-theme {
    position: fixed;
    top: 22px;
    right: 22px;
  }
}

/* ------------------------------------------------------------------ */
/* Recherche vectorielle — point 05                                    */
/* ------------------------------------------------------------------ */

/*
 * Le champ de la page dédiée. Il portait « bg-surface border border-bordure-3 » en
 * classes Tailwind, et son trait ne se peignait donc pas : sans le preflight de
 * Tailwind, « border » ne pose qu'une épaisseur, jamais un style de trait. Relevé le
 * 2026-09-09 en habillant l'écran d'ouverture, où le champ se retrouvait sans contour
 * juste au-dessus d'un schéma qui, lui, en avait un.
 */
.champ-recherche {
  background: var(--couleur-surface);
  border: 1px solid var(--couleur-bordure-3);
}

/*
 * Le titre d'un résultat est un lien, et la règle a:hover de la charte l'emporterait
 * sur une classe utilitaire : il porte donc sa propre couleur. Enseignement du point
 * 04b, où trois éléments avaient viré au vert en devenant des liens.
 */
.lien-resultat {
  color: var(--couleur-texte-fort);
  font-size: 17px;
  line-height: 1.3;
  display: block;
}

.lien-resultat:hover {
  color: var(--couleur-texte-fort);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.lien-resultat--faible {
  color: var(--couleur-texte);
}

.lien-resultat--faible:hover {
  color: var(--couleur-texte);
}

/* Origine du document : registre technique de la charte, jamais le vert. */
.puce-origine {
  font-family: var(--police-nav);
  font-size: 10px;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  color: var(--couleur-technique);
  border: 1px solid var(--couleur-bordure);
  border-radius: var(--rayon-pilule);
  padding: 3px 9px;
  white-space: nowrap;
}

/*
 * Mention « correspondance faible ». Volontairement discrète et dans les gris : ce
 * n'est ni une erreur, ni une alerte — c'est une précaution de lecture.
 */
.puce-faible {
  font-size: 11px;
  color: var(--couleur-texte-discret);
  border: 1px solid var(--couleur-bordure);
  border-radius: var(--rayon-pilule);
  padding: 3px 9px;
  white-space: nowrap;
}

/* Filet du passage déclencheur : mint, l'extrait étant une citation du corpus. */
.filet-passage {
  width: 2px;
  flex: none;
  border-radius: 2px;
  background: var(--couleur-technique);
  opacity: 0.55;
}

.filet-passage--faible {
  background: var(--couleur-bordure-3);
  opacity: 1;
}

.titre-passages {
  font-family: var(--police-nav);
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--couleur-texte-discret);
}

.bouton-passages {
  font-size: 12px;
  color: var(--couleur-texte-discret);
}

.bouton-passages:hover {
  color: var(--couleur-texte-fort);
}

/* ------------------------------------------------------------------ */
/* Barre globale (Ctrl+K)                                              */
/* ------------------------------------------------------------------ */

.voile-palette {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--couleur-voile-fort);
}

.palette {
  position: fixed;
  top: 92px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 61;
  width: min(760px, calc(100vw - 40px));
  max-height: calc(100vh - 160px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--couleur-surface);
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-cta);
  /*
   * L'ombre du portail, comme l'infobulle et le panneau de l'assistant : la palette
   * est un contenant flottant de plus, elle n'a pas de raison d'avoir la sienne.
   * L'ombre écrite ici en dur était un noir fixe, invisible en thème sombre et non
   * teintée en clair, alors que le voile fort détache déjà franchement la palette.
   */
  box-shadow: var(--ombre-flottant);
}

/*
 * Filet de progression. La recherche part au fil de la frappe et le webhook répond
 * en 0,9 à 2,0 s : cet état est le plus souvent visible de l'écran, il est donc
 * peint franchement plutôt que caché. Vert, registre du traitement IA en cours.
 */
.progression-palette {
  height: 2px;
  flex: none;
  background: var(--couleur-bordure);
  overflow: hidden;
}

.progression-palette__barre {
  display: block;
  height: 100%;
  width: 38%;
  background: var(--couleur-accent);
  animation: progression-palette 1.1s ease-in-out infinite;
}

@keyframes progression-palette {
  0% {
    transform: translateX(-100%);
  }

  100% {
    transform: translateX(340%);
  }
}

/*
 * Le même filet, posé sous le champ de la page dédiée. La recherche vectorielle
 * met une à deux secondes : sans témoin, la page reste figée après le clic et, en
 * rendez-vous, on croit au clic manqué. Un seul vocabulaire d'attente pour la
 * barre globale et pour la page.
 */
.progression-recherche {
  margin-top: 10px;
  border-radius: var(--rayon-pilule);
}

/*
 * Pendant l'attente, les résultats de la recherche précédente s'estompent : ils
 * restent lisibles — on ne vide pas un écran devant un prospect — mais ils cessent
 * de se faire passer pour la réponse à la question qui vient d'être posée.
 */
.resultats-en-vol {
  opacity: 0.5;
  transition: opacity 140ms ease-out;
}

/*
 * L'infobulle de la méthode d'évaluation. Plus fournie que celle d'un bénéfice
 * d'outil — une phrase, quatre lignes de barème, une phrase — d'où la largeur et
 * l'interligne repris du corps de texte plutôt que de la puce.
 */
.infobulle--evaluation {
  width: 360px;
  max-width: min(360px, calc(100vw - 80px));
  padding: 13px 15px;
  line-height: 17px;
}

.ligne-bareme {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  padding: 4px 0;
  border-bottom: 1px solid var(--couleur-bordure);
}

.ligne-bareme:last-child {
  border-bottom: 0;
}

.ligne-bareme dt {
  color: var(--couleur-texte-discret);
}

.champ-palette {
  flex: 1;
  min-width: 0;
  font-size: 16.5px;
  color: var(--couleur-texte-fort);
  background: transparent;
  border: 0;
  outline: none;
}

.champ-palette::placeholder {
  color: var(--couleur-texte-discret);
}

/*
 * Les résultats de la frappe précédente restent affichés pendant qu'un appel est en
 * vol, mais atténués : la liste ne doit pas se lire comme la réponse à ce qui est en
 * train d'être tapé. Arbitré le 2026-09-01.
 */
.resultats-palette--en-vol {
  opacity: 0.55;
}

.ligne-palette {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 11px 22px;
  text-align: left;
  color: var(--couleur-texte);
}

.ligne-palette:hover,
.ligne-palette:focus-visible {
  background: var(--couleur-surface-3);
  color: var(--couleur-texte-fort);
}

.ligne-palette__titre {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 14.5px;
}

@media (prefers-reduced-motion: reduce) {
  .progression-palette__barre {
    animation: none;
    width: 100%;
    opacity: 0.6;
  }
}

/*
 * La bande d'erreur de la connexion, réutilisée au milieu d'un écran : sa marge
 * négative était calée sur le formulaire de connexion, elle n'a pas de sens ailleurs.
 */
.bande-erreur--ecran {
  margin: 0;
  align-items: flex-start;
}

/*
 * Attente de l'assistant, écran de complétion de devis.
 *
 * Une pastille figée ne dit pas la même chose qu'une pastille qui bat : pendant les
 * quarante secondes d'analyse, le prospect doit voir que la machine travaille, sans
 * quoi il croit l'écran bloqué. Les deux animations s'arrêtent si le poste demande
 * de réduire les animations.
 */
.points-attente {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.points-attente span {
  width: 5px;
  height: 5px;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-accent);
  animation: point-attente 1.05s infinite ease-in-out;
}

.points-attente span:nth-child(2) {
  animation-delay: 0.15s;
}

.points-attente span:nth-child(3) {
  animation-delay: 0.3s;
}

@keyframes point-attente {
  0%, 80%, 100% {
    opacity: 0.25;
    transform: translateY(0);
  }

  40% {
    opacity: 1;
    transform: translateY(-3px);
  }
}

/* Pastille d'état, avec son halo, quand un traitement est en cours. */
.point-travail {
  animation: halo-travail 1.6s infinite ease-out;
}

/*
 * Le halo est l'accent du thème, et non un vert recopié : c'est --couleur-accent-halo
 * qui le porte, déclaré dans les deux registres. Les deux images d'arrivée valent
 * « transparent » plutôt qu'un vert d'alpha nulle : les couleurs s'interpolent en
 * alpha prémultipliée, les deux écritures donnent donc exactement le même fondu, et
 * celle-ci ne redonne pas une troisième fois la teinte de l'accent.
 */
@keyframes halo-travail {
  0% {
    box-shadow: 0 0 0 0 var(--couleur-accent-halo);
  }

  70% {
    box-shadow: 0 0 0 7px transparent;
  }

  100% {
    box-shadow: 0 0 0 0 transparent;
  }
}

/*
 * Barre d'avancement indéterminée : elle sert entre deux lots, quand le workflow
 * travaille sans annoncer de progression.
 */
.barre-indeterminee::after {
  content: "";
  display: block;
  width: 35%;
  height: 100%;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-accent);
  animation: glissement-barre 1.4s infinite ease-in-out;
}

@keyframes glissement-barre {
  0% {
    transform: translateX(-100%);
  }

  100% {
    transform: translateX(340%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .points-attente span,
  .point-travail,
  .barre-indeterminee::after {
    animation: none;
  }

  .points-attente span {
    opacity: 0.6;
  }
}

/* ------------------------------------------------------------------ */
/* Assistant (point 06)                                                */
/* ------------------------------------------------------------------ */

/*
 * Le panneau de la pastille flotte au-dessus d'un écran, sans voile : il doit
 * donc se détacher tout seul. Il reprend pour cela le contenant flottant du
 * portail — surface, liseré marqué, ombre du thème —, comme la palette et les
 * infobulles. Il était auparavant peint en « fond », c'est-à-dire exactement la
 * couleur de la page derrière lui : sur un vidéoprojecteur qui délave les
 * noirs, le panneau disparaissait dans l'écran.
 */
.panneau-assistant {
  background: var(--couleur-surface);
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-bloc);
  box-shadow: var(--ombre-flottant);
}

/*
 * Le champ de saisie se creuse dans le panneau au lieu de s'y fondre : posé en
 * surface sur un panneau de surface, il n'avait plus de bord visible.
 */
.champ-assistant {
  background: var(--couleur-fond);
  border: 1px solid var(--couleur-bordure-3);
}

/*
 * La pastille prend l'ombre du thème plutôt que celle de Tailwind, noire dans
 * les deux modes et donc absente en thème sombre.
 */
.pastille-assistant {
  box-shadow: var(--ombre-flottant);
}

/*
 * La réponse est du Markdown rendu par assistant.js. Le balisage produit est
 * volontairement pauvre — paragraphes, listes, gras, italique, liens —, donc la
 * mise en forme tient ici, en quelques règles, plutôt qu'en classes semées dans
 * le script.
 */
.assistant-reponse p {
  margin: 0 0 12px;
  font-size: 14.5px;
  color: var(--couleur-texte);
  line-height: 1.62;
  text-wrap: pretty;
}

.assistant-reponse p:last-child,
.assistant-reponse ul:last-child {
  margin-bottom: 0;
}

.assistant-reponse .assistant-titre {
  color: var(--couleur-texte-fort);
  font-weight: 500;
}

.assistant-reponse strong {
  color: var(--couleur-texte-fort);
  font-weight: 500;
}

.assistant-reponse em {
  color: var(--couleur-texte-discret);
  font-style: italic;
}

.assistant-reponse a {
  color: var(--couleur-technique);
}

/*
 * L'image d'une réponse — la simulation visuelle rendue par l'agent d'avant-vente.
 * Bornée en largeur ET en hauteur : une image rendue en pleine définition pousserait
 * le texte de la réponse hors de l'écran au moment précis où on la commente.
 */
.assistant-reponse img {
  display: block;
  max-width: 100%;
  max-height: 420px;
  width: auto;
  margin: 4px 0 14px;
  border: 1px solid var(--couleur-bordure);
  border-radius: var(--rayon-carte);
}

.assistant-reponse ul {
  margin: 0 0 14px;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.assistant-reponse li {
  position: relative;
  padding-left: 17px;
  font-size: 14.5px;
  color: var(--couleur-texte);
  line-height: 1.55;
  text-wrap: pretty;
}

/*
 * La puce est dessinée plutôt que laissée au navigateur : list-style place le
 * marqueur hors du flux, et il se décale dès que la ligne passe sur deux lignes.
 */
.assistant-reponse li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 9px;
  width: 4px;
  height: 4px;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-texte-discret);
}

/*
 * Selecteur d'espace de travail, sous le bloc de marque de la barre laterale.
 *
 * Une ligne, jamais un pave : la hauteur d'une entree de navigation au plus, pour
 * qu'il se lise comme une partie de la barre et non comme un encart pose dessus.
 * Aucune icone de destination : dans cette barre, une icone annonce un ecran, et
 * le selecteur n'en est pas un. Le chevron n'annonce pas une destination, il dit
 * un etat ouvert ou ferme.
 *
 * L'etat ferme porte le registre courant : c'est sa seule raison d'etre visible
 * en permanence, et c'est le garde-fou contre le registre herite du prospect
 * precedent.
 */
.selecteur-registre {
  position: relative;
}

.selecteur-registre__resume {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 10px 0 12px;
  border-radius: var(--rayon-bouton);
  border: 1px solid var(--couleur-bordure);
  background: var(--couleur-surface-2);
  color: var(--couleur-texte-nav);
  font-family: var(--police-nav);
  font-size: 13px;
  cursor: pointer;
  list-style: none;
}

/* Le triangle natif de Safari et de Chrome, retire des deux facons qui existent. */
.selecteur-registre__resume::-webkit-details-marker {
  display: none;
}

.selecteur-registre__resume:hover {
  background: var(--couleur-surface-3);
  color: var(--couleur-texte-fort);
}

.selecteur-registre__resume:focus-visible {
  outline: 2px solid var(--couleur-accent);
  outline-offset: 2px;
}

.selecteur-registre__chevron {
  color: var(--couleur-texte-discret);
  transition: transform 120ms ease;
}

.selecteur-registre[open] .selecteur-registre__chevron {
  transform: rotate(180deg);
}

/*
 * La liste RECOUVRE la navigation au lieu de la pousser vers le bas : une barre
 * laterale dont les entrees glissent sous le pouce pendant qu'on choisit est le
 * genre de detail qui se voit en videoprojection.
 */
.selecteur-registre__liste {
  position: absolute;
  z-index: 30;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px;
  border-radius: var(--rayon-bouton);
  border: 1px solid var(--couleur-bordure);
  background: var(--couleur-surface);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.28);
}

.selecteur-registre__choix {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border-radius: 9px;
  text-align: left;
  color: var(--couleur-texte-nav);
  font-family: var(--police-nav);
  font-size: 13px;
  cursor: pointer;
}

.selecteur-registre__choix:hover {
  background: var(--couleur-surface-3);
  color: var(--couleur-texte-fort);
}

.selecteur-registre__choix--courant {
  background: var(--couleur-surface-3);
  color: var(--couleur-texte-fort);
}

/* ------------------------------------------------------------------ */
/* Appareil photo de la carte de visite (point 08b)                    */
/* ------------------------------------------------------------------ */

/*
 * Le flux de la caméra prend l'écran, et le reste du portail disparaît derrière un
 * voile. Ce bloc est le seul du portail qui ne suit pas les deux registres de couleur :
 * un viseur est noir dans les deux thèmes, parce que ce qu'on y regarde est l'image, et
 * qu'un fond clair autour d'elle fausse le jugement du cadrage. Seul l'accent vient du
 * thème — c'est lui qui dit « carte reconnue ».
 */
.voile-appareil {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: rgba(8, 9, 10, 0.94);
}

.panneau-appareil {
  display: flex;
  flex-direction: column;
  gap: 14px;
  width: 100%;
  max-width: 760px;
}

/*
 * L'écran interne pose une colonne de chiffres à côté du flux : le panneau s'élargit
 * d'autant, pour que ce soit la fenêtre et non le relevé qui décide de la taille de
 * l'image. Sur une fenêtre étroite le relevé passe sur l'image et cette largeur ne sert
 * plus — « width: 100% » la borne de toute façon.
 */
.panneau-appareil--sonde {
  max-width: 1020px;
}

/*
 * Le flux et son relevé. Par défaut — téléphone, fenêtre étroite — l'enveloppe ne fait
 * rien d'autre que porter le cadre : c'est le relevé qui vient se poser DESSUS, en
 * surimpression sur le bord droit. Sous les boutons, il aurait fallu faire défiler pour
 * le voir, et on regarde la carte en même temps qu'on lit les chiffres.
 */
.scene-appareil {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

/*
 * Le cadre porte les proportions posées par le script — celles du flux, ou trois demis
 * pleine largeur quand le téléphone est tenu debout. Les tracés sont placés en
 * pourcentages du cadre, et le script analyse exactement la bande du flux que le cadre
 * montre : ce qui est peint est ce qui est cherché.
 */
.cadre-appareil {
  --ratio-cadre: 1.3333;
  position: relative;
  margin: 0 auto;
  width: min(100%, calc(var(--ratio-cadre) * 62vh));
  aspect-ratio: var(--ratio-cadre);
  overflow: hidden;
  border-radius: var(--rayon-carte);
  background: #000;
}

/* Les phrases d'état et les boutons, sous le flux — ou à côté sur un téléphone couché. */
.commandes-appareil {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/*
 * La rangée de boutons du viseur. Elle est écrite ici et non en utilitaires Tailwind :
 * les deux écrans publics du scan ne chargent pas Tailwind, et ils restaient avec des
 * boutons collés à gauche et sans espace (relevé le 2026-09-18). La requête paysage plus
 * bas remet cette rangée en colonne, ce qu'elle ne pouvait pas faire sans « display ».
 */
.boutons-appareil {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

/*
 * Un téléphone tenu couché : c'est la tenue que l'écran conseille, elle ne doit pas
 * rogner le flux. Les commandes passent à droite, le flux prend la hauteur qui reste.
 * La borne de hauteur écarte les ordinateurs, dont la fenêtre est toujours couchée.
 */
@media (orientation: landscape) and (max-height: 520px) {
  .panneau-appareil {
    flex-direction: row;
    align-items: center;
    max-width: none;
  }

  .cadre-appareil {
    flex: none;
    margin: 0;
    width: min(64%, calc(var(--ratio-cadre) * (100vh - 32px)));
  }

  /*
   * Quand le cadre est enveloppé, c'est l'enveloppe qui est l'élément du panneau : elle
   * se laisse dimensionner par le cadre, et le cadre se mesure alors sur la fenêtre et
   * non sur elle — sinon chacun attendrait la largeur de l'autre.
   */
  .scene-appareil {
    flex: none;
  }

  .scene-appareil > .cadre-appareil {
    width: min(64vw, calc(var(--ratio-cadre) * (100vh - 32px)));
  }

  .commandes-appareil {
    flex: 1;
    min-width: 0;
  }

  .boutons-appareil {
    flex-direction: column;
    align-items: stretch;
  }
}

.flux-appareil {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/*
 * Le guide du viseur, et l'assombrissement de tout ce qui l'entoure. L'ombre portée de
 * 100vmax est ce qui obscurcit l'extérieur sans un second élément : elle est découpée
 * par le « overflow: hidden » du cadre.
 *
 * Il est FIXE depuis le 2026-09-11 — le même retrait de 7 % que cadreDeRecherche dans
 * scan-carte.js. Frennly : « montrer les contours dynamiquement sur la photo ne sert à
 * rien ». Il ne dit donc pas où la carte est, il dit ce que la reconnaissance en voit,
 * par sa couleur : pointillés discrets tant que rien n'est trouvé, trait blanc plein
 * quand une carte est vue, accent quand elle ne bouge plus et que la photo va se
 * prendre. La transition ne porte que sur la couleur.
 */
.cadre-carte {
  position: absolute;
  inset: 7%;
  border: 2px solid rgba(255, 255, 255, 0.86);
  border-radius: 10px;
  box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.5);
  transition: border-color 120ms linear, box-shadow 120ms linear;
}

.cadre-carte--recherche {
  border-style: dashed;
  border-color: rgba(255, 255, 255, 0.4);
  box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.28);
}

.cadre-carte--suivi {
  border-color: rgba(255, 255, 255, 0.95);
}

.cadre-carte--vue {
  border-color: var(--couleur-accent);
  border-width: 3px;
}

.etat-appareil {
  margin: 0;
  text-align: center;
  color: rgba(255, 255, 255, 0.92);
  font-family: var(--police-texte);
  font-size: 14.5px;
  line-height: 1.5;
}

.etat-appareil--vue {
  color: var(--couleur-accent);
}

/* Le conseil de tenue : il précède l'état et se distingue de lui. */
.etat-appareil--conseil {
  color: var(--couleur-accent);
  font-weight: 500;
}

/*
 * La mention de conservation des images du viseur. Elle est due à la personne dont la
 * carte passe devant l'objectif, donc elle reste lisible ; discrète parce qu'elle ne
 * conduit aucun geste, et qu'elle ne doit pas concurrencer la phrase d'état.
 */
.etat-appareil--discret {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.55);
  max-width: 44ch;
  margin-inline: auto;
}

/* La ligne de diagnostic : des chiffres, petits, pour une capture d'écran. */
.etat-appareil--diagnostic {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.6);
  word-break: break-word;
}

/* ------------------------------------------------------------------ */
/* Relevé de la reconnaissance (point 08c), écran interne seulement    */
/* ------------------------------------------------------------------ */

/*
 * Ce que le détecteur voit, pendant qu'il le voit : la taille du flux, le moteur et sa
 * durée, le score de la carte, son côté et sa netteté face aux deux seuils, la rafale
 * en cours. Deux versions du viseur ont été réglées à l'aveugle sur ce que voyait un
 * téléphone ; ces chiffres sont ce qui manquait.
 *
 * Neuf mesures, toujours les neuf, toujours dans le même ordre, jauges comprises — voir
 * RELEVE_MESURES dans html/assets/scan-carte.js. RIEN ne doit apparaître ni disparaître
 * d'un tour à l'autre : c'est un relevé qu'on regarde tourner, et une ligne qui surgit
 * fait redescendre les autres et oblige l'œil à reprendre sa lecture. D'où, ici, une
 * hauteur de ligne fixe et une valeur qui ne passe jamais à la ligne.
 *
 * Il vit dans le viseur, donc en sombre dans les deux thèmes — seul l'accent vient du
 * registre de couleur.
 *
 * Trois mises en page, pour une seule ligne de fabrication : la serrée — libellé à
 * gauche, valeur à droite, jauge posée sur le bas de la ligne — vaut partout, et seul
 * l'endroit où le panneau se pose change. Sur un téléphone tenu debout il est SOUS
 * l'image, en pleine largeur (requête portrait, plus bas) ; dès que la fenêtre est large
 * et haute il quitte l'image et prend une colonne à sa droite, au large, et les lignes
 * s'aèrent. Reste ce bloc-ci, qui sert le téléphone couché : là, la hauteur manque des
 * deux côtés et le relevé se pose en surimpression sur le bord droit de l'image.
 */
.sonde-appareil {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: min(46%, 152px);
  max-height: calc(100% - 12px);
  overflow: hidden;
  padding: 7px 8px 8px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 10px;
  background: rgba(8, 9, 10, 0.66);
  backdrop-filter: blur(7px);
  -webkit-backdrop-filter: blur(7px);
}

/*
 * Le titre ne se peint que dans la colonne : sur l'image, ces dix-sept pixels sont ceux
 * qui feraient tomber la dernière mesure hors du cadre, et le panneau se passe de nom
 * quand il est seul de son espèce.
 */
.sonde-appareil__titre {
  display: none;
  margin: 0;
  color: rgba(255, 255, 255, 0.45);
  font-family: var(--police-nav);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Serré : le libellé à gauche, la valeur à droite, la jauge sous les deux. */
.sonde-mesure {
  position: relative;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
  padding-bottom: 3px;
}

.sonde-mesure__libelle {
  flex: none;
  color: rgba(255, 255, 255, 0.45);
  font-family: var(--police-nav);
  font-size: 9px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/*
 * Les chiffres changent douze fois par seconde : en chasse fixe ET en chiffres de même
 * largeur, sans quoi la valeur danse d'un pixel à chaque tour et devient illisible.
 *
 * Une seule ligne, coupée par des points de suspension si la valeur est longue : une
 * valeur qui passe de une à deux lignes ferait descendre tout ce qui la suit. La ligne
 * à plat du relevé, elle, garde la valeur entière.
 */
.sonde-mesure__valeur {
  flex: 1 1 auto;
  min-width: 0;
  color: rgba(255, 255, 255, 0.94);
  font-size: 12px;
  line-height: 15px;
  height: 15px;
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-variant-numeric: tabular-nums;
}

.sonde-mesure--bon .sonde-mesure__valeur {
  color: var(--couleur-accent);
}

.sonde-mesure--attente .sonde-mesure__valeur {
  color: #f3c677;
}

.sonde-mesure--alerte .sonde-mesure__valeur {
  color: #f08d7c;
}

/*
 * La jauge des quatre mesures qui visent un seuil — score, côté, netteté, rafale. Elle
 * dit d'un coup d'œil s'il s'en faut de peu, ce que deux nombres côte à côte ne disent
 * pas. Pas de transition : la valeur est déjà lissée par le rythme de la boucle, et une
 * animation la ferait traîner derrière ce que le flux montre.
 *
 * Serrée, elle est posée SUR le bas de la ligne et ne lui coûte aucune hauteur.
 */
.sonde-jauge {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: block;
  height: 2px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.16);
  overflow: hidden;
}

.sonde-jauge__part {
  display: block;
  height: 100%;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.55);
}

.sonde-mesure--bon .sonde-jauge__part {
  background: var(--couleur-accent);
}

.sonde-mesure--attente .sonde-jauge__part {
  background: #f3c677;
}

.sonde-mesure--alerte .sonde-jauge__part {
  background: #f08d7c;
}

/*
 * La fenêtre est large et haute : le relevé quitte l'image et prend une colonne à sa
 * droite. Rien ne recouvre plus le flux, une capture d'écran porte les deux, et la
 * place gagnée sert à remettre la valeur sous son libellé, en plus gros. Les deux
 * bornes écartent le téléphone, couché comme debout, qui garde la mise en page serrée.
 */
@media (min-width: 900px) and (min-height: 560px) {
  .scene-appareil {
    flex-direction: row;
    align-items: flex-start;
  }

  .scene-appareil > .cadre-appareil {
    flex: 0 1 auto;
    min-width: 0;
  }

  /*
   * Le fond devient opaque : posé sur le voile et non plus sur l'image, un fond
   * translucide laissait lire l'écran du portail au travers des chiffres.
   */
  .sonde-appareil {
    position: static;
    flex: none;
    width: 208px;
    max-height: none;
    gap: 9px;
    padding: 12px 13px 13px;
    background: #16171a;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  .sonde-appareil__titre {
    display: block;
  }

  .sonde-mesure {
    flex-direction: column;
    align-items: stretch;
    gap: 1px;
    padding-bottom: 0;
  }

  .sonde-mesure__libelle {
    font-size: 9.5px;
    letter-spacing: 0.08em;
  }

  .sonde-mesure__valeur {
    font-size: 15.5px;
    line-height: 20px;
    height: 20px;
    text-align: left;
  }

  .sonde-jauge {
    position: static;
    height: 3px;
    margin-top: 4px;
  }
}

/*
 * Le téléphone tenu debout, la tenue de tous les jours : le relevé QUITTE l'image et
 * passe dessous, et le viseur se colle en haut de l'écran. Demande de Frennly du
 * 2026-09-18.
 *
 * La raison d'origine du relevé en surimpression était le manque de place — sous les
 * boutons, il aurait fallu faire défiler pour le voir. Elle tombe avec la seconde
 * moitié de la demande : le voile centrait son contenu, ce qui laissait une bande vide
 * en haut d'un écran de huit cent quarante pixels ; collé en haut, il reste la hauteur
 * qu'il faut pour les neuf mesures en une colonne, sous l'image et au-dessus des
 * commandes.
 *
 * La borne de largeur est le complément exact de la requête « large et haut » plus
 * haut : une tablette tenue debout est assez large pour garder sa colonne à droite,
 * et un téléphone couché relève de la requête paysage, pas de celle-ci.
 */
@media (orientation: portrait) and (max-width: 899px) {
  /*
   * L'image en haut. Le défilement est le filet : le voile n'en avait aucun, et sur un
   * écran court le panneau débordait des deux côtés sans qu'on puisse l'atteindre.
   */
  .voile-appareil {
    align-items: flex-start;
    overflow-y: auto;
    padding-top: max(16px, env(safe-area-inset-top, 0px));
  }

  /*
   * Le relevé retourne dans le flux : l'enveloppe est déjà une colonne, il tombe sous le
   * cadre tout seul. Le fond devient opaque comme dans la colonne du grand écran — posé
   * sur le voile et non plus sur l'image, un fond translucide laissait lire l'écran du
   * portail au travers des chiffres.
   */
  .sonde-appareil {
    position: static;
    width: 100%;
    max-height: none;
    padding: 10px 12px 11px;
    background: #16171a;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }

  /* Il n'est plus seul de son espèce à cet endroit : il reprend son nom. */
  .sonde-appareil__titre {
    display: block;
  }

  /*
   * La jauge se range sous sa valeur, à droite. Tirée d'un bord à l'autre de la pleine
   * largeur, elle ne se lisait plus comme une jauge mais comme un filet entre deux
   * lignes.
   */
  .sonde-jauge {
    left: auto;
    width: 120px;
  }
}

.bouton-appareil {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 44px;
  padding: 0 22px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: var(--rayon-carte);
  color: rgba(255, 255, 255, 0.92);
  font-family: var(--police-nav);
  font-size: 14.5px;
  cursor: pointer;
}

.bouton-appareil--primaire {
  border-color: var(--couleur-accent);
  background: var(--couleur-accent);
  color: var(--couleur-sur-accent);
  font-weight: 500;
}

/*
 * Les trois blocs du dépôt qui portent un trait.
 *
 * Ils sont écrits ici, en CSS, et non avec les classes de bordure de Tailwind : le
 * portail charge Tailwind SANS son preflight (voir html/views/layout.php), et sans lui
 * « border » ne pose qu'une épaisseur, jamais un style de trait. Une bordure ainsi
 * déclarée ne se peint donc pas du tout — vérifié à la capture du 2026-09-04. Tout le
 * reste de theme.css écrit ses traits en clair pour la même raison.
 */
.bouton-depot {
  border: 1px solid var(--couleur-bordure-3);
  background: var(--couleur-surface);
}

.bouton-depot:hover {
  border-color: var(--couleur-accent-halo);
  color: var(--couleur-texte-fort);
}

.bouton-depot[disabled] {
  opacity: 0.5;
}

/*
 * « Observer la reconnaissance » : le geste d'atelier de l'écran interne, qui ouvre le
 * viseur sans rien prendre ni envoyer. Il porte le mint des choses techniques, en aplat
 * pour qu'on le distingue au premier regard du dépôt de fichier juste en dessous, mais
 * jamais le vert de l'accent — l'action de la démonstration reste « Scanner une carte ».
 *
 * L'aplat et son filet sont les deux jetons de surbrillance : c'est le même mint, déjà
 * décliné dans les deux registres de couleur.
 */
.bouton-observer {
  border: 1px solid var(--couleur-surbrillance-bordure);
  background: var(--couleur-surbrillance);
  color: var(--couleur-technique);
}

.bouton-observer:hover {
  border-color: var(--couleur-technique);
}

.bouton-observer[disabled] {
  opacity: 0.5;
}

/*
 * L'attente de la lecture, et la fiche lue : le même vert atténué, parce que ce sont
 * les deux temps du même geste. L'accent plein — un vert pur — serait criard sur un
 * cadre entier ; il reste au bouton, où il tient sur une petite surface.
 */
.attente-depot,
.carte-lue,
.faces-prises {
  border: 1px solid var(--couleur-accent-halo);
}

/*
 * La vignette d'une face prise. Cent soixante pixels : assez pour voir qu'on a bien
 * photographié une carte et pas la table, pas assez pour lire — ce n'est pas son rôle.
 * Le trait est écrit ici, pour la même raison que les trois blocs ci-dessus.
 */
.face-prise img {
  display: block;
  width: 160px;
  max-width: 100%;
  height: auto;
  border: 1px solid var(--couleur-bordure);
  border-radius: 8px;
  background: var(--couleur-fond);
}

/* ------------------------------------------------------------------ */
/* Recherche jouée à l'accueil — point 05b                             */
/* ------------------------------------------------------------------ */

/*
 * L'encart d'une étape. Même matière que la carte des autres écrans — un seul
 * vocabulaire de bloc dans le portail — mais avec sa tête, son compteur et son
 * contenu qui arrive après coup.
 */
.encart {
  background: var(--couleur-surface);
  border: 1px solid var(--couleur-bordure);
  border-radius: var(--rayon-carte);
  padding: 15px 18px 17px;
}

/*
 * Pendant que l'étape travaille, son cadre passe au vert atténué : c'est le registre
 * du traitement IA en cours, déjà employé par le dépôt de la carte de visite. Le vert
 * plein serait criard sur un cadre entier.
 */
.encart--travaille {
  border-color: var(--couleur-accent-halo);
}

.encart__tete {
  display: flex;
  align-items: center;
  gap: 11px;
  padding-bottom: 12px;
}

/*
 * Le numéro de l'étape. Il compte : c'est lui qui dit au prospect qu'il y a DEUX
 * temps, et que le second ne cherche pas — il lit ce que le premier a trouvé.
 */
.encart__rang {
  flex: none;
  width: 20px;
  height: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  color: var(--couleur-texte-discret);
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-pilule);
}

.encart__titre {
  flex: 1;
  min-width: 0;
  font-family: var(--police-nav);
  font-size: 12.5px;
  color: var(--couleur-texte-fort);
}

/*
 * Le compteur. C'est la pièce qui transforme une attente en preuve de travail : il
 * tourne pendant l'appel, puis se fige sur la durée mesurée par le serveur — celle
 * du webhook, la seule défendable devant un prospect.
 */
.encart__chrono {
  flex: none;
  font-size: 12px;
  color: var(--couleur-technique);
}

.encart__compte {
  margin: 0;
  font-size: 12px;
  color: var(--couleur-texte-discret);
}

.encart__liste {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.encart__pied {
  margin: 12px 0 0;
  font-size: 11.5px;
  color: var(--couleur-texte-discret);
}

/*
 * Le retour à l'état de repos, sous les deux encarts.
 *
 * Il sort du registre discret des passages, et c'est délibéré : pendant le parcours, la
 * rangée des sept outils s'efface, et ce bouton est le SEUL chemin de retour de l'écran.
 * Il portait « .bouton-passages » jusqu'au 2026-09-16 — un mot gris de 12 px, sans fond
 * ni bordure, posé sur le fond de page : 3,4 pour 1 de contraste en thème sombre, sous
 * le seuil de 4,5. Frennly ne le voyait pas, et en vidéoprojection il disparaissait.
 *
 * Le fond plein est l'arbitrage de Frennly, rendu contre l'argument que l'accent attire
 * l'œil plus que la réponse rédigée juste au-dessus. Cet argument se paie ici sur la
 * taille : hauteur de 38 px et largeur dictée par le libellé, pour que le bouton soit un
 * bouton et non un bandeau.
 *
 * Le registre est celui de « .bouton-primaire », dont la géométrie n'est pas reprise :
 * ses 50 px de haut et sa marge sont taillés pour la colonne de l'écran de connexion.
 */
.bouton-relance {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 38px;
  padding: 0 20px;
  border-radius: var(--rayon-bouton);
  background: var(--couleur-accent);
  color: var(--couleur-sur-accent);
  font-family: var(--police-nav);
  font-size: 13.5px;
  font-weight: 500;
}

.bouton-relance:hover {
  filter: brightness(0.94);
}

/*
 * Un extrait donné au modèle. La ligne entière s'allume quand une citation de la
 * réponse la désigne : c'est tout l'argument de l'écran — la phrase rédigée et le
 * document qui la porte se regardent.
 */
.extrait {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 7px 9px;
  border: 1px solid transparent;
  border-radius: var(--rayon-bouton);
}

.extrait--vise {
  background: var(--couleur-surbrillance);
  border-color: var(--couleur-surbrillance-bordure);
}

.extrait--faible {
  opacity: 0.72;
}

.extrait__rang {
  flex: none;
  width: 18px;
  font-size: 11px;
  text-align: right;
  color: var(--couleur-texte-discret);
}

.extrait__corps {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 9px;
}

/*
 * Le titre est un lien, et la règle a:hover de la charte l'emporterait sur une
 * classe utilitaire : il porte donc sa propre couleur, comme .lien-resultat du
 * point 05. Une seule ligne, tronquée : cinq extraits doivent tenir sans pousser la
 * réponse hors de l'écran.
 */
.extrait__titre {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--couleur-texte);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

a.extrait__titre:hover {
  color: var(--couleur-texte-fort);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.extrait__score {
  flex: none;
  font-size: 12px;
  color: var(--couleur-texte-discret);
}

/*
 * La réponse rédigée. Plus grande que le corps de texte courant : c'est la seule
 * phrase de l'écran que le prospect lira vraiment, et elle est lue à voix haute en
 * rendez-vous.
 */
.synthese {
  margin: 10px 0 0;
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--couleur-texte-fort);
}

.synthese__ligne {
  margin: 0 0 8px;
}

.synthese__ligne:last-child {
  margin-bottom: 0;
}

/*
 * La reponse en etapes. Le wiki n ecrit que des procedures, et la consigne demande au
 * modele de rendre une action par ligne : cette liste est donc la forme NORMALE de la
 * reponse, pas un cas particulier. Puce en tiret plutot qu en point, comme le modele
 * l ecrit, et retrait leger pour que les citations restent alignees avec le texte.
 */
.synthese__liste {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
}

.synthese__liste:last-child {
  margin-bottom: 0;
}

.synthese__liste li {
  position: relative;
  padding-left: 20px;
  margin-bottom: 4px;
}

.synthese__liste li::before {
  content: "—";
  position: absolute;
  left: 0;
  color: var(--couleur-texte-discret);
}

/*
 * Une citation dans la réponse. Un bouton, et non une puce décorative : il s'atteint
 * au clavier, et c'est le seul moyen de rendre le lien citation → document utilisable
 * autrement qu'à la souris. Mint, registre de la citation du corpus.
 */
.citation {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 17px;
  height: 17px;
  margin: 0 1px;
  padding: 0 4px;
  vertical-align: 1px;
  font-family: var(--police-mono);
  font-size: 10.5px;
  color: var(--couleur-technique);
  background: var(--couleur-surbrillance);
  border: 1px solid var(--couleur-surbrillance-bordure);
  border-radius: var(--rayon-pilule);
  cursor: pointer;
}

.citation:hover,
.citation:focus-visible {
  color: var(--couleur-sur-accent);
  background: var(--couleur-technique);
  border-color: var(--couleur-technique);
}

/*
 * L'infobulle d'une citation : le titre entier du document, et de quoi l'ouvrir.
 *
 * Elle reprend la chrome de « .infobulle » — fond, bordure, ombre, bec, largeur
 * maximale — déjà écrite pour les picots des cartes et déjà vérifiée dans les deux
 * thèmes. N'est posé ici que ce qui lui manque : un hôte, l'ouverture, et sa mise en
 * page intérieure.
 *
 * Ouverture par la feuille de style, sans une ligne d'Alpine : les citations sont
 * injectées en x-html, où aucun x-data imbriqué ne prendrait. « :focus-within » est ce
 * qui l'ouvre au doigt — un appui met le bouton au focus — et au clavier.
 */
.citation-hote {
  position: relative;
  display: inline-block;
}

.citation-hote .infobulle {
  display: none;
}

.citation-hote:hover .infobulle,
.citation-hote:focus-within .infobulle {
  display: block;
}

/*
 * Position et largeur sont posées ici en valeur de départ, puis mesurées par le
 * composant au moment du survol : lui seul sait où la citation est tombée dans la
 * phrase. Les 320 px sont écrits des deux côtés — c'est le seul accord à tenir entre
 * cette règle et recherche-jouee.js.
 */
.infobulle--source {
  left: 0;
  width: min(320px, calc(100vw - 16px));
  max-width: none;
  transform: none;
  font-size: 12.5px;
}

.infobulle--source::after {
  left: var(--bec, 24px);
  right: auto;
  margin-left: -5px;
}

/*
 * Le pont. Entre le chiffre et la bulle il y a 10 px de vide : sans cette bande
 * invisible, le pointeur perd le survol en chemin et la bulle se ferme avant que le
 * lien soit atteint.
 */
.infobulle--source::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -11px;
  height: 11px;
}

.infobulle-source__titre {
  display: block;
  color: var(--couleur-texte-fort);
  font-weight: 500;
  line-height: 17px;
}

.infobulle-source__lien {
  display: block;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--couleur-bordure-3);
  color: var(--couleur-technique);
  font-size: 12px;
}

.infobulle-source__lien:hover {
  color: var(--couleur-technique);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/*
 * La bande d'erreur posée dans un encart : sans la marge négative de l'écran de
 * connexion, et plus compacte — l'encart a déjà son cadre et sa tête.
 */
.bande-erreur--encart {
  margin: 8px 0 0;
  align-items: flex-start;
  padding: 10px 12px;
}

/*
 * Voile d'attente d'anonymisation — point 10b.
 *
 * Le module de support masque ses données CÔTÉ SERVEUR : la page arrive déjà
 * anonymisée, et il n'y a donc aucun moment, après le rendu, où un témoin
 * d'attente dirait quelque chose de vrai. Le seul temps réel est celui de la
 * navigation — entre le clic et la réponse, le serveur interroge la source, fait
 * relever les noms puis les remplace. C'est ce temps-là que ce voile occupe, et
 * c'est pour cela qu'il est posé au clic et non à l'arrivée : un témoin affiché
 * après coup serait du faux progrès, ce que le module s'interdit ailleurs.
 *
 * Le filet reprend celui de la palette de recherche : un seul vocabulaire
 * d'attente dans tout le portail, et il est indéterminé — il ne prétend pas
 * connaître un pourcentage.
 */
.voile-anonymisation {
  display: none;
}

.voile-anonymisation.est-visible {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--couleur-voile-fort);
}

.voile-anonymisation__boite {
  width: 100%;
  max-width: 380px;
  padding: 20px 22px 18px;
  border-radius: var(--rayon-bloc);
  background: var(--couleur-surface);
  border: 1px solid var(--couleur-bordure-3);
  box-shadow: var(--ombre-flottant);
}

.voile-anonymisation__titre {
  margin: 0;
  font-family: var(--police-titre);
  font-size: 15px;
  color: var(--couleur-texte-fort);
}

.voile-anonymisation__detail {
  margin: 6px 0 0;
  font-family: var(--police-texte);
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--couleur-texte-discret);
}

.voile-anonymisation__filet {
  display: block;
  height: 2px;
  margin-top: 14px;
  overflow: hidden;
  background: var(--couleur-bordure);
  border-radius: var(--rayon-pilule);
}

.voile-anonymisation__barre {
  display: block;
  height: 100%;
  width: 38%;
  background: var(--couleur-accent);
  animation: progression-palette 1.1s ease-in-out infinite;
}

/* Qui a demandé moins de mouvement garde le filet, sans le balayage. */
@media (prefers-reduced-motion: reduce) {
  .voile-anonymisation__barre {
    width: 100%;
    animation: none;
  }
}

/* ------------------------------------------------------------------ */
/* Diagnostic de maturité IA sur tablette — point 18                   */
/* ------------------------------------------------------------------ */

/*
 * Page pleine, sans Tailwind comme la connexion : une colonne de 760 px centrée sur
 * le fond, un écran visible à la fois, deux boutons de 56 px ancrés en bas à hauteur
 * de pouce. Les valeurs sont celles de la maquette validée le 2026-09-10 : question en
 * Jost 30, cartes de réponse de 68 px — cinq doivent tenir sans défilement —, barre de
 * progression continue avec son compteur. Les écrans non courants sont cachés par
 * x-cloak dès qu'Alpine tourne ; sans lui, ils restent tous cachés et le message
 * noscript est le seul visible.
 */
.autodiag-corps {
  min-height: 100%;
  display: flex;
  justify-content: center;
  -webkit-tap-highlight-color: transparent;
}

.autodiag {
  width: 760px;
  max-width: calc(100vw - 48px);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  padding: 36px 0;
}

html.js .autodiag .autodiag-etape[x-cloak],
html.js .autodiag .autodiag-progression[x-cloak] {
  display: none;
}

.autodiag-marque {
  display: flex;
  align-items: center;
  justify-content: space-between;

  /*
   * La hauteur du mot-symbole. En marque blanche il n'y a plus d'image, et sans ce
   * plancher le bandeau tomberait de 28 px à 12 px : tout l'écran remonterait de
   * 16 px par rapport à la page de Frennly.
   */
  min-height: 28px;
}

/* Plus qu'une cellule en marque blanche : le libellé se range à gauche. */
.autodiag-marque--neutre {
  justify-content: flex-start;
}

.autodiag-marque__nom {
  display: flex;
  align-items: center;
  gap: 11px;
  font-size: 18px;
  font-weight: 500;
  color: var(--couleur-texte-fort);
  letter-spacing: 0.2px;
}

.autodiag-marque__outil {
  font-size: 10px;
  letter-spacing: 0.9px;
  text-transform: uppercase;
  color: var(--couleur-texte-discret);
}

.autodiag-progression {
  display: flex;
  align-items: center;
  gap: 20px;
  margin-top: 30px;
}

.autodiag-progression__piste {
  flex: 1;
  height: 4px;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-bordure-3);
  overflow: hidden;
}

.autodiag-progression__remplie {
  display: block;
  height: 4px;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-accent);
  transition: width 0.25s ease;
}

.autodiag-progression__compteur {
  flex: none;
  font-size: 13px;
  letter-spacing: 0.2px;
  color: var(--couleur-texte);
}

.autodiag-attente {
  margin: 60px 0 0;
  font-size: 16px;
  color: var(--couleur-texte);
}

.autodiag-etape {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.autodiag-etape__corps {
  display: flex;
  flex-direction: column;
}

.autodiag-etape__espace {
  flex: 1;
}

.autodiag-etape__espace--grand {
  flex: 1.4;
}

.autodiag-question {
  margin: 30px 0 0;
  font-size: 30px;
  font-weight: 300;
  line-height: 1.22;
  letter-spacing: -0.3px;
  color: var(--couleur-texte-fort);
  text-wrap: pretty;
}

.autodiag-question--coordonnees {
  margin-top: 24px;
  font-size: 26px;
  line-height: 1.25;
  letter-spacing: -0.2px;
}

/* ---- L'accueil ---- */

.autodiag-accueil__titre {
  margin: 0;
  font-size: 52px;
  font-weight: 300;
  line-height: 1.12;
  letter-spacing: -0.8px;
  color: var(--couleur-texte-fort);
  text-wrap: balance;
}

.autodiag-accueil__sous-titre {
  margin: 22px 0 0;
  font-size: 20px;
  line-height: 1.45;
  color: var(--couleur-texte);
}

.autodiag-faits {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  margin-top: 44px;
}

.autodiag-fait {
  display: flex;
  flex-direction: column;
  padding: 22px 24px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-carte);
  background: var(--couleur-surface);
}

.autodiag-fait__chiffre {
  font-size: 40px;
  font-weight: 300;
  line-height: 1;
  color: var(--couleur-texte-fort);
}

.autodiag-fait__unite {
  font-size: 26px;
  color: var(--couleur-texte);
}

.autodiag-fait__texte {
  margin-top: 10px;
  font-size: 15px;
  color: var(--couleur-texte);
}

/* ---- Une question et ses cartes ---- */

.autodiag-choix {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 26px;
}

.autodiag-carte {
  display: flex;
  align-items: center;
  gap: 18px;
  min-height: 68px;
  padding: 16px 24px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-carte);
  background: var(--couleur-surface);
  color: var(--couleur-texte);
  font-family: var(--police-texte);
  text-align: left;
  cursor: pointer;
}

.autodiag-carte--choisie {
  border: 1.5px solid var(--couleur-accent);
  color: var(--couleur-texte-fort);
}

.autodiag-carte__rond {
  width: 22px;
  height: 22px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--couleur-texte-discret);
  border-radius: var(--rayon-pilule);
  color: var(--couleur-sur-accent);
}

.autodiag-carte--choisie .autodiag-carte__rond {
  border-color: var(--couleur-accent);
  background: var(--couleur-accent);
}

.autodiag-carte__texte {
  font-size: 17px;
  line-height: 1.35;
}

/* ---- La transition ---- */

.autodiag-transition__coche {
  width: 56px;
  height: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-accent);
  color: var(--couleur-sur-accent);
}

.autodiag-transition__titre {
  margin: 26px 0 0;
  font-size: 44px;
  font-weight: 300;
  line-height: 1.15;
  letter-spacing: -0.5px;
  color: var(--couleur-texte-fort);
}

.autodiag-transition__texte {
  margin: 18px 0 0;
  max-width: 620px;
  font-size: 21px;
  line-height: 1.45;
  color: var(--couleur-texte);
  text-wrap: pretty;
}

/* ---- Les coordonnées ---- */

.autodiag-champs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 20px;
  margin-top: 22px;
}

.autodiag-champ {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.autodiag-champ__libelle {
  display: flex;
  align-items: baseline;
  gap: 3px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--couleur-texte-fort);
}

/* L'étoile des champs obligatoires. Les six le sont ; seules les deux dernières cases
   à cocher ne le sont pas, et elles portent déjà leur mention. */
.autodiag-champ__requis {
  color: var(--couleur-alerte);
  font-weight: 500;
}

.autodiag-champ__saisie {
  height: 50px;
  padding: 0 14px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-champ);
  background: var(--couleur-champ-fond);
  color: var(--couleur-texte-fort);
  font-family: var(--police-texte);
  font-size: 16px;
}

.autodiag-champ__saisie:focus {
  outline: none;
  border-color: var(--couleur-accent);
  box-shadow: inset 0 0 0 1px var(--couleur-accent);
}

.autodiag-champ__saisie--erreur {
  border-color: var(--couleur-alerte);
}

.autodiag-champ__erreur {
  display: block;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--couleur-alerte);
}

.autodiag-champ__erreur:empty {
  display: none;
}

/*
 * Les deux groupes de boutons sont encadrés comme les champs de saisie qui les
 * précèdent. Sans ce cadre, les trois fonctions et les quatre effectifs se lisaient
 * comme une seule rangée de sept boutons, et l'on ne voyait pas qu'il y avait là deux
 * questions — relevé par Frennly le 2026-09-11 sur l'écran des coordonnées.
 */
.autodiag-options {
  display: grid;
  gap: 8px;
  padding: 8px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-champ);
  background: var(--couleur-champ-fond);
}

.autodiag-options--trois {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.autodiag-options--quatre {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.autodiag-option {
  min-height: 48px;
  padding: 0 8px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: 11px;
  background: var(--couleur-surface);
  color: var(--couleur-texte);
  font-size: 14px;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
}

.autodiag-option--choisie {
  border: 1.5px solid var(--couleur-accent);
  color: var(--couleur-texte-fort);
  font-weight: 500;
}

.autodiag-pot {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.autodiag-cases {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 20px;
}

.autodiag-case {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  cursor: pointer;
}

/* La case native est masquée mais reste focalisable : la boîte dessinée la suit. */
.autodiag-case__saisie {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  opacity: 0;
  pointer-events: none;
}

.autodiag-case__boite {
  width: 22px;
  height: 22px;
  flex: none;
  margin-top: 1px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--couleur-texte-discret);
  border-radius: 6px;
  color: transparent;
}

.autodiag-case__saisie:checked + .autodiag-case__boite {
  border-color: var(--couleur-accent);
  background: var(--couleur-accent);
  color: var(--couleur-sur-accent);
}

.autodiag-case__saisie:focus-visible + .autodiag-case__boite {
  box-shadow: 0 0 0 2px var(--couleur-accent);
}

.autodiag-case__texte {
  font-size: 15px;
  line-height: 1.5;
  color: var(--couleur-texte);
}

.autodiag-case__texte--fort {
  color: var(--couleur-texte-fort);
}

.autodiag-case__obligatoire {
  color: var(--couleur-texte-discret);
}

.autodiag-mention {
  margin: 14px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--couleur-texte-discret);
}

.autodiag-erreur-envoi {
  margin: 14px 0 0;
  font-size: 14px;
}

/*
 * Le widget anti-robot. Il vient avec sa propre boîte et son propre thème — le
 * portail ne fait que lui donner sa place. Tant qu'il n'est pas monté, le bloc est
 * vide et sans marge : rien ne bouge sous les yeux du prospect quand il apparaît,
 * puisqu'il apparaît avant que l'écran ne soit montré.
 */
.autodiag-turnstile:not(:empty) {
  margin: 18px 0 0;
}

/* ---- Le résultat ---- */

.autodiag-resultat__titre {
  margin: 28px 0 0;
  font-size: 32px;
  font-weight: 300;
  line-height: 1.2;
  letter-spacing: -0.3px;
  color: var(--couleur-texte-fort);
  text-wrap: pretty;
}

.autodiag-resultat__niveau {
  font-weight: 500;
  white-space: nowrap;
}

.autodiag-score {
  display: flex;
  align-items: center;
  gap: 28px;
  margin-top: 22px;
}

.autodiag-score__bloc {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex: none;
}

.autodiag-score__libelle {
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--couleur-texte-discret);
}

.autodiag-score__valeur {
  font-size: 56px;
  font-weight: 300;
  line-height: 1;
  letter-spacing: -1px;
  color: var(--couleur-texte-fort);
}

.autodiag-score__segments {
  display: flex;
  gap: 6px;
  flex: none;
}

.autodiag-score__segment {
  width: 34px;
  height: 6px;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-bordure-3);
}

.autodiag-score__segment--fait {
  background: var(--couleur-accent);
}

.autodiag-score__phrase {
  font-size: 17px;
  line-height: 1.4;
  color: var(--couleur-texte);
  text-wrap: pretty;
}

.autodiag-points {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  margin-top: 28px;
}

.autodiag-point {
  display: flex;
  flex-direction: column;
  padding: 22px 24px 24px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-carte);
  background: var(--couleur-surface);
}

.autodiag-point--appui {
  border: 1.5px solid var(--couleur-accent);
}

.autodiag-point__entete {
  display: flex;
  align-items: center;
  gap: 10px;
}

.autodiag-point__icone {
  width: 22px;
  height: 22px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
}

.autodiag-point__icone--appui {
  border-radius: var(--rayon-pilule);
  background: var(--couleur-accent);
  color: var(--couleur-sur-accent);
}

/* L'ambre de la vigilance n'existe pas dans la charte : la seule couleur hors tokens
   de cet écran, la même dans les deux thèmes. */
.autodiag-point__icone--vigilance {
  color: #F5B942;
}

.autodiag-point__titre {
  font-size: 11px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--couleur-texte);
}

.autodiag-point__axe {
  margin-top: 16px;
  font-size: 24px;
  font-weight: 400;
  line-height: 1.2;
  color: var(--couleur-texte-fort);
}

.autodiag-point__texte {
  margin-top: 10px;
  font-size: 16px;
  line-height: 1.45;
  color: var(--couleur-texte);
}

.autodiag-envoi {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 26px 0 0;
  font-size: 17px;
  line-height: 1.45;
  color: var(--couleur-texte-fort);
}

.autodiag-envoi__icone {
  flex: none;
  margin-top: 1px;
  color: var(--couleur-accent);
}

.autodiag-envoi__discret {
  color: var(--couleur-texte);
}

/* ---- Le pied et les boutons ---- */

.autodiag-pied {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: auto;
  padding-top: 24px;
}

.autodiag-pied--centre {
  justify-content: center;
}

.autodiag-bouton {
  height: 56px;
  padding: 0 28px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-bouton);
  background: var(--couleur-surface);
  color: var(--couleur-texte);
  font-size: 15px;
  font-weight: 500;
  cursor: pointer;
}

.autodiag-bouton--primaire {
  width: 220px;
  padding: 0;
  border: 0;
  background: var(--couleur-accent);
  color: var(--couleur-sur-accent);
}

.autodiag-bouton--large {
  width: 260px;
}

.autodiag-bouton--pleine {
  width: 100%;
  height: 64px;
  border-radius: 14px;
  font-size: 17px;
}

.autodiag-bouton:disabled {
  opacity: 0.6;
  cursor: default;
}

/*
 * Tablette en portrait et téléphone : une colonne, et le pied des boutons **fixé** au
 * bas de l'écran — sur un téléphone, la question et ses réponses dépassent la hauteur
 * visible, et le bouton « Continuer » se trouvait sous la ligne de flottaison. Chaque
 * écran réserve donc la hauteur du pied en bas de son contenu, sans quoi la dernière
 * réponse passerait dessous.
 */
@media (max-width: 720px) {
  .autodiag {
    padding: 26px 0 0;
  }

  .autodiag-etape {
    padding-bottom: calc(92px + env(safe-area-inset-bottom, 0px));
  }

  .autodiag-pied {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 5;
    gap: 12px;
    margin-top: 0;
    padding: 12px 24px calc(12px + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--couleur-bordure-2);
    background: var(--couleur-fond);
  }

  /* Le bouton principal prend la place qui reste ; « Retour » garde sa largeur. */
  .autodiag-pied .autodiag-bouton--primaire {
    flex: 1;
    width: auto;
  }

  /* Sans cette marge, le grand titre de l'accueil touche le nom de la marque dès que
     le contenu remplit la hauteur : l'espace souple au-dessus tombe alors à zéro. */
  .autodiag-accueil__titre {
    margin-top: 26px;
    font-size: 38px;
  }

  .autodiag-faits,
  .autodiag-champs,
  .autodiag-points {
    grid-template-columns: 1fr;
  }

  .autodiag-options--quatre {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .autodiag-question {
    font-size: 26px;
  }

  .autodiag-resultat__titre {
    font-size: 28px;
  }

  .autodiag-score {
    flex-wrap: wrap;
    gap: 16px;
  }

  .autodiag-score__valeur {
    font-size: 44px;
  }

  .autodiag-bouton--primaire,
  .autodiag-bouton--large {
    width: auto;
    padding: 0 28px;
  }

  .autodiag-bouton--pleine {
    width: 100%;
  }
}

/* ------------------------------------------------------------------ */
/* Diagnostic de maturité IA, côté portail : la table des réponses     */
/* ------------------------------------------------------------------ */

.bouton-ouvrir-tablette {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 44px;
  padding: 0 20px;
  border-radius: var(--rayon-bouton);
  background: var(--couleur-accent);
  color: var(--couleur-sur-accent);
  font-size: 14.5px;
  font-weight: 500;
}

.bouton-ouvrir-tablette:hover {
  color: var(--couleur-sur-accent);
  filter: brightness(0.94);
}

.bouton-exporter {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  height: 44px;
  padding: 0 18px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-bouton);
  background: var(--couleur-surface);
  color: var(--couleur-texte);
  font-size: 14px;
  font-weight: 500;
}

.bouton-exporter:hover {
  color: var(--couleur-texte-fort);
}

.table-leads {
  border: 1px solid var(--couleur-bordure);
  border-radius: var(--rayon-carte);
  background: var(--couleur-surface);
  padding: 18px 6px 6px;
}

.table-leads table {
  width: 100%;
  border-collapse: collapse;
}

.table-leads th {
  padding: 0 7px 12px;
  border-bottom: 1px solid var(--couleur-bordure);
  font-size: 10.5px;
  font-weight: 400;
  letter-spacing: 0.8px;
  text-transform: uppercase;
  text-align: left;
  color: var(--couleur-texte-discret);
  white-space: nowrap;
}

.table-leads td {
  padding: 15px 7px;
  border-bottom: 1px solid var(--couleur-bordure-2);
  font-size: 13px;
  color: var(--couleur-texte);
  white-space: nowrap;
}

.table-leads tbody tr:last-child td {
  border-bottom: 0;
}

.table-leads__fort {
  color: var(--couleur-texte-fort);
}

.table-leads__date {
  font-size: 12px;
}

.table-leads__nombre {
  text-align: right;
}

.table-leads__lien {
  color: var(--couleur-texte);
}

.table-leads__lien:hover {
  color: var(--couleur-texte-fort);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.etat-envoi {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 24px;
  padding: 0 10px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-pilule);
  background: var(--couleur-surface-3);
  font-size: 12px;
  color: var(--couleur-texte);
}

.etat-envoi__point {
  width: 6px;
  height: 6px;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-accent);
}

.etat-envoi--echec {
  border-color: var(--couleur-alerte);
  color: var(--couleur-alerte);
}

.etat-envoi--echec .etat-envoi__point {
  background: var(--couleur-alerte);
}

.table-leads__sous {
  display: block;
  margin-top: 2px;
  font-size: 11.5px;
  color: var(--couleur-texte-discret);
}

.table-leads__centre {
  text-align: center;
}

.pastille-oui,
.pastille-non {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: var(--rayon-pilule);
  vertical-align: middle;
}

.pastille-oui {
  background: var(--couleur-accent);
  color: var(--couleur-sur-accent);
}

.pastille-non {
  border: 1px solid var(--couleur-bordure-3);
  color: var(--couleur-texte-discret);
  font-size: 11px;
}

/* ------------------------------------------------------------------ */
/* Le détail d'une réponse, dans son tiroir, et sa suppression         */
/* ------------------------------------------------------------------ */

.bande-retour {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 12px 15px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-carte);
  background: var(--couleur-surface);
  font-size: 13px;
  line-height: 1.45;
  color: var(--couleur-texte);
}

.bande-retour__icone {
  flex: none;
  color: var(--couleur-accent);
}

.bande-retour--echec {
  border-color: var(--couleur-alerte);
}

.bande-retour--echec .bande-retour__icone {
  color: var(--couleur-alerte);
}

/*
 * La colonne des deux gestes reste au bord droit quand la table déborde : c'est la
 * colonne qu'on vient chercher, elle ne doit pas être celle qui sort de l'écran.
 */
.table-leads th:last-child,
.table-leads td:last-child {
  position: sticky;
  right: 0;
  padding-left: 8px;
  background: var(--couleur-surface);
  box-shadow: -10px 0 10px -10px rgba(0, 0, 0, 0.45);
}

.actions-lead {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.bouton-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: var(--rayon-bouton);
  color: var(--couleur-texte-discret);
}

.bouton-action:hover {
  background: var(--couleur-surface-3);
  color: var(--couleur-texte-fort);
}

.bouton-action--danger:hover {
  color: var(--couleur-alerte);
}

.voile-lead {
  position: fixed;
  inset: 0;
  background: var(--couleur-voile);
  z-index: 40;
}

/*
 * Le voile de la confirmation passe AU-DESSUS du tiroir : sans cela, le tiroir restait
 * net derrière la question et paraissait toujours manœuvrable, alors qu'un seul geste
 * est attendu.
 */
.voile-lead--haut {
  z-index: 55;
}

.tiroir-lead {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 520px;
  max-width: 94vw;
  z-index: 50;
  display: flex;
  flex-direction: column;
  background: var(--couleur-surface);
  border-left: 1px solid var(--couleur-bordure-3);
  box-shadow: var(--ombre-tiroir);
}

.tiroir-lead__entete {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 20px 20px 16px 24px;
  border-bottom: 1px solid var(--couleur-bordure);
}

.tiroir-lead__contact {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  color: var(--couleur-texte-fort);
}

.tiroir-lead__sous {
  margin: 3px 0 0;
  font-size: 12.5px;
  color: var(--couleur-texte-discret);
}

.tiroir-lead__corps {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 20px 24px 26px;
}

.tiroir-lead__bandeau {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 13px 15px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-carte);
  background: var(--couleur-surface-3);
}

.tiroir-lead__niveau {
  font-size: 14.5px;
  font-weight: 500;
  color: var(--couleur-texte-fort);
}

.tiroir-lead__score {
  font-size: 12.5px;
  color: var(--couleur-texte-discret);
  white-space: nowrap;
}

.fiche-lead {
  margin: 16px 0 0;
}

.fiche-lead__ligne {
  display: flex;
  gap: 14px;
  padding: 8px 0;
  border-bottom: 1px solid var(--couleur-bordure);
  font-size: 13px;
}

.fiche-lead__ligne dt {
  flex: none;
  width: 92px;
  color: var(--couleur-texte-discret);
}

.fiche-lead__ligne dd {
  margin: 0;
  flex: 1;
  min-width: 0;
  color: var(--couleur-texte);
  overflow-wrap: anywhere;
}

.texte-alerte {
  color: var(--couleur-alerte);
}

.titre-tiroir {
  font-family: var(--police-nav);
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--couleur-texte-discret);
  margin: 26px 0 10px;
}

.axe-lead {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 0;
  font-size: 13px;
}

.axe-lead__nom {
  flex: none;
  width: 150px;
  color: var(--couleur-texte);
}

.axe-lead__jauge {
  display: flex;
  gap: 3px;
}

.axe-lead__cran {
  width: 14px;
  height: 6px;
  border-radius: 3px;
  background: var(--couleur-bordure-3);
}

.axe-lead__cran.est-plein {
  background: var(--couleur-accent);
}

.axe-lead__note {
  font-size: 12px;
  color: var(--couleur-texte-discret);
  white-space: nowrap;
}

.axe-lead__marque {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 8px;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-accent);
  color: var(--couleur-sur-accent);
  font-size: 11px;
}

.axe-lead__marque--veille {
  background: transparent;
  border: 1px solid var(--couleur-alerte);
  color: var(--couleur-alerte);
}

.reponse-lead {
  padding: 9px 0;
  border-bottom: 1px solid var(--couleur-bordure);
}

.reponse-lead__question {
  margin: 0;
  font-size: 12.5px;
  color: var(--couleur-texte-discret);
}

.reponse-lead__valeur {
  margin: 3px 0 0;
  font-size: 13.5px;
  color: var(--couleur-texte-fort);
}

.reponse-lead__axe {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 7px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-pilule);
  font-size: 11px;
  color: var(--couleur-texte-discret);
}

.accord-lead {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--couleur-texte);
}

.accord-lead .pastille-oui,
.accord-lead .pastille-non {
  flex: none;
  margin-top: 1px;
}

.mention-lead {
  margin: 16px 0 0;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--couleur-texte-discret);
}

.tiroir-lead__pied {
  flex: none;
  display: flex;
  justify-content: flex-end;
  padding: 14px 24px;
  border-top: 1px solid var(--couleur-bordure);
}

.bouton-supprimer {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  height: 40px;
  padding: 0 16px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-bouton);
  background: var(--couleur-surface);
  color: var(--couleur-texte);
  font-size: 13.5px;
  font-weight: 500;
}

.bouton-supprimer:hover {
  border-color: var(--couleur-alerte);
  color: var(--couleur-alerte);
}

.bouton-supprimer--plein {
  height: 44px;
  border-color: var(--couleur-alerte);
  background: var(--couleur-alerte);
  color: var(--couleur-surface);
}

.bouton-supprimer--plein:hover {
  color: var(--couleur-surface);
  filter: brightness(0.94);
}

.boite-suppression {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 60;
  width: 470px;
  max-width: 92vw;
  padding: 22px 24px 20px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-carte);
  background: var(--couleur-surface);
  box-shadow: var(--ombre-flottant);
}

.boite-suppression__titre {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  color: var(--couleur-texte-fort);
}

.boite-suppression__texte {
  margin: 10px 0 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--couleur-texte);
}

.boite-suppression__pied {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 20px;
}

/*
 * Sur un écran étroit, un tiroir de 520 px laisserait une bande inutilisable à gauche :
 * il prend toute la largeur. La table, elle, continue de défiler horizontalement.
 */
@media (max-width: 720px) {
  .tiroir-lead {
    width: 100vw;
    max-width: 100vw;
  }

  .axe-lead__nom {
    width: 110px;
  }
}

/* ------------------------------------------------------------------ *
 * Connecteurs : le schéma d'ouverture — point 07b
 *
 * Un avant / après à grammaire identique : les mêmes quatre outils à gauche,
 * le même assistant à droite, et entre les deux la pièce qui change — vous et
 * vos copier-coller d'un côté, le connecteur de l'autre. Tout est dessiné en
 * HTML plutôt qu'en image : le schéma suit les deux thèmes sans seconde
 * version, et se relit à la ligne près quand un libellé change.
 * ------------------------------------------------------------------ */

.schema-mcp {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px;
  margin-top: 20px;
}

/*
 * Le filet ne sépare que la première moitié : posé sur les deux, il doublerait
 * le bord droit de la carte.
 */
.schema-mcp__moitie {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.schema-mcp__moitie:first-child {
  padding-right: 24px;
  border-right: 1px solid var(--couleur-bordure);
}

/*
 * La rangée du schéma ne se replie pas : un faisceau qui passe à la ligne ne
 * raconte plus rien. Sur un écran étroit elle défile horizontalement, et c'est
 * la seule chose de cet écran qui défile ainsi.
 */
.schema-mcp__flux {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 16px;
  overflow-x: auto;
}

.schema-mcp__outils {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: none;
}

.schema-mcp__outil {
  display: flex;
  align-items: center;
  height: 26px;
  padding: 0 11px;
  border: 1px solid var(--couleur-bordure);
  border-radius: var(--rayon-pilule);
  background: var(--couleur-fond);
  font-size: 12px;
  color: var(--couleur-texte);
  white-space: nowrap;
}

.schema-mcp__boite {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  flex: none;
  height: 62px;
  padding: 0 16px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-bouton);
  background: var(--couleur-surface-3);
}

/*
 * La pièce du milieu, moitié « sans connecteur ». Trait pointillé et fond de
 * page : c'est la place vide que le connecteur vient prendre, elle ne doit pas
 * se lire comme un composant du portail.
 */
.schema-mcp__boite--vous {
  border-style: dashed;
  background: var(--couleur-fond);
}

.schema-mcp__boite-titre {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  color: var(--couleur-texte-fort);
  white-space: nowrap;
}

.schema-mcp__boite-sous {
  font-size: 11px;
  color: var(--couleur-texte-discret);
  white-space: nowrap;
}

.schema-mcp__trait {
  flex: none;
  stroke: var(--couleur-bordure-3);
}

.schema-mcp__trait--actif {
  stroke: var(--couleur-faisceau);
}

.schema-mcp__consequence {
  margin: 16px 0 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--couleur-texte-discret);
}

/*
 * Sous 1 200 px, les deux moitiés ne tiennent plus côte à côte sans que chaque
 * faisceau ne devienne une barre de défilement. Elles s'empilent, et le filet
 * passe du côté droit au dessous.
 */
@media (max-width: 1200px) {
  .schema-mcp {
    grid-template-columns: minmax(0, 1fr);
  }

  .schema-mcp__moitie:first-child {
    padding-right: 0;
    padding-bottom: 22px;
    border-right: 0;
    border-bottom: 1px solid var(--couleur-bordure);
  }
}

/* ------------------------------------------------------------------- */
/* Scan d'une carte de visite sans compte — point 18b                   */
/*                                                                      */
/* La coque est celle du diagnostic : meme colonne, meme en-tete, meme  */
/* pied fixe sous 720 px. Ce sont les deux ecrans publics qu'on tient a */
/* la main, et ils n'avaient pas a etre habilles deux fois. Le viseur,  */
/* lui, emprunte les classes de la demonstration connectee sans en      */
/* changer une ligne.                                                   */
/* ------------------------------------------------------------------- */

/* Une enveloppe de donnees, pas une boite : elle ne doit rien peindre. */
.scan-zone {
  display: contents;
}

/*
 * Le contenu ne s'etire pas, contrairement au diagnostic : celui-ci a des ecrans a
 * remplir, celui-ci n'a qu'un titre et ce qui a ete lu. Etire, il ouvrait un vide de
 * quatre cents pixels entre la phrase et les boutons sur une tablette.
 */
.scan-page {
  flex: none;
  gap: 18px;
}

/*
 * Le pied suit le contenu au lieu d'etre pousse en bas de fenetre. Sous 720 px, la
 * requete du diagnostic le fixe au bas de l'ecran, et cette marge n'a plus d'effet :
 * un element fixe cale par « bottom » ne se decale pas d'une marge haute.
 */
.scan-pied {
  margin-top: 24px;
}

/* Le bouton secondaire garde son libelle sur une ligne ; le principal prend le reste. */
.scan-pied .autodiag-bouton {
  flex: none;
  white-space: nowrap;
}

.scan-pied .autodiag-bouton--primaire {
  flex: 1;
  width: auto;
}

.scan-titre {
  margin: 26px 0 0;
  font-size: 30px;
  font-weight: 300;
  line-height: 1.2;
  letter-spacing: -0.2px;
  color: var(--couleur-texte-fort);
}

.scan-phrase {
  margin: 0;
  max-width: 560px;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--couleur-texte);
}

.scan-lien {
  color: var(--couleur-texte-fort);
  text-decoration: underline;
}

.scan-attente {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 15px;
  color: var(--couleur-texte-fort);
}

.scan-faces {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 18px;
  border-radius: var(--rayon-carte);
  background: var(--couleur-surface);
}

.scan-faces__vignettes {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}

.scan-faces__rang {
  margin-top: 8px;
  font-size: 10.5px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--couleur-texte-discret);
}

.scan-gestes {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

/* Dans le pave des faces, les boutons sont des gestes secondaires. */
.scan-gestes .autodiag-bouton {
  height: 44px;
  padding: 0 18px;
  font-size: 14px;
}

.scan-gestes .autodiag-bouton--primaire {
  width: auto;
  padding: 0 18px;
}

/*
 * La fiche lue : le moment de la demonstration. Bordee d'accent comme sur l'ecran
 * connecte, et c'est tout ce que cette page montre — aucune ligne de la base.
 */
.scan-fiche {
  padding: 18px;
  border: 1.5px solid var(--couleur-accent);
  border-radius: var(--rayon-carte);
  background: var(--couleur-surface);
}

.scan-fiche__titre {
  font-size: 10.5px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--couleur-texte-discret);
}

.scan-fiche__champs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 24px;
  margin: 16px 0 0;
}

.scan-fiche__champ {
  min-width: 0;
}

.scan-fiche__libelle {
  font-size: 11px;
  letter-spacing: 0.3px;
  color: var(--couleur-texte-discret);
}

.scan-fiche__valeur {
  margin: 2px 0 0;
  font-size: 15.5px;
  line-height: 1.35;
  color: var(--couleur-texte-fort);
  overflow-wrap: anywhere;
}

.scan-message {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--couleur-texte);
}

/*
 * Le bouton de scan de l'etape des coordonnees du diagnostic.
 *
 * En bordure d'accent et non en fond plein : « Voir mon resultat » est l'action de
 * l'ecran, et deux boutons pleins se disputeraient l'oeil. Pose AU-DESSUS des six
 * champs, c'est le premier geste de l'etape — il doit se voir avant qu'on ait
 * commence a taper.
 */
.autodiag-scan {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 20px;
}

.autodiag-scan__bouton {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
  min-height: 48px;
  padding: 10px 20px;
  border: 1.5px solid var(--couleur-accent);
  border-radius: var(--rayon-bouton);
  background: transparent;
  color: var(--couleur-texte-fort);
  font-size: 14.5px;
  font-weight: 500;
  line-height: 1.25;
  text-align: left;
  cursor: pointer;
}

.autodiag-scan__bouton svg {
  flex: none;
  color: var(--couleur-accent);
}

.autodiag-scan__phrase {
  flex: 1;
  min-width: 220px;
  margin: 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--couleur-texte);
}

/* Le pave des faces prises et l'attente respirent sous le bouton. */
.autodiag-scan ~ .scan-faces,
.autodiag-scan ~ .scan-attente,
.autodiag-scan ~ .scan-message {
  margin-top: 14px;
}

.scan-champ-cache {
  display: none;
}

@media (max-width: 720px) {
  .scan-titre {
    font-size: 25px;
  }

  /*
   * Sur un telephone, le bouton prend la largeur et la phrase passe dessous : cote a
   * cote, il ne restait a chacun qu'une demi-colonne, et les deux cassaient.
   */
  .autodiag-scan__bouton {
    width: 100%;
    justify-content: center;
    text-align: center;
  }

  .autodiag-scan__phrase {
    min-width: 0;
  }

  /* Deux colonnes de fiche ne tiennent pas sur un telephone. */
  .scan-fiche__champs {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ------------------------------------------------------------------ *
 * Consommation de la cle du modele — point 20
 *
 * Le bandeau vit entre l'en-tete et le contenu, dans la colonne de droite
 * du gabarit. Il est « flex: none » parce que cette colonne est un flex
 * vertical dont le <main> prend le reste : sans cela le bandeau se
 * comprimerait a zero des que la page deborde.
 *
 * Il n'est peint que quand le seuil est franchi. Le rouge d'alerte reste
 * en trait et en texte, jamais en aplat plein largeur : une barre rouge
 * sur toute la largeur de l'ecran, pendant toute une demonstration,
 * deviendrait le sujet a la place du portail.
 * ------------------------------------------------------------------ */

.bandeau-quota {
  flex: none;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 26px;
  border-bottom: 1px solid var(--couleur-alerte);
  background: var(--couleur-surface-3);
  font-size: 13px;
  line-height: 1.4;
  color: var(--couleur-texte);
}

.bandeau-quota[hidden] {
  display: none;
}

.bandeau-quota__icone {
  flex: none;
  display: inline-flex;
  color: var(--couleur-alerte);
}

.bandeau-quota__texte {
  min-width: 0;
  color: var(--couleur-texte-fort);
}

.bandeau-quota__lien {
  flex: none;
  color: var(--couleur-lien);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.bandeau-quota__lien:hover {
  color: var(--couleur-lien-survol);
}

.bandeau-quota__fermer {
  flex: none;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: var(--rayon-champ);
  background: transparent;
  color: var(--couleur-texte-discret);
  cursor: pointer;
}

.bandeau-quota__fermer:hover {
  background: var(--couleur-surface);
  color: var(--couleur-texte-fort);
}

/*
 * La jauge de l'ecran. Le trait du seuil est pose par une variable en
 * ligne : c'est une position, pas une couleur, et la vue peut donc la
 * calculer sans ecrire de couleur hors de ce fichier.
 */
.jauge-quota {
  position: relative;
  height: 10px;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-bordure-3);
  overflow: hidden;
}

.jauge-quota__remplissage {
  height: 100%;
  border-radius: var(--rayon-pilule);
  background: var(--couleur-accent);
}

.jauge-quota__remplissage.est-en-alerte {
  background: var(--couleur-alerte);
}

.jauge-quota__seuil {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  left: var(--position-seuil, 80%);
  background: var(--couleur-texte-fort);
  opacity: 0.55;
}

/* Une valeur du releve : l'intitule au-dessus, le chiffre en dessous. */
.valeur-quota {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.valeur-quota__intitule {
  font-family: var(--police-nav);
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--couleur-texte-discret);
}

.valeur-quota__chiffre {
  font-family: var(--police-titre);
  font-size: 24px;
  font-weight: 300;
  color: var(--couleur-texte-fort);
}

.champ-seuil {
  width: 96px;
  height: 40px;
  padding: 0 12px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-champ);
  background: var(--couleur-champ-fond);
  color: var(--couleur-texte-fort);
  font-size: 14px;
}

.champ-seuil:focus {
  outline: none;
  border-color: var(--couleur-accent);
}

/* Retour d'une action : la couleur porte le sens, le texte le redit. */
.retour-quota {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 11px 15px;
  border: 1px solid var(--couleur-bordure-3);
  border-radius: var(--rayon-carte);
  background: var(--couleur-surface-3);
  font-size: 13px;
  color: var(--couleur-texte);
}

.retour-quota--ko {
  border-color: var(--couleur-alerte);
}

@media (max-width: 900px) {
  .bandeau-quota {
    padding: 10px 18px;
    flex-wrap: wrap;
  }
}

/* ------------------------------------------------------------------ *
 * Verdict du viseur sur une image relevée — point 08d
 *
 * Une pastille sous la vignette, qui dit si le détecteur a eu raison.
 * Deux fautes sont peintes et rien d'autre : le faux positif en rouge,
 * la carte manquée en ambre. Les deux succès et le hors-jugement
 * restent discrets — une grille où tout est coloré ne montre rien.
 * ------------------------------------------------------------------ */

.verdict {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 9px;
  border: 1px solid var(--couleur-bordure);
  border-radius: var(--rayon-pilule);
  font-size: 11px;
  letter-spacing: 0.4px;
  color: var(--couleur-texte-discret);
  white-space: nowrap;
}

.verdict--faux-positif {
  border-color: var(--couleur-alerte);
  color: var(--couleur-alerte);
}

.verdict--manquee {
  border-color: var(--couleur-vigilance);
  color: var(--couleur-vigilance);
}

/* Le score qui a fait basculer, en chiffres tabulaires pour que les pastilles s'alignent. */
.verdict__score {
  font-family: var(--police-mono);
  font-variant-numeric: tabular-nums;
  opacity: 0.85;
}
