/* ============================================================================
   Pipeline — prospection et livraison

   Variables reprises du kanban V2 : c'est le choix esthetique existant, et
   l'ambre s'accordait deja avec l'etoile Google du prospecteur (#f0c14b).

   Ecrit en mobile d'abord. Ce n'est pas une preference de style : l'outil sert
   debout devant un commerce, le telephone dans une main. La version large est
   l'exception qu'on ajoute ensuite, pas l'inverse.
   ========================================================================= */

:root {
  --bg: #0d0f12;
  --bg-2: #15181d;
  --panel: #181c22;
  --panel-2: #1d222a;
  --line: #262c35;
  --line-2: #313945;
  --txt: #e7e9ee;
  --muted: #9aa3b0;
  --faint: #6b7480;

  --amber: #f0b429;
  --amber-dim: #3a2f12;
  --cyan: #38bdf8;
  --green: #34d399;
  --red: #ff5d5d;
  --slate: #7c8aa0;

  --mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --sans: "Sora", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  --radius: 12px;
  --shadow: 0 8px 30px rgba(0, 0, 0, .45);

  /* Hauteur minimale des cibles tactiles. En dessous de 44 px on rate sa
     cible au doigt — c'est le defaut que presentaient les deux applications,
     l'une a 33 px, l'autre a 30. */
  --touch: 44px;

  --barre-onglets: 62px;
}

* { box-sizing: border-box; }

html, body { margin: 0; height: 100%; }

body {
  background: var(--bg);
  color: var(--txt);
  font: 15px/1.55 var(--sans);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  -webkit-text-size-adjust: 100%;
}

/* ------------------------------------------------------------------ barre */

.barre {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 10px 12px;
  background: linear-gradient(180deg, rgba(21, 24, 29, .95), rgba(13, 15, 18, .85));
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}

.marque {
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  font-size: 14px;
  color: var(--amber);
}

input, select, textarea, button {
  font: inherit;
  font-family: var(--sans);
  color: var(--txt);
  background: var(--panel-2);
  border: 1px solid var(--line-2);
  border-radius: 10px;
  padding: 10px 12px;
  min-height: var(--touch);
}
input::placeholder { color: var(--faint); }
input:focus-visible, select:focus-visible, textarea:focus-visible, button:focus-visible {
  outline: 2px solid var(--amber);
  outline-offset: 1px;
}

button { cursor: pointer; }
button:hover:not(:disabled) { background: #242a33; }
button:disabled { opacity: .5; cursor: default; }


.stats {
  display: flex;
  gap: 14px;
  font-size: 13px;
  color: var(--muted);
  margin-left: auto;
}
.stats b { color: var(--txt); font-weight: 600; }

/* ------------------------------------------------------------ progression */

.progression {
  background: var(--bg-2);
  border-bottom: 1px solid var(--line);
  padding: 10px 12px;
  max-height: 30vh;
  overflow: auto;
  flex: 0 0 auto;
}
.progression-titre { font-weight: 600; margin-bottom: 6px; font-size: 14px; }
.progression pre {
  margin: 0;
  font: 12px/1.5 var(--mono);
  color: var(--muted);
  white-space: pre-wrap;
}

/* ------------------------------------------------------------------ vues

   Sous 900 px, une seule vue est visible a la fois ; la barre d'onglets basse
   pilote `data-vue` sur le body. Au-dessus, les colonnes coexistent.        */

.grille {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
}

/* Retour Carte / Aujourd'hui / Liste : seulement sous 900 px, a la place
   de l'ancienne barre d'onglets du bas. */
.vue-mobile-nav {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 8px 12px;
  flex: 0 0 auto;
  border-bottom: 1px solid var(--line);
  background: var(--bg-2);
}
.vue-mobile-nav button,
.btn-revenir-carte {
  min-height: var(--touch);
  padding: 0 14px;
  font-size: 13.5px;
  font-weight: 600;
}

.carte-liste {
  flex: 0 0 auto;
  min-height: var(--touch);
  padding: 0 16px;
  border-radius: 10px;
  background: rgba(24, 28, 34, .95);
  border: 1px solid var(--line-2);
  color: var(--txt);
  font-size: 13.5px;
  font-weight: 600;
}
/* Cadre pose : la liste ne montre plus que ce que la carte encadre. Sans ce
   retour, la carte et la liste divergent sans que rien ne le dise. */
.carte-liste[aria-pressed="true"] {
  border-color: var(--amber);
  color: var(--amber);
  background: var(--amber-dim);
}

.grille > [data-vue] {
  display: none;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
}
body[data-vue="liste"]  .grille > [data-vue="liste"],
body[data-vue="carte"]  .grille > [data-vue="carte"],
body[data-vue="aujourdhui"] .grille > [data-vue="aujourdhui"] { display: flex; }

.panneau { background: var(--panel); flex-direction: column; }

/* La fiche vit dans #dlg-fiche : plus une vue, une popup par-dessus la carte.
   La classe ne porte que la typographie du contenu — placement et defilement
   viennent de .modale / .modale-corps. */
.fiche { background: var(--panel); }

.carte-zone { position: relative; }
#carte { position: absolute; inset: 0; background: var(--panel-2); }

/* --------------------------------------------------------------- filtres */

/* Les deux volets — Filtres et Outils — partagent une ligne tant qu'ils sont
   replies. Des qu'on en ouvre un, il reprend toute la largeur et repousse
   l'autre sous lui : `flex-basis: 100%` dans un conteneur qui enroule suffit,
   sans une ligne de JS. Deux poignees empilees coutaient 90 px d'en-tete
   permanent sur telephone, pour deux mots. */
.volets {
  display: flex;
  flex-wrap: wrap;
  flex: 0 0 auto;
}
.volets > details { flex: 1 1 auto; min-width: 0; }
.volets > details[open] { flex-basis: 100%; }
/* Le filet ne separe les deux que lorsqu'ils sont reellement cote a cote —
   c'est-a-dire quand aucun des deux n'est ouvert. */
.volets > details:not([open]) + details:not([open]) { border-left: 1px solid var(--line); }

.filtres-repli {
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
  background: var(--bg-2);
}
.filtres-repli > summary {
  padding: 12px 14px;
  min-height: var(--touch);
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-weight: 600;
  font-size: 14px;
  list-style: none;
  user-select: none;
}
.filtres-repli > summary::-webkit-details-marker { display: none; }
.filtres-repli > summary::before {
  content: "▸";
  color: var(--amber);
  transition: transform .15s;
}
.filtres-repli[open] > summary::before { transform: rotate(90deg); }

.filtres {
  padding: 4px 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-height: 60vh;
  overflow-y: auto;
}
.filtres > input, .filtres select { width: 100%; }

/* Groupes du panneau. Le titre en ambre et le trait de separation font le
   travail : d'un coup d'oeil on sait a quelle question chaque controle
   repond, sans avoir a lire les quinze libelles. */
.filtres-groupe {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.filtres-groupe:first-of-type { border-top: 0; padding-top: 4px; }
.filtres-groupe > h3 {
  margin: 0;
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--amber);
  font-weight: 600;
}
/* Dans un groupe, les cases se serrent : elles se lisent comme une liste de
   conditions, pas comme des reglages independants. */
.filtres-groupe .bascule { min-height: 32px; }

.champ { display: flex; flex-direction: column; gap: 6px; }
.champ > label {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--muted);
  font-weight: 600;
}

.pastilles { display: flex; flex-wrap: wrap; gap: 7px; }
.pastille {
  font-size: 13px;
  padding: 11px 14px;
  /* 44 px comme le reste : une pastille de filtre se manque au doigt aussi
     facilement qu'un bouton. */
  min-height: var(--touch);
  display: inline-flex;
  align-items: center;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  background: var(--panel-2);
  color: var(--muted);
  cursor: pointer;
  user-select: none;
}
.pastille.on {
  background: var(--amber-dim);
  border-color: var(--amber);
  color: var(--amber);
  font-weight: 500;
}
.pastille .puce {
  display: inline-block;
  width: 8px; height: 8px;
  border-radius: 50%;
  margin-right: 6px;
}

.bascule {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 14px;
  color: var(--muted);
  cursor: pointer;
  min-height: var(--touch);
}
.bascule input { width: 20px; height: 20px; min-height: 0; accent-color: var(--amber); }

.action { width: 100%; }

.quota { font-size: 12.5px; color: var(--muted); text-align: center; }
.quota.chaud { color: var(--amber); }
.quota.plein { color: var(--red); }

/* Compte par secteur. Tabulaire : les chiffres ne dansent pas d'une largeur a
   l'autre quand les comptes changent, la rangee de pastilles reste stable. */
.pastille-n {
  margin-left: 7px;
  font-family: var(--mono);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--faint);
}
.pastille.on .pastille-n { color: var(--amber); }
/* Grisee et non masquee : une pastille qui disparait puis revient fait sauter
   la mise en page a chaque changement de filtre. Elle reste cliquable — on
   peut vouloir la cocher avant d'elargir le reste. */
.pastille.vide { opacity: .42; }

.secteurs-hors { margin-top: 8px; }
.secteurs-hors > summary {
  font-size: 12.5px;
  color: var(--faint);
  cursor: pointer;
  padding: 6px 0;
  user-select: none;
}
.secteurs-hors[open] > summary { color: var(--muted); }
.secteurs-hors .pastilles { margin-top: 6px; }

/* Vues rapides, sous les filtres : les quatre listes de travail reelles. */
.vues {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  padding: 10px 14px 0;
  flex: 0 0 auto;
}
.vues button {
  font-size: 13px;
  padding: 6px 13px;
  min-height: var(--touch);
  border-radius: 999px;
  flex: 0 1 auto;
}
.vues button[aria-pressed="true"] {
  border-color: var(--amber);
  color: var(--amber);
  background: var(--amber-dim);
}

/* Filtres actifs. Hors du panneau repliable, donc toujours lisibles : c'est
   la reponse a « pourquoi ma liste est-elle si courte ». */
.puces-filtres {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 10px 14px 0;
  flex: 0 0 auto;
}
.puce-filtre {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  /* Plus basse que les 44 px de rigueur : c'est une action de retrait, pas
     une cible de travail, et une rangee de puces a cette hauteur mangerait
     l'ecran du telephone des trois filtres. La zone reste au-dessus de 32 px,
     et l'equivalent pleine taille existe dans le panneau. */
  min-height: 34px;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--line-2);
  background: var(--panel-2);
  color: var(--muted);
  cursor: pointer;
  max-width: 100%;
}
.puce-filtre span[aria-hidden] { color: var(--faint); font-size: 15px; line-height: 1; }
.puce-filtre:hover { border-color: var(--amber); color: var(--txt); }
.puce-filtre:hover span[aria-hidden] { color: var(--amber); }
.puce-filtre.effacer { color: var(--faint); border-style: dashed; }

/* Texte reserve aux lecteurs d'ecran : la croix seule ne dit pas ce qu'elle
   retire. */
.sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.compteur {
  padding: 10px 14px;
  font-size: 13px;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}

/* ----------------------------------------------------------- aujourd'hui */

.aujourdhui { flex-direction: column; overflow-y: auto; }
.auj-corps { padding: 0 0 24px; width: 100%; }
.auj-date { padding: 12px 14px 4px; color: var(--muted); font-size: 13px; }
.auj-bloc h3 { margin: 16px 14px 6px; font-size: 14px; }
.auj-n { color: var(--muted); font-weight: 400; }
.auj-vide { padding: 4px 14px 10px; color: var(--muted); font-size: 13px; }
/* Les items reutilisent .item/.score/.etiq de la liste : meme lecture partout. */
.auj-items { flex: 0 0 auto; overflow: visible; }

.onglets .badge {
  background: var(--amber);
  color: #14171e;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  padding: 1px 6px;
  /* Bouton en colonne sur mobile : en flux, la pastille passerait SOUS le
     libelle et grandirait toute la barre. Posee en coin, elle n'occupe rien. */
  position: absolute;
  top: 3px;
  right: 10px;
}

/* Recurrents dans « Chiffres » : un suspendu reste visible mais efface. */
.bord-ligne.rec-pause { opacity: .45; }
.rec-bascule {
  font-size: 11.5px;
  padding: 2px 8px;
  margin-left: 8px;
}

/* ------------------------------------------------------------------ devis */

.devis-liste { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.devis-lien { font-size: 12px; }
/* .devis-compose a disparu avec la creation de devis depuis la carte : arriver
   au devis, c'est etre deja passe dans Odoo, qui porte tarifs et facturation.
   Les devis deja emis restent telechargeables via .devis-lien. */

/* --------------------------------------------------------- actions en lot */

.lot-barre {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
  background: var(--panel-2);
}
.lot-barre select, .lot-barre input, .lot-barre button { font-size: 12.5px; }
#lot-nombre { font-size: 12.5px; color: var(--muted); margin-right: 4px; }

/* Coche distincte de `.actif` (fiche ouverte) : liseret complet, pas un filet. */
.item.coche { outline: 1px solid var(--amber); outline-offset: -1px; background: #241f10; }

/* ----------------------------------------------------------------- liste */

.liste {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  flex: 1 1 auto;
  -webkit-overflow-scrolling: touch;
}

.item {
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  display: grid;
  /* Troisieme colonne : l'etoile de mise de cote, alignee a droite. */
  grid-template-columns: 42px 1fr auto;
  gap: 12px;
  align-items: start;
  min-height: 64px;
}
.item:active { background: var(--panel-2); }
.item.actif { background: #1e2431; box-shadow: inset 3px 0 0 var(--amber); }

.score {
  font: 600 15px/1 var(--mono);
  text-align: center;
  padding: 8px 0;
  border-radius: 8px;
  background: var(--panel-2);
  border: 1px solid var(--line-2);
}
.item-nom { font-weight: 500; font-size: 15px; }
.item-meta {
  font-size: 12.5px;
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 5px;
}

.etiq {
  font-size: 12px;
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--panel-2);
  border: 1px solid var(--line-2);
}
.etiq.etat { color: #10131a; border: none; font-weight: 600; }

/* L'etoile Google : seule information de la ligne dont l'exactitude est
   garantie par un tiers, elle doit se distinguer au premier coup d'oeil. */
.etiq.google { background: var(--amber-dim); border-color: var(--amber); color: var(--amber); }
.etiq.google b { color: #ffd76e; }

.lien-site {
  font-size: 12.5px;
  color: var(--cyan);
  text-decoration: none;
  margin-left: 8px;
  white-space: nowrap;
  padding: 4px 0;
}
.lien-site:hover { text-decoration: underline; }

/* ----------------------------------------------------------------- fiche */

.fiche-vide { color: var(--muted); text-align: center; margin-top: 60px; padding: 0 20px; }
.fiche-soustitre { color: var(--muted); font-size: 13.5px; }

/* En-tete : l'essentiel avant tout depliage — etat du site, contactabilite et
   les deux actions faites cent fois par jour. Volontairement pas collante :
   sur telephone plein ecran, deux rangees figees mangeraient un tiers de la
   hauteur utile, et le nom reste de toute facon visible dans la tete du
   dialog, hors zone de defilement. */
.fiche-entete { display: flex; flex-direction: column; gap: 10px; padding-bottom: 14px; }

/* Deux puces d'etat, sans un mot de droit : le rappel de la LCD occupait
   trois pavés que personne ne relit ici. Ne restent que les deux faits qui
   changent ce qu'on fait du lead — ce numero se compose-t-il, et ce commerce
   est-il deja dans Odoo. */
.fiche-canaux { display: flex; gap: 6px; flex-wrap: wrap; }
.canal { font-size: 12px; padding: 3px 9px; border-radius: 999px; border: 1px solid; }
.canal[title] { cursor: help; }
.canal-ok        { background: #17281c; border-color: #2c4c34; color: var(--green); }
.canal-attention { background: #2b2517; border-color: #5c4a22; color: var(--amber); }
.canal-bloque    { background: #2a1d1d; border-color: #5a3330; color: var(--red); }
.canal-neutre    { background: var(--panel-2); border-color: var(--line-2); color: var(--muted); }

/* Les deux liens sortants d'Odoo : assez espaces pour le pouce, sans devenir
   des boutons qui concurrenceraient les vraies actions au-dessus. */
.odoo-liens { display: flex; gap: 16px; flex-wrap: wrap; font-size: 13.5px; }
.odoo-liens a { padding: 6px 0; }

/* Sections repliables : meme chevron que .filtres-repli, et la typographie des
   anciens h3 de fiche pour ne pas depayser. Neuf blocs empiles rendaient la
   fiche illisible ; repliee, chaque section annonce son contenu par un resume
   et on ne deplie que ce qu'on vient chercher. */
.fiche-section { border-top: 1px solid var(--line); }
.fiche-section > summary {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--touch);
  padding: 12px 0;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.fiche-section > summary::-webkit-details-marker { display: none; }
.fiche-section > summary::before {
  content: "▸";
  color: var(--amber);
  transition: transform .15s;
}
.fiche-section[open] > summary::before { transform: rotate(90deg); }
.fiche-section-titre {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--muted);
  font-weight: 600;
}
/* Le resume ne prend une couleur d'etat que s'il y a une decision a prendre :
   un resume gris informe, un colore appelle. */
.fiche-section-resume { margin-left: auto; font-size: 12.5px; color: var(--faint); text-align: right; }
.resume-ok { color: var(--green); }
.resume-attention { color: var(--amber); }
.resume-bloque { color: var(--red); }

/* L'espacement vertical vient du parent : plus un seul style="margin-top"
   inline dans dessinerFiche. */
.fiche-corps { padding-bottom: 16px; }
.fiche-corps > * + * { margin-top: 10px; }
/* Les blocs qui portent leur propre marge haute (avertissement, bloc-google)
   ouvriraient un trou sous le titre de section quand ils viennent en tete. */
.fiche-corps > :first-child { margin-top: 0; }
.avertissement .rangee { margin-top: 8px; }

/* Libelle au-dessus de la valeur : une colonne de libelles fixe amputait la
   valeur a 166 px sur un panneau de 320, faisant passer a la ligne l'adresse,
   la raison sociale et chaque URL. */
.paire { display: block; margin: 0; }
.paire dt {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--faint);
  margin-top: 10px;
}
.paire dd { margin: 2px 0 0; word-break: break-word; font-size: 14.5px; }

.but {
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted);
  background: var(--panel-2);
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  padding: 12px 14px;
  /* Dix lignes visibles par defaut, contre une seule auparavant. */
  max-height: 15.5em;
  overflow: hidden;
  position: relative;
}
.but.deplie { max-height: none; }
.but:not(.deplie)::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 3em;
  background: linear-gradient(transparent, var(--panel-2));
  pointer-events: none;
}
.but-plus {
  background: none;
  border: none;
  color: var(--cyan);
  padding: 8px 0;
  min-height: 0;
  font-size: 13.5px;
}

.defauts { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.defauts li {
  font-size: 13.5px;
  line-height: 1.5;
  background: #2a1d1d;
  border: 1px solid #4a2b28;
  border-left: 3px solid var(--red);
  border-radius: 8px;
  padding: 10px 12px;
}

.rangee { display: flex; gap: 8px; flex-wrap: wrap; }
.rangee > * { flex: 1 1 auto; }

a.lien { color: var(--cyan); text-decoration: none; }
a.lien:hover { text-decoration: underline; }

.bouton-site {
  display: block;
  text-align: center;
  padding: 12px;
  margin-bottom: 10px;
  border-radius: var(--radius);
  background: #16283a;
  border: 1px solid #24486b;
  color: var(--cyan);
  text-decoration: none;
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-height: var(--touch);
}
.bouton-site:hover { background: #1b3149; }

.bloc-google {
  margin-top: 12px;
  border-radius: var(--radius);
  padding: 12px 14px;
  background: var(--amber-dim);
  border: 1px solid #5c4a22;
}
.google-titre { font-size: 13px; font-weight: 600; color: var(--amber); margin-bottom: 6px; }
.google-note { font-size: 15px; display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.etoiles { color: #ffc83d; letter-spacing: 2px; }
.google-note-bas { font-size: 12.5px; color: var(--muted); margin-top: 6px; }

.avertissement {
  font-size: 13.5px;
  line-height: 1.5;
  border-radius: var(--radius);
  padding: 11px 13px;
  margin-top: 10px;
  border: 1px solid;
}
.avertissement.bloque { background: #2a1d1d; border-color: #5a3330; }
.avertissement.attention { background: #2b2517; border-color: #5c4a22; }
.avertissement.ok { background: #17281c; border-color: #2c4c34; }
.avertissement b { display: block; margin-bottom: 4px; }

.journal { list-style: none; margin: 0; padding: 0; font-size: 13.5px; }
.journal li { padding: 9px 0; border-bottom: 1px solid var(--line); }
.journal .quand { color: var(--faint); font-size: 12px; }

textarea { width: 100%; resize: vertical; min-height: 72px; line-height: 1.5; }

.copiable {
  background: none;
  border: none;
  color: var(--cyan);
  padding: 2px 6px;
  min-height: 0;
  font-size: 12px;
  font-family: var(--mono);
}

/* ---------------------------------------------------------------- kanban */

.kanban { flex-direction: column; background: var(--bg); min-height: 0; }

.kanban-barre {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
  flex: 0 0 auto;
}
.kanban-barre select { flex: 1 1 auto; min-width: 0; }
.kanban-barre .action { flex: 0 0 auto; width: auto; }
.kanban-mrr { font: 600 13px var(--mono); color: var(--green); white-space: nowrap; }

/* Tableau de bord : le tunnel complet, de la prospection au revenu
   recurrent. Aucun des deux outils ne pouvait le produire seul — le
   prospecteur ignorait ce que devenaient ses leads gagnes, le kanban d'ou
   venaient ses cartes. */
.tableau-bord {
  flex: 0 0 auto;
  padding: 14px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-2);
  max-height: 55vh;
  overflow-y: auto;
}
.tunnel { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 4px; }
.tunnel-etape {
  flex: 1 1 92px;
  background: var(--panel);
  border: 1px solid var(--line-2);
  border-radius: 10px;
  padding: 10px 12px;
}
.tunnel-etape b { display: block; font: 700 20px/1.2 var(--mono); }
.tunnel-etape span { font-size: 12px; color: var(--muted); }
.tunnel-etape.gagne { border-color: var(--green); }
.tunnel-etape.gagne b { color: var(--green); }

.bord-titre {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--muted);
  font-weight: 600;
  margin: 16px 0 8px;
}
.bord-lignes { display: flex; flex-direction: column; gap: 6px; font-size: 13.5px; }
.bord-ligne { display: flex; justify-content: space-between; gap: 10px; }
.bord-ligne span:last-child { font-family: var(--mono); color: var(--muted); }
.bord-vide { color: var(--faint); font-size: 13px; }

.kanban-colonnes {
  flex: 1 1 auto;
  display: flex;
  gap: 12px;
  padding: 12px;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}

.k-colonne {
  flex: 0 0 86vw;
  max-width: 340px;
  scroll-snap-align: center;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.k-colonne-titre {
  padding: 12px 14px;
  font-weight: 600;
  font-size: 14px;
  border-bottom: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  gap: 8px;
}
.k-colonne-titre span { color: var(--faint); font-family: var(--mono); font-size: 12.5px; }

.k-cartes {
  list-style: none;
  margin: 0;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  overflow-y: auto;
  flex: 1 1 auto;
  min-height: 60px;
}

.k-carte {
  background: var(--panel-2);
  border: 1px solid var(--line-2);
  border-left: 3px solid var(--slate);
  border-radius: 10px;
  padding: 12px;
  cursor: grab;
  /* Le glisser-deposer par appui long de SortableJS ne fonctionne que si le
     navigateur ne prend pas le geste pour un defilement. */
  touch-action: manipulation;
}
.k-carte:active { cursor: grabbing; }
.k-carte.high { border-left-color: var(--red); }
.k-carte.medium { border-left-color: var(--amber); }
.k-carte.low { border-left-color: var(--slate); }
.k-carte-titre { font-weight: 500; font-size: 14.5px; }
.k-carte-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 7px;
  font-size: 12.5px;
  color: var(--muted);
}
.k-carte-valeur { font-family: var(--mono); color: var(--green); }
.k-vide { color: var(--faint); font-size: 13px; text-align: center; padding: 18px 8px; }

.sortable-ghost { opacity: .35; }
.sortable-chosen { box-shadow: var(--shadow); }

/* ------------------------------------------------------- onglets (desktop)

   Sur telephone la barre du bas a disparu : Liste est un bouton sur la carte.
   Ces styles ne s'appliquent qu'a partir de 900 px (bloc plus bas). */

.onglets {
  display: none;
}
.onglets button {
  position: relative;
  background: none;
  border: none;
  border-radius: 0;
  color: var(--faint);
  font-size: 11.5px;
  padding: 8px 4px;
  min-height: var(--barre-onglets);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
}
.onglets button svg {
  width: 22px; height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.onglets button.on { color: var(--amber); }
.onglets button:hover:not(.on) { background: none; color: var(--muted); }

/* --------------------------------------------------------------- Leaflet */

.leaflet-container { background: #10131a; font-family: var(--sans); }
.leaflet-popup-content-wrapper, .leaflet-popup-tip { background: var(--panel); color: var(--txt); }
.leaflet-popup-content { margin: 10px 13px; font-size: 14px; }
.leaflet-bar a { background: var(--panel); color: var(--txt); border-color: var(--line-2); }
.leaflet-bar a:hover { background: var(--panel-2); }
.leaflet-control-zoom a { width: 36px; height: 36px; line-height: 36px; font-size: 20px; }

.pin { filter: drop-shadow(0 1px 2px rgba(0, 0, 0, .45)); }

.leaflet-control-layers {
  background: rgba(24, 28, 34, .96);
  border: 1px solid var(--line-2);
  color: var(--txt);
  border-radius: 10px;
}
.leaflet-control-layers-expanded { padding: 10px 12px; }
.leaflet-control-layers label { font-size: 13.5px; min-height: 30px; display: flex; align-items: center; }
.leaflet-control-attribution {
  background: rgba(21, 24, 29, .85) !important;
  color: var(--muted) !important;
  font-size: 11px;
}
.leaflet-control-attribution a { color: var(--cyan) !important; }

/* Rangee basse de la carte : compteur a gauche, legende a droite. Elles
   partagent une largeur au lieu de se superposer — voir le commentaire de
   `legende()` dans app.js. La rangee elle-meme ne capte pas le pointeur, sans
   quoi elle avalerait les clics sur toute la largeur de la carte. */
.carte-bas {
  position: absolute;
  left: 10px;
  right: 10px;
  bottom: 26px;
  z-index: 500;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 10px;
  pointer-events: none;
}
.carte-bas > * { pointer-events: auto; }

.legende {
  /* Largeur naturelle, jamais comprimee : c'est le compteur qui cede. */
  flex: 0 0 auto;
  background: rgba(24, 28, 34, .95);
  border: 1px solid var(--line-2);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 12.5px;
}
.legende div { display: flex; align-items: center; gap: 8px; padding: 2px 0; }
.legende .puce { width: 10px; height: 10px; border-radius: 50%; }

.legende > summary {
  display: flex;
  align-items: center;
  min-height: var(--touch);
  cursor: pointer;
  color: var(--muted);
  font-weight: 500;
}
.legende[open] > summary {
  margin-bottom: 5px;
  border-bottom: 1px solid var(--line-2);
}

/* Commande logee en bas de la legende depliee. Le trait la separe des
   couleurs : au-dessus on explique ce qu'on voit, ici on agit dessus — sans
   separation, la ligne se lirait comme une septieme couleur. */
.legende-bascule {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--line-2);
  /* Cible tactile pleine hauteur : c'est la seule ligne de la legende sur
     laquelle on appuie. Le label porte le clic sur toute la largeur du
     cartouche, case comprise — il n'y a pas a viser la case. */
  min-height: var(--touch);
  cursor: pointer;
  white-space: nowrap;
}
.legende-bascule input { cursor: pointer; flex: 0 0 auto; }

/* ============================================================================
   ≥ 900 px — liste et carte cote a cote, fiche en panneau glissant.
   La barre d'onglets disparait : tout coexiste.
   ========================================================================= */

@media (min-width: 900px) {
  body { font-size: 14px; }
  :root { --touch: 36px; }

  .grille { position: relative; overflow: hidden; }

  /* Ici la liste suit la carte d'elle-meme (voir listeSuitCarte) : les deux
     commandes qui posent le cadre a la main n'ont plus d'objet, et un bouton
     qui ne change rien a ce qui est deja affiche est pire qu'absent. Elles
     restent entieres sous 900 px, ou une seule vue est visible a la fois. */
  .vue-mobile-nav,
  .carte-liste,
  [data-vue-rapide="cadre"] { display: none; }

  .grille > [data-vue="liste"] { display: flex; flex: 0 0 340px; border-right: 1px solid var(--line); }
  .grille > [data-vue="carte"] { display: flex; }

  /* La fiche est une popup (#dlg-fiche) a toutes les largeurs : au-dela de
     700 px elle prend la taille standard des modales, rien a faire ici. */

  /* Deux colonnes etiquette/valeur : la regle vivait dans le bloc >=1400 px
     quand elle dependait de la largeur de l'ancienne colonne fiche ; la
     modale fait 680 px des 700 px d'ecran, la place y est toujours. */
  .paire { display: grid; grid-template-columns: 104px 1fr; gap: 3px 12px; }
  .paire dt { margin-top: 6px; }
  .paire dd { margin-top: 6px; }

  /* Meme traitement que le kanban : la vue du jour se superpose aux colonnes
     permanentes plutot que de les compresser. */
  .grille > [data-vue="aujourdhui"] { position: absolute; inset: 0; z-index: 700; }
  .aujourdhui .auj-corps { max-width: 760px; }

  .onglets {
    position: static;
    display: flex;
    justify-content: flex-start;
    gap: 4px;
    border-top: none;
    border-bottom: 1px solid var(--line);
    background: var(--bg-2);
    padding: 0 12px;
    order: -1;
  }
  .onglets button {
    flex-direction: row;
    gap: 7px;
    min-height: 42px;
    padding: 0 14px;
    font-size: 13px;
    border-bottom: 2px solid transparent;
  }
  .onglets button.on { border-bottom-color: var(--amber); }
  .onglets button[data-onglet="liste"], .onglets button[data-onglet="carte"] { display: none; }
  /* Bouton en ligne ici : la pastille reprend sa place dans le flux. */
  .onglets .badge { position: static; margin-left: 5px; }


  /* Les filtres s'ouvrent d'office sur grand ecran — c'est le JS qui pose
     `open` (voir ajusterFiltres). Le summary reste visible : masquer la seule
     poignee d'un panneau qui n'etait jamais ouvert le rendait inatteignable,
     et il faut pouvoir replier pour rendre de la hauteur a la liste.
     `max-height` est conservee pour la meme raison : un panneau deroule sur
     toute la colonne repousserait la liste hors de l'ecran. */

  .k-colonne { flex: 0 0 300px; }
  .kanban-colonnes { scroll-snap-type: none; }
}

/* ============================================================================
   ≥ 1400 px — trois colonnes, la fiche cesse de recouvrir la carte.
   ========================================================================= */

@media (min-width: 1400px) {
  .grille > [data-vue="liste"] { flex: 0 0 360px; }
}

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

/* ------------------------------------------- courrier et script d'appel

   La modale sert deux contenus qui se lisent debout devant un commerce :
   un apercu de lettre et un script de trente secondes. D'ou une largeur
   confortable en bureau, mais plein ecran sous 700 px — l'ecran du telephone
   est le format reel d'usage du script. */

.modale {
  width: min(680px, 94vw);
  max-height: 88vh;
  padding: 0;
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  background: var(--panel);
  color: var(--txt);
  overflow: hidden;
}
.modale::backdrop { background: rgba(0, 0, 0, .62); }

.modale-tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
  background: var(--panel-2);
}
.modale-tete h2 { margin: 0; font-size: 15px; }
/* Le nom du commerce vit dans la tete du dialog — un seul titre, toujours
   visible en defilant. Il doit s'ecraser en ellipse plutot que pousser la
   croix hors de l'ecran. */
#fiche-titre { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* La croix de TOUTE tete de modale — par classe et non par id : la regle
   visait #dlg-fermer, et les croix des deux modales ajoutees ensuite (fiche,
   carte kanban) heritaient du style de bouton generique, un pave borde que
   rien ne designait comme « fermer ». */
.modale-tete button {
  border: 0;
  background: none;
  color: var(--muted);
  font-size: 22px;
  line-height: 1;
  padding: 0 4px;
  cursor: pointer;
}
.modale-tete button:hover { color: var(--txt); }

.modale-corps { padding: 16px; overflow-y: auto; max-height: calc(88vh - 118px); }

/* Phrase d'explication sous un formulaire de modale (import, etc.). */
.modale-corps .aide { margin: 10px 0 0; font-size: 12.5px; color: var(--muted); }

/* La fiche n'a pas de pied : le calc standard de .modale-corps reserve les
   118 px d'une tete PLUS un pied, ce qui laisserait une bande morte de ~60 px
   sous le contenu — genant surtout en plein ecran sur telephone. 56 px = la
   tete seule. */
#dlg-fiche .modale-corps { max-height: calc(88vh - 56px); }

/* ------------------------------------------------- modale carte du pipeline */

.kc-check-ligne { display: flex; align-items: center; gap: 8px; }
.kc-check-ligne .bascule { flex: 1 1 auto; min-width: 0; }
.kc-check-ligne .bascule span { overflow-wrap: anywhere; }
/* Le x de retrait garde une cible tactile pleine : c'est un geste rare mais
   destructif, le rater au profit de la case a cocher serait pire. */
.kc-check-ligne > button {
  flex: 0 0 auto;
  min-width: var(--touch);
  min-height: var(--touch);
  padding: 0;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 17px;
}
.kc-fait { text-decoration: line-through; color: var(--muted); }
.kc-check-ajout { display: flex; gap: 8px; }
.kc-check-ajout input { flex: 1 1 auto; min-width: 0; }
.kc-check-ajout .action { width: auto; flex: 0 0 auto; }

/* Le destructif part a gauche, loin d'Enregistrer : le pied est en flex-end,
   margin-right:auto suffit a creuser l'ecart. */
#kc-supprimer { margin-right: auto; border-color: #5a3330; color: var(--red); }
/* L'encart lead garde son bouton a largeur naturelle. */
#kc-voir-fiche { width: auto; margin-top: 8px; }
.modale-pied {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  padding: 12px 16px;
  border-top: 1px solid var(--line);
  background: var(--panel-2);
  min-height: 22px;
}

/* L'apercu imite la feuille : fond clair et serif, pour que l'oeil juge le
   courrier tel qu'il sera recu et non tel que l'application l'affiche. */
.lettre-apercu {
  background: #f6f5f1;
  color: #1a1a1a;
  border-radius: var(--radius);
  padding: 22px 24px;
  font-size: 13px;
  line-height: 1.62;
}
.lettre-apercu h4 { margin: 20px 0 14px; font-size: 14px; }
.lettre-apercu p { margin: 0 0 11px; }
.lettre-exp { font-size: 11px; color: #55524c; line-height: 1.45; }
.lettre-dest { margin: 22px 0 0 46%; }
.lettre-date { margin: 16px 0 0 46%; font-size: 12px; }
.lettre-legal { margin-top: 20px; font-size: 10.5px; color: #6a675f; line-height: 1.45; }

.apercu-titre { margin: 18px 0 8px; font-size: 13px; color: var(--muted); }

.script-tel { font-family: var(--mono); font-size: 19px; margin: 12px 0 14px; }

.script { list-style: none; margin: 0; padding: 0; counter-reset: etape; }
.script li {
  counter-increment: etape;
  border-left: 2px solid var(--line-2);
  padding: 0 0 14px 14px;
  position: relative;
}
.script li::before {
  content: counter(etape);
  position: absolute;
  left: -9px;
  top: 0;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--panel-2);
  border: 1px solid var(--line-2);
  color: var(--muted);
  font-size: 10px;
  line-height: 15px;
  text-align: center;
}
.script-titre {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 3px;
}
.script-secondes { font-family: var(--mono); color: var(--faint); }
.script-texte { display: block; font-size: 14.5px; line-height: 1.5; }
.script-duree { font-size: 12px; color: var(--faint); margin-right: auto; }

.objections { margin: 0; font-size: 13.5px; }
.objections dt { color: var(--muted); margin-top: 10px; }
.objections dd { margin: 3px 0 0; line-height: 1.5; }

@media (max-width: 700px) {
  .modale { width: 100vw; max-width: 100vw; max-height: 100vh; height: 100vh; border: 0; border-radius: 0; }
  .modale-corps { max-height: calc(100vh - 118px); }
  #dlg-fiche .modale-corps { max-height: calc(100vh - 56px); }
  .lettre-dest, .lettre-date { margin-left: 0; }
}

/* Formulaire de reglages dans la modale. Deux colonnes en bureau pour que les
   huit champs tiennent sans defiler ; une seule sous 560 px. */
.reglages-intro { margin: 0 0 14px; font-size: 13px; color: var(--muted); line-height: 1.55; }
.reglages { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.reglages .champ { display: flex; flex-direction: column; gap: 5px; }
.reglages label { font-size: 12px; color: var(--muted); }
.reglages input { width: 100%; }
.reglages-etat { margin-right: auto; font-size: 12px; color: var(--amber); }

@media (max-width: 560px) {
  .reglages { grid-template-columns: 1fr; }
}

/* ------------------------------------------------------------- connexion

   Plein ecran et opaque : tant que la session n'est pas etablie, rien de la
   base ne doit transparaitre derriere. */
.connexion {
  position: fixed;
  inset: 0;
  z-index: 3000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: var(--bg);
}
.connexion[hidden] { display: none; }

.connexion-boite {
  width: min(360px, 100%);
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 26px 24px;
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  background: var(--panel);
}
.connexion-boite h1 {
  margin: 0;
  font-size: 15px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--amber);
}
.connexion-intro { margin: 0; font-size: 12.5px; color: var(--muted); line-height: 1.55; }
.connexion-boite .champ { display: flex; flex-direction: column; gap: 5px; }
.connexion-boite label { font-size: 12px; color: var(--muted); }
.connexion-erreur {
  font-size: 13px;
  border-radius: var(--radius);
  padding: 9px 11px;
  background: #2a1d1d;
  border: 1px solid #5a3330;
}
.connexion-erreur[hidden] { display: none; }

/* Ce que la carte montre a cet instant. Sans lui, rien ne distingue « il n'y a
   rien ici » de « il y en a trop pour les afficher un par un ». */
.carte-compteur {
  /* Cede la place a la legende et se retrecit jusqu'a passer a la ligne. Sans
     `min-width: 0`, un texte long refuserait de se compresser et repousserait
     la legende hors du cadre — c'est le defaut classique d'un enfant flex. */
  flex: 0 1 auto;
  min-width: 0;
  max-width: 46ch;
  background: rgba(24, 28, 34, .95);
  border: 1px solid var(--line-2);
  border-radius: 10px;
  padding: 7px 11px;
  font-size: 12.5px;
  color: var(--muted);
  pointer-events: none;
}
.carte-compteur:empty { display: none; }

@media (max-width: 899px) {
  .carte-compteur { display: none; }

  /* Sur telephone, la liste n'avait qu'une bande en bas de l'ecran.
     L'en-tete du panneau — retour carte, filtres, outils, vues rapides,
     puces, compteur — etait fige en haut, et seule `.liste` defilait dans ce
     qu'il restait : sur un ecran de six pouces, quatre lignes de leads.
     Chaque ajout au-dessus mangeait la liste d'autant.

     C'est donc le panneau entier qui defile maintenant, la liste comprise :
     l'en-tete remonte et sort de l'ecran au premier glissement, et les leads
     occupent toute la hauteur des qu'on commence a les parcourir. Sur grand
     ecran, rien ne change — l'en-tete y tient sans rogner la liste, et le
     defilement independant vaut mieux quand les filtres restent ouverts. */
  .panneau[data-vue="liste"] {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    /* Le geste s'arrete au panneau : sans cela, arriver en bas de liste
       entrainait le rebond de la page derriere. */
    overscroll-behavior: contain;
  }
  .panneau[data-vue="liste"] .liste { overflow: visible; flex: 0 0 auto; }

  /* Plus de scroller dans un scroller : le panneau ouvert s'etend et defile
     avec le reste. Emboites, les deux se disputaient le glissement du doigt —
     on croyait parcourir les filtres, c'est la page qui bougeait. */
  .filtres { max-height: none; overflow: visible; }

  /* Le retour a la carte devient un bouton flottant, en bas a droite —
     symetrique de « Liste du cadre » qui flotte sur la carte. En rangee
     pleine largeur, il coutait 60 px d'en-tete a demeure pour un seul bouton ;
     hors du flux il n'en coute aucun, et reste atteignable au pouce ou qu'on
     soit dans la liste. C'est le seul chemin de retour depuis que la barre du
     bas a disparu, d'ou le fait qu'il ne defile pas avec le reste. */
  .vue-mobile-nav {
    position: fixed;
    right: 14px;
    /* Au-dessus de la zone de geste systeme des telephones sans bouton. */
    bottom: calc(14px + env(safe-area-inset-bottom, 0px));
    z-index: 6;
    padding: 0;
    border: 0;
    background: none;
  }
  .vue-mobile-nav button {
    border-radius: 999px;
    padding: 0 18px;
    background: rgba(24, 28, 34, .96);
    border: 1px solid var(--line-2);
    box-shadow: var(--shadow);
  }
  /* Ni le dernier lead ni la derniere ligne d'Aujourd'hui ne doivent finir
     sous le bouton flottant. */
  .panneau[data-vue="liste"] .liste { padding-bottom: 76px; }
  .auj-corps { padding-bottom: 76px; }

  /* Les vues rapides tiennent sur une ligne qui defile lateralement plutot
     que d'enrouler sur deux : la seconde ligne coutait 50 px d'en-tete pour
     un bouton et demi. */
  .vues {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: 2px;
  }
  .vues::-webkit-scrollbar { display: none; }
  .vues button { flex: 0 0 auto; white-space: nowrap; }

  /* Le compteur est une ligne d'information, pas une cible : il n'a pas
     besoin de la hauteur d'un bouton. */
  .compteur { padding: 7px 14px; font-size: 12.5px; }

  /* Les actions en lot passent sous le pouce et y restent : on coche une
     trentaine de leads en descendant, la barre est en tete de panneau, et il
     aurait fallu tout remonter pour appliquer quoi que ce soit. Masquee hors
     mode selection, elle ne prend aucune place le reste du temps. */
  .lot-barre { position: sticky; bottom: 0; z-index: 5; }
}

/* Scores Lighthouse. Les couleurs reprennent les seuils publics de Google —
   0-49 rouge, 50-89 orange, 90-100 vert — pour que le commercant qui refait
   la mesure lui-meme retrouve exactement le meme verdict.

   Une ligne et non quatre tuiles : quatre chiffres dans l'ordre habituel de
   Lighthouse (performance, accessibilite, bonnes pratiques, SEO) se lisent
   aussi vite, et les libelles ne valaient pas le quart de hauteur de fiche
   qu'ils prenaient — ils vivent desormais dans l'infobulle. */
.ps-ligne { font-size: 13.5px; color: var(--muted); }
.ps-ligne b { font-family: var(--mono); font-size: 15px; color: var(--txt); }
.ps-ligne .ps-rouge  { color: #ff6b6b; }
.ps-ligne .ps-orange { color: var(--amber); }
.ps-ligne .ps-vert   { color: var(--green); }
.ps-ligne-quand { color: var(--faint); font-size: 12px; margin-left: 6px; }

/* ------------------------------------------------- mise de cote et rappels */

/* L'etoile reste discrete tant qu'elle n'est pas active : une liste de mille
   leads couverte de symboles vifs ne se lit plus. */
.etoile {
  background: none;
  border: 0;
  color: var(--faint);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
  min-width: var(--touch);
  min-height: var(--touch);
}
.etoile:hover { color: var(--amber); }
.etoile.on { color: var(--amber); }

/* Un rappel echu doit sauter aux yeux : c'est la seule etiquette de la liste
   qui appelle une action aujourd'hui. */
.etiq.rappel-du {
  background: var(--amber-dim);
  color: var(--amber);
  border-color: var(--amber);
}

/* Tout bouton a bascule montre son etat — par attribut et non par id, pour
   que « Chiffres », « Selectionner » et les suivants soient couverts d'office.
   Sans retour visuel, appuyer semble ne rien faire tant que l'effet est plus
   bas dans la page. */
#btn-marque[aria-pressed="true"],
.action[aria-pressed="true"] {
  border-color: var(--amber);
  color: var(--amber);
  background: var(--amber-dim);
}

/* Dans l'iframe Odoo, la marque fait double emploi avec le menu CRM. */
body.embed .marque { display: none; }
body.embed .barre { min-height: 40px; }

/* ------------------------------------------------------------- assistant

   Meme famille visuelle que le reste : panneaux sombres, ambre pour ce qui
   attend une decision. Les bulles de l'utilisateur sont a droite en ambre
   sourd, celles du modele a gauche sur panel-2 ; les propositions d'ecriture
   ont un liseret ambre tant qu'elles attendent, vert une fois faites. */

body[data-vue="assistant"] .grille > [data-vue="assistant"] { display: flex; }
.assistant { flex-direction: column; }

.asst-tete {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-2);
  flex: 0 0 auto;
}
.asst-tete button { min-height: 36px; padding: 0 12px; font-size: 13px; font-weight: 600; }
.asst-titre {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 600;
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.asst-corps { flex: 1 1 auto; min-height: 0; display: flex; position: relative; }

.asst-liste {
  display: none;
  flex: 0 0 260px;
  border-right: 1px solid var(--line);
  overflow-y: auto;
  background: var(--panel);
}
.asst-liste.ouverte { display: block; position: absolute; inset: 0; z-index: 3; border-right: 0; }
.asst-conv {
  position: relative;
  padding: 10px 36px 10px 14px;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  font-size: 13.5px;
}
.asst-conv:hover { background: var(--panel-2); }
.asst-conv.on { background: #1e2431; box-shadow: inset 3px 0 0 var(--amber); }
.asst-conv-titre { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.asst-conv-meta { font-size: 12px; color: var(--faint); margin-top: 2px; }
.asst-conv-meta .lead { color: var(--amber); cursor: pointer; }
.asst-conv-suppr {
  position: absolute;
  right: 6px;
  top: 6px;
  background: none;
  border: 0;
  color: var(--faint);
  font-size: 18px;
  line-height: 1;
  min-height: 0;
  padding: 4px 8px;
}
.asst-conv-suppr:hover { color: var(--red); background: none; }
.asst-conv-vide { padding: 14px; color: var(--muted); font-size: 13px; }

.asst-chat { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.asst-fil {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  -webkit-overflow-scrolling: touch;
}

.msg {
  max-width: min(760px, 92%);
  padding: 10px 14px;
  border-radius: 14px;
  font-size: 14.5px;
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.msg.moi {
  align-self: flex-end;
  background: var(--amber-dim);
  border: 1px solid #5a4a1c;
  white-space: pre-wrap;
}
.msg.lui { align-self: flex-start; background: var(--panel-2); border: 1px solid var(--line-2); }
.msg.lui p { margin: 0 0 8px; }
.msg.lui p:last-child { margin-bottom: 0; }
.msg.lui ul, .msg.lui ol { margin: 4px 0 8px; padding-left: 22px; }
.msg.lui li { margin: 2px 0; }
.msg.lui h4 { margin: 8px 0 4px; font-size: 14.5px; }
.msg.lui h4:first-child { margin-top: 0; }
.msg.lui code { font: 13px var(--mono); background: var(--bg-2); padding: 1px 5px; border-radius: 4px; }
.msg.lui a { color: var(--cyan); }
.msg.lui a.lead { color: var(--amber); text-decoration: none; font-weight: 600; }
.msg.lui a.lead:hover { text-decoration: underline; }
.msg.systeme {
  align-self: center;
  background: none;
  color: var(--faint);
  font-size: 12.5px;
  text-align: center;
  padding: 2px 8px;
  white-space: pre-wrap;
}

/* Trois points qui respirent : le modele reflechit ou un outil tourne. */
.msg.frappe { display: flex; gap: 5px; align-items: center; padding: 12px 16px; }
.msg.frappe span {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--muted);
  animation: asst-pulse 1.2s infinite ease-in-out;
}
.msg.frappe span:nth-child(2) { animation-delay: .2s; }
.msg.frappe span:nth-child(3) { animation-delay: .4s; }
@keyframes asst-pulse { 0%, 80%, 100% { opacity: .25; transform: translateY(0); } 40% { opacity: 1; transform: translateY(-3px); } }

.asst-outils { align-self: flex-start; display: flex; flex-wrap: wrap; gap: 6px; max-width: 92%; }
.asst-outil {
  font: 12px var(--mono);
  color: var(--muted);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 4px 10px;
}
.asst-outil.encours::before { content: "⏳ "; }
.asst-outil.ok::before { content: "✓ "; color: var(--green); }
.asst-outil.erreur::before { content: "✗ "; color: var(--red); }
.asst-outil .detail { color: var(--faint); }

.proposition {
  align-self: flex-start;
  max-width: min(760px, 92%);
  border: 1px solid var(--amber);
  background: var(--amber-dim);
  border-radius: 12px;
  padding: 10px 14px;
  font-size: 14px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.proposition .rangee > button { flex: 0 1 auto; min-height: 36px; padding: 0 14px; }
.proposition [data-decision="confirmer"] { border-color: var(--amber); color: var(--amber); font-weight: 600; }
.proposition.faite { border-color: var(--green); background: #14261f; }
.proposition.ignoree { opacity: .6; border-color: var(--line-2); background: var(--panel-2); }
.proposition.echec { border-color: var(--red); background: #2a1d1d; }
.proposition-etat { font-size: 12.5px; color: var(--muted); }

.asst-composer {
  display: flex;
  gap: 8px;
  align-items: flex-end;
  padding: 10px 12px;
  border-top: 1px solid var(--line);
  background: var(--bg-2);
  flex: 0 0 auto;
}
.asst-composer textarea { flex: 1 1 auto; resize: none; max-height: 160px; line-height: 1.4; }
.asst-composer button { flex: 0 0 auto; width: 48px; font-size: 18px; padding: 0; }

.asst-vide { color: var(--muted); max-width: 560px; margin: 32px auto 0; text-align: center; font-size: 14px; }
.asst-vide h2 { font-size: 18px; margin: 0 0 8px; color: var(--txt); }
.asst-vide code { font: 13px var(--mono); background: var(--bg-2); padding: 1px 5px; border-radius: 4px; }
.asst-suggestions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin: 14px 0; }
.asst-suggestions button { font-size: 13px; text-align: left; min-height: 38px; padding: 8px 12px; }
.asst-note { color: var(--faint); font-size: 12.5px; }

@media (min-width: 900px) {
  .grille > [data-vue="assistant"] { position: absolute; inset: 0; z-index: 700; }
  .asst-liste { display: block; }
  .asst-liste-btn, .asst-retour, .carte-assistant { display: none; }
}

@media (max-width: 899px) {
  .asst-fil { padding-bottom: 20px; }
}
