/* ============================================================================
   ecran-matchs.css - Complément de l'écran Rapprochement (S5).
   Complète app.css, ne le double pas. Aucune valeur hors token.

   VERSION SOCLE - ne restent que les contacts proposés et leurs critères
   comparés. Sont partis avec la simplification du 12 août 2026 : la bascule de
   sens, le panneau « voir la source » et son extrait surligné, les cases à
   cocher de la shortlist, le compteur d'envoi partiel et la citation posée sur
   la carte de liste. Feuille complète dans
   `.archive/2026-08-12_avant-simplification/ecran-matchs.css`.
   ========================================================================== */

/* --- 1. Contacts proposés (vue détail) ------------------------------------ */

.ecran-matchs__detail { display: block; }
.ecran-matchs__detail .section-titre:first-child { margin-top: var(--sp-4); }

.ecran-matchs__destinataires {
  display: grid; gap: var(--sp-2);
  margin-top: var(--sp-2);
}

.ecran-matchs__dest {
  padding: var(--sp-3);
  background: var(--surface-creuse);
  border: 1px solid var(--ligne);
  border-radius: var(--r-1);
}

/* L'identité absorbe la place libre, ce qui pousse la note contre le bord
   droit du label. Sans `flex: 1`, elle reste dimensionnée par son texte et la
   note se pose juste après le nom : deux lignes aux noms de longueurs
   différentes n'ont alors pas le même bord, et la colonne n'existe plus. */
.ecran-matchs__ident { min-width: 0; flex: 1 1 auto; }

.ecran-matchs__nom {
  display: block;
  font-size: var(--fs-corps); line-height: 1.3;
  font-weight: var(--gras-titre); letter-spacing: -.008em;
  color: var(--encre);
}
.ecran-matchs__fonction {
  display: block;
  font-size: var(--fs-meta); line-height: var(--lh-meta);
  color: var(--encre-douce);
}

/* --- LA NOTE, EN COLONNE ALIGNÉE -------------------------------------------
   Largeur fixe et chiffres tabulaires : deux à dix notes ont le même bord
   droit au pixel, donc elles se comparent d'un regard au lieu de se lire une
   par une. Trois encres, aucun fond : la pastille d'origine ajoutait un objet
   là où une couleur de texte suffit. */
.ecran-matchs__note {
  flex: none;
  width: var(--note-large);
  text-align: right;
  font-size: var(--fs-titre); line-height: 1.2;
  font-weight: var(--gras-titre); letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  color: var(--encre);
}
.ecran-matchs__note--haute { color: var(--succes-encre); }
.ecran-matchs__note-unite {
  font-size: var(--fs-meta); font-weight: var(--gras-corps);
  color: var(--encre-douce);
}
.ecran-matchs__dest.est-exclu .ecran-matchs__note { color: var(--encre-douce); }

/* La légende, une fois pour toute la liste. */
.ecran-matchs__legende { margin: var(--sp-1) 0 0; }

/* Le corps de la ligne s'aligne sous le nom, sauf quand la largeur est trop
   rare pour offrir la gouttière. */
.ecran-matchs__dest > .ecran-matchs__raisons,
.ecran-matchs__dest > .ecran-matchs__manques,
.ecran-matchs__dest > .ecran-matchs__rouvert {
  margin-left: calc(20px + var(--sp-2));
}
@media (max-width: 480px) {
  .ecran-matchs__dest > .ecran-matchs__raisons,
  .ecran-matchs__dest > .ecran-matchs__manques,
  .ecran-matchs__dest > .ecran-matchs__rouvert { margin-left: 0; }
}

/* --- 2. Raisons structurées - la preuve que ce n'est pas un filtre --------- */

/* Le nombre de colonnes se déduit de la place réelle et non de la largeur de
   fenêtre : la colonne principale fait 440 px à 1160 et 720 px à 1440, une
   règle accrochée à la fenêtre repliait donc la moitié des critères. */
.ecran-matchs__raisons {
  display: grid; gap: 2px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--critere-min)), 1fr));
  column-gap: var(--sp-4);
  font-size: var(--fs-meta); line-height: var(--lh-meta);
  color: var(--encre);
}
.ecran-matchs__raisons li { padding-left: var(--sp-3); position: relative; }
.ecran-matchs__raisons li::before {
  content: "·"; position: absolute; left: var(--sp-1);
  color: var(--encre-douce); font-weight: var(--gras-titre);
}

/* --- 3. Critères non couverts --------------------------------------------
   Un cran au-dessus des critères couverts, pas deux : c'est ce qui fera
   hésiter avant d'envoyer, donc ça ne peut pas se lire comme une note de bas
   de page. Mais ce n'est pas une alerte non plus - le bien reste proposable.
   D'où le fond d'alerte le plus pâle du jeu de jetons, et rien de plus : ni
   bordure épaisse, ni gras, ni majuscules.                                 */

.ecran-matchs__manques {
  margin-top: var(--sp-2);
  padding: var(--sp-2);
  border-radius: var(--r-1);
  background: var(--alerte-fond);
  color: var(--alerte-encre);
}

.ecran-matchs__manques-titre {
  display: flex; align-items: center; gap: var(--sp-1);
  margin: 0;
  font-size: var(--fs-meta); line-height: var(--lh-meta);
  font-weight: var(--gras-titre);
  color: var(--alerte-encre);
}
.ecran-matchs__manques-titre .icone { width: 16px; height: 16px; flex: none; }

.ecran-matchs__manques-liste {
  display: grid; gap: 2px;
  margin-top: var(--sp-1);
  font-size: var(--fs-meta); line-height: var(--lh-meta);
}
/* L'écart en tête de ligne : ce qui se lit, avant le détail qui le prouve. */
.ecran-matchs__ecart {
  display: inline-block;
  margin-right: var(--sp-1);
  padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--alerte-encre);
  color: var(--papier);
  font-size: var(--fs-meta);
  font-weight: var(--gras-titre);
  font-variant-numeric: tabular-nums;
}

.ecran-matchs__manques-liste li { padding-left: var(--sp-3); position: relative; }
.ecran-matchs__manques-liste li::before {
  content: "·"; position: absolute; left: var(--sp-1); font-weight: var(--gras-titre);
}

/* --- 4. Ligne ouvrable (sens « acquéreur → biens ») -----------------------
   Chaque ligne est un bien : elle s'ouvre en panneau latéral. C'est donc un
   <button>, avec la cible, le survol et le focus qui vont avec.            */

.ecran-matchs__dest--ouvrable {
  display: block; width: 100%; text-align: left;
  position: relative;
  font: inherit; color: inherit;
  cursor: pointer;
  padding-right: var(--sp-6);
  transition: border-color var(--duree-1) var(--courbe),
              background var(--duree-1) var(--courbe);
}
.ecran-matchs__dest--ouvrable:hover {
  border-color: var(--ligne-forte);
  background: var(--surface);
}
.ecran-matchs__dest--ouvrable:focus-visible {
  outline: var(--focus-largeur) solid var(--focus);
  outline-offset: 2px;
}
.ecran-matchs__chevron {
  position: absolute; top: var(--sp-3); right: var(--sp-2);
  color: var(--encre-douce);
}

/* Descriptif du mandat, en tête du panneau : la prose du CRM, rien d'autre. */
.ecran-matchs__description {
  margin-top: var(--sp-3);
  font-size: var(--fs-corps); line-height: var(--lh-corps);
  color: var(--encre);
}

/* Titre de section à l'intérieur du panneau latéral. */
.ecran-matchs__soustitre {
  margin: var(--sp-3) 0 var(--sp-1);
  font-size: var(--fs-meta); line-height: var(--lh-meta);
  font-weight: var(--gras-titre); color: var(--encre-douce);
  text-transform: uppercase; letter-spacing: .04em;
}
.ecran-matchs__criteres .ecran-matchs__manques { margin-top: var(--sp-3); }

/* --- Recherche : lancer un rapprochement sur son pool ---------------------- */

.ecran-matchs__recherche { margin-bottom: var(--sp-3); }
.ecran-matchs__champ-recherche {
  width: 100%;
  min-height: var(--cible);
  padding: 0 var(--sp-3);
  border: 1px solid var(--ligne-forte); border-radius: var(--r-1);
  background: var(--surface);
  font: inherit;
}
.ecran-matchs__champ-recherche:focus-visible {
  outline: var(--focus-largeur) solid var(--focus); outline-offset: 2px;
}
.ecran-matchs__resultats { display: grid; gap: var(--sp-1); margin-top: var(--sp-1); }
.ecran-matchs__resultat {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  width: 100%;
  min-height: var(--cible);
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--ligne); border-radius: var(--r-1);
  background: var(--surface-creuse); color: var(--encre);
  font: inherit; text-align: left; cursor: pointer;
}
.ecran-matchs__resultat:hover { border-color: var(--ligne-forte); background: var(--surface); }
.ecran-matchs__resultat:focus-visible {
  outline: var(--focus-largeur) solid var(--focus); outline-offset: 2px;
}
.ecran-matchs__resultat-corps { min-width: 0; }
.ecran-matchs__resultat-action {
  flex: none;
  font-size: var(--fs-meta); font-weight: var(--gras-titre);
  /* `--accent-encre` EST défini (blanc, pour le texte posé SUR l'accent) :
     la valeur de repli n'avait donc jamais lieu et le libellé sortait en
     blanc sur fond clair, à 1,06:1. C'est le déclencheur manuel, le
     cinquième de la chaîne, et il était illisible. */
  color: var(--encre);
  font-weight: var(--gras-titre);
  white-space: nowrap;
}

/* Réponse du prospect, recueillie par la page publique du bien. Le OUI est
   la seule bonne nouvelle de la file : fond succès, et la suite en toutes
   lettres. */
.ecran-matchs__dest--interesse {
  background: var(--succes-fond);
  border-color: var(--succes-fond);
}
.ecran-matchs__reponse {
  margin-top: var(--sp-1);
  font-size: var(--fs-meta); line-height: var(--lh-meta);
  font-weight: var(--gras-titre);
  color: var(--succes-encre);
}
.ecran-matchs__reponse--non { color: var(--alerte-encre); }
.ecran-matchs__suite .btn { margin-top: var(--sp-2); }
.ecran-matchs__suite {
  margin-top: 2px;
  font-size: var(--fs-meta); line-height: var(--lh-meta);
  color: var(--encre);
}

/* --- 5. Mémoire des couples ------------------------------------------------
   Une ligne terminée (proposée par un collègue, écartée) RESTE affichée :
   c'est elle qui explique pourquoi on ne re-propose pas. Encre douce plutôt
   qu'opacité, pour que le texte reste au-dessus de 4,5:1.                  */

.ecran-matchs__dest--bloque { background: var(--surface); }
.ecran-matchs__dest--bloque .ecran-matchs__nom {
  color: var(--encre-douce);
  font-weight: var(--gras-appui);
}
.ecran-matchs__memoire {
  margin-top: var(--sp-1);
  font-size: var(--fs-meta); line-height: var(--lh-meta);
  color: var(--encre-douce);
}

.ecran-matchs__dest .reserve { margin-top: var(--sp-2); }

/* ===========================================================================
   7. SÉLECTION AVANT ENVOI (ajout du 19/08)

   Une proposition est retenue par défaut ; la case sert à RETIRER. Décocher
   doit donc se voir sans ambiguïté, sur la ligne comme sur le compteur :
   une ligne exclue s'éteint mais reste lisible, parce qu'on doit pouvoir
   relire ce qu'on vient d'écarter avant d'envoyer.
   ======================================================================== */

.ecran-matchs__selection {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3);
  margin-top: var(--sp-2);
}
.ecran-matchs__compteur { margin: 0; }

.ecran-matchs__dest-tete {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--sp-2);
}

/* Toute la tête est cliquable : la cible dépasse largement 44 px. */
.ecran-matchs__case {
  display: flex; align-items: flex-start; gap: var(--sp-2);
  min-width: 0; flex: 1 1 auto;
  min-height: var(--cible);
  padding: 2px 0;
  cursor: pointer;
}
.ecran-matchs__case:focus-within {
  outline: var(--focus-largeur) solid var(--focus);
  outline-offset: var(--focus-ecart);
  border-radius: var(--r-1);
}
.ecran-matchs__case input[type="checkbox"] {
  width: 20px; height: 20px;
  margin: 1px 0 0;
  accent-color: var(--accent);
  flex: none;
  cursor: pointer;
}

/* Exclue : atténuée PAR LA COULEUR, jamais par l'opacité.

   `opacity: .5` faisait tomber les critères à 3,40:1, le bloc « critère non
   couvert » à 2,37:1 et la pastille de note à 2,40:1, tous sous le seuil AA,
   alors que le commentaire d'origine affirmait le contraire : il ne mesurait
   que le nom. Une encre choisie tient sa promesse, une opacité la dilue.

   Et le fond seul ne suffisait pas à distinguer une ligne retirée d'une ligne
   retenue : 4 % d'écart de luminance, invisible. D'où le liseré, qui se voit
   en niveaux de gris comme en couleur. */
.ecran-matchs__dest.est-exclu {
  background: var(--surface);
  /* Ombre INTERNE et non bordure : une bordure consomme de la largeur et
     décale tout le contenu de la ligne de 3 px. Invisible tant que la note
     flottait, fatal dès qu'elle devient une colonne alignée au pixel. */
  box-shadow: inset 3px 0 0 var(--ligne-forte);
}
.ecran-matchs__dest.est-exclu .ecran-matchs__nom,
.ecran-matchs__dest.est-exclu .ecran-matchs__raisons,
.ecran-matchs__dest.est-exclu .ecran-matchs__manques-liste { color: var(--encre-douce); }
.ecran-matchs__dest.est-exclu .ecran-matchs__manques {
  background: var(--surface-creuse);
  border-color: var(--ligne);
}
.ecran-matchs__dest.est-exclu .ecran-matchs__manques-titre { color: var(--encre-douce); }

/* Le chevron n'est plus la ligne entière : c'est un bouton à lui, posé à
   côté de la case, pour que deux gestes distincts aient deux cibles. */
.ecran-matchs__ouvrir { flex: none; color: var(--encre-douce); }
.ecran-matchs__ouvrir:hover { color: var(--encre); }

/* ===========================================================================
   8. HISTORIQUE DES ENVOIS (ajout du 19/08)

   La mémoire des couples, lue par un bout : depuis un bien, les acquéreurs
   servis ; depuis un acquéreur, les biens proposés. Chaque ligne porte son
   issue, parce qu'un envoi sans réponse et un refus ne se travaillent pas de
   la même façon.
   ======================================================================== */

.ecran-matchs__historique { margin-top: var(--sp-2); }

.ecran-matchs__historique-liste {
  display: grid; gap: var(--sp-1);
  margin: 0; padding: 0; list-style: none;
}

.ecran-matchs__envoi {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  background: var(--surface-creuse);
  border: 1px solid var(--ligne);
  border-radius: var(--r-1);
}
.ecran-matchs__envoi-corps { display: grid; gap: 2px; min-width: 0; }

/* Les deux mesures de droite : combien de fois vu, et où en est la réponse.
   Largeur FIXE, pour qu'elles s'alignent d'une ligne à l'autre et se lisent
   en colonne - c'est ce qui permet de balayer la liste au lieu de la lire. */
.ecran-matchs__envoi-mesures {
  display: flex; align-items: center; justify-content: flex-end;
  gap: var(--sp-3);
  flex: none;
}

.ecran-matchs__vues {
  display: inline-flex; align-items: center; gap: 4px;
  min-width: 3ch; justify-content: flex-end;
  font-size: var(--fs-meta); font-variant-numeric: tabular-nums;
  color: var(--encre-douce);
}
.ecran-matchs__vues svg { width: 16px; height: 16px; flex: none; }

.ecran-matchs__statut {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; flex: none;
  border-radius: var(--r-pill);
}
.ecran-matchs__statut svg { width: 15px; height: 15px; }

/* Trois états, trois couleurs, et jamais la couleur SEULE : la forme de
   l'icône distingue déjà attente, validé et refusé pour qui ne perçoit pas
   les teintes (critère a11y). */
.ecran-matchs__statut--attente { background: var(--surface); color: var(--encre-douce); }
.ecran-matchs__statut--valide  { background: var(--succes-fond); color: var(--succes-encre); }
.ecran-matchs__statut--refuse  { background: var(--alerte-fond); color: var(--alerte-encre); }

/* ===========================================================================
   9. RÉSULTAT DE RECHERCHE À DEUX GESTES (ajout du 19/08)

   Lancer un rapprochement et consulter l'historique sont deux actions : le
   résultat n'est donc plus un bouton unique, mais une rangée qui en porte
   deux. En dessous de 480 px, elles passent sous le nom plutôt que de le
   comprimer.
   ======================================================================== */

/* Le résultat est redevenu UN bouton : un clic, une fiche. Le chevron dit
   qu'il ouvre, il ne prétend pas être une seconde action. */
.ecran-matchs__resultat-chevron { flex: none; color: var(--encre-douce); }

/* Le geste, en tête de fiche et en pleine largeur : on n'ouvre pas une fiche
   depuis la recherche pour la lire, on l'ouvre pour décider. */
.ecran-matchs__action-fiche { margin: 0 0 var(--sp-4); }
.ecran-matchs__action-fiche .btn { width: 100%; }

/* ===========================================================================
   10. L'HISTORIQUE, CADRE DÉTACHÉ À DROITE (ajout du 20/08)

   Sur mobile, tout se lit en une colonne : les propositions, le brouillon,
   puis l'historique. Passé 1024 px la colonne devient trop longue pour qu'on
   voie les deux à la fois, alors que c'est exactement ce qu'on veut - décider
   d'un envoi EN AYANT sous les yeux ce qui est déjà parti.

   L'historique se détache donc dans son propre cadre, à droite, et il colle
   au défilement : la liste des propositions peut être longue, la mémoire du
   couple reste visible pendant qu'on la parcourt.

   Une seule mise en page, deux largeurs : le DOM ne change pas, seul le
   placement change. Rien n'est dupliqué, rien n'est masqué.
   ======================================================================== */

.ecran-matchs__cote { display: block; }
.ecran-matchs__cote .section-titre:first-child { margin-top: var(--sp-4); }

/* 1160 px, et pas 1024. Les deux pistes exigeaient 460 + 440 + 20 de
   gouttière, soit 840 px de contenu, alors qu'à 1024 px de fenêtre il n'en
   reste que 760 une fois le rail de navigation et les marges déduits. Les
   pistes `minmax` ne descendent pas sous leur minimum : la grille débordait
   de 65 px, et `.carte { overflow: hidden }` coupait le dépassement en
   silence. Ce qui sortait de l'écran était exactement la colonne de droite de
   l'historique, donc le compteur de vues et la pastille d'état. */
@media (min-width: 1160px) {
  /* LA GRILLE À DEUX COLONNES EST NEUTRALISÉE (22/08) : l'historique vit dans
     la fiche, il n'y a plus qu'un enfant à placer, et une grille à une colonne
     laissait 400 px de vide à droite. La règle reste écrite pour le jour où un
     second panneau reviendra. */
  .ecran-matchs__detail--deux-colonnes {
    display: grid;
    /* Le contenu principal ne descend jamais sous 460 px : en dessous, les
       lignes de proposition (case + nom + critères) se replient et la grille
       coûte plus qu'elle ne rapporte. Le panneau, lui, est à largeur fixe :
       c'est une liste de faits courts, elle n'a pas besoin de respirer. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
    column-gap: var(--sp-5);
    align-items: start;
  }
  /* Deux enfants, deux colonnes. Aucune règle de placement à écrire : la
     grille n'a pas de rangée à répartir, donc pas de hauteur à combler. */
  .ecran-matchs__principal { min-width: 0; }

  .ecran-matchs__cote {
    position: sticky;
    top: var(--sp-4);
    padding: var(--sp-2) var(--sp-3) var(--sp-3);
    border: 1px solid var(--ligne);
    border-radius: var(--r-2);
    background: var(--papier);
    max-height: calc(100vh - var(--sp-8, 48px));
    overflow-y: auto;
  }
  .ecran-matchs__cote .section-titre:first-child { margin-top: var(--sp-1); }

  /* --- REMPLIR LA LARGEUR, pas seulement l'occuper ------------------------
     Les blocs ci-dessous sont des listes de FAITS COURTS : un libellé, une
     valeur. Empilés sur une seule colonne de 1 000 px, ils laissent les deux
     tiers de chaque ligne vides et allongent la page pour rien. À deux
     colonnes, la même matière tient sur moitié moins de hauteur et se lit
     d'un regard.

     Les règles sont accrochées à `.colonne--colonnes`, jamais à la largeur
     de fenêtre seule : les écrans restés en colonne de lecture (Relances,
     Dictée) ont la même classe `.champs` mais 640 px, où deux colonnes
     serreraient les valeurs jusqu'à les tronquer. */
  .colonne--colonnes .carte--detail > .carte__tap > .carte__corps > .champs {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--sp-4);
  }
  /* Dans le cadre, les lignes n'ont plus besoin de leur propre fond : le
     cadre les contient déjà. Une seule bordure, pas deux imbriquées. */
  .ecran-matchs__cote .ecran-matchs__envoi {
    background: var(--surface);
    padding: var(--sp-2);
  }
}

/* Un « oui » n'est pas une archive : la ligne porte le fond succès et le
   bouton qui ouvre la suite. */
.ecran-matchs__envoi--valide { background: var(--succes-fond); border-color: var(--succes-fond); }
.ecran-matchs__cote .ecran-matchs__envoi--valide { background: var(--succes-fond); }
.ecran-matchs__envoi .ecran-matchs__suite { margin-top: var(--sp-2); }
.ecran-matchs__envoi .ecran-matchs__suite .btn { width: 100%; }

/* Une proposition qui revient après un refus levé : elle porte sa raison, et
   un liseré qui la distingue d'une proposition neuve. Fond neutre, pas
   d'alerte : c'est une bonne nouvelle, pas un problème. */
.ecran-matchs__dest--rouvert { box-shadow: inset 3px 0 0 var(--accent); }

.ecran-matchs__rouvert {
  display: flex; align-items: center; gap: 6px;
  margin: var(--sp-1) 0 0;
  font-size: var(--fs-meta); line-height: var(--lh-meta);
  color: var(--encre-douce);
}
.ecran-matchs__rouvert svg { width: 15px; height: 15px; flex: none; }

/* Le brouillon se dimensionne sur son contenu (voir `ajusterHauteur`). Deux
   bornes : jamais plus de 60 % de la hauteur d'écran, pour que les boutons
   d'envoi restent atteignables, et jamais plus large que 68 caractères, parce
   qu'un message relu en diagonale ne se lit pas sur 130 signes. */
.ecran-matchs__brouillon .champ-saisie {
  max-height: 60vh;
  overflow-y: auto;
  resize: vertical;
}
@media (min-width: 1160px) {
  .ecran-matchs__brouillon .champ-saisie { max-width: 68ch; }
}
