/* Prospecto — feuille de style.
   Principe : aéré, une information par ligne, gros boutons.
   Pas de framework CSS, pas d'étape de build.

   LA COULEUR PORTE DU SENS, elle ne décore pas. Un statut a une couleur, et
   cette couleur est la même partout : badge sur la fiche, onglet, pastille du
   journal, barre du dashboard. On doit pouvoir lire un écran de loin, sans lire
   les mots. Ne jamais réutiliser une de ces couleurs pour autre chose. */

:root {
  /* --- La refonte du 10/09/2026 --------------------------------------------
     Maquette fournie par le propriétaire, palette **relevée dans son fichier**
     et non choisie à l'œil. Le principe de la refonte du 31/08 est repris tel
     quel, et c'est lui qui rend l'opération sûre : tout tient dans ces
     variables, le mapping Python (`COULEURS_STATUT`) désigne des **noms**
     (`vert`, `ambre`, `rouge`), donc changer la peau ne demande pas une ligne
     de Python ni un gabarit de données.

     **Ce qui change vraiment** : l'outil passe d'un bandeau horizontal crème et
     vermillon à une barre latérale sombre, dans une gamme violet et cyan. Plus
     dense, plus proche des outils que l'équipe utilise ailleurs.

     **Ce qui ne change pas, et ne doit jamais changer** : vert, ambre et rouge
     restent les seules couleurs d'**état**. Un badge « payé » se lit à deux
     mètres, et c'est tout ce qu'on lui demande. */
  --violet-marque: #5b3df0;
  --violet-fonce: #4b2cd4;
  --cyan: #4fb3d9;
  --navy: #171b30;

  /* Encre et fonds */
  --texte: #22263a;
  --texte-doux: #6c7287;
  --fond: #f6f7fb;          /* jamais du blanc plein : les cartes ressortent */
  --carte: #ffffff;
  --bordure: #e8eaf2;
  --rayon: 16px;   /* la valeur du fichier de maquette */
  --rayon-petit: 9px;
  /* Ombre froide et très basse : sur ce gris bleuté, l'ombre chaude d'avant
     tirait au jaune. Les cartes se posent, elles ne flottent pas. */
  --ombre: 0 1px 2px rgba(34, 38, 58, .04), 0 3px 10px rgba(34, 38, 58, .04);
  --ombre-haute: 0 16px 50px -20px rgba(32, 32, 68, .28);

  /* --- Ce qui se clique ----------------------------------------------------
     **Le violet réunit deux rôles que l'ancienne charte séparait.** Avant, le
     vermillon marquait la sélection et le bleu signal l'action : deux couleurs
     de marque pour deux gestes voisins, ce qui obligeait à expliquer laquelle
     allait où. Ici une seule les porte — bouton, onglet courant, lien de texte,
     contour de focus — et le cyan sert d'appui, jamais d'action.

     La raison de fond n'a pas bougé d'un pouce : **la couleur d'action ne doit
     pas pouvoir se confondre avec une alerte.** Le violet n'entre en
     concurrence avec aucun état, là où l'ancien vermillon frôlait le rouge de
     la dette — c'est même ce qui avait forcé, en août, à choisir le bleu pour
     les boutons. Le problème disparaît de lui-même. */
  --accent: #5b3df0;
  --accent-fort: #4b2cd4;
  --accent-pale: #f0edff;
  --accent-trait: #d3ccf7;

  /* Gardées pour ne pas casser les règles qui les nomment encore. Le vermillon
     de l'ancienne charte **ne sert plus** : il est aliasé sur le violet, ce qui
     évite de laisser une couleur orpheline traîner dans la feuille. */
  --vermillon: var(--accent);
  --bleu-signal: var(--accent);
  --acide: #4fb3d9;
  --noir: var(--navy);
  --creme: var(--fond);

  /* --- Les couleurs de sens ------------------------------------------------
     Retouchées pour tenir sur un gris bleuté et non sur le crème : les valeurs
     chaudes d'hier y paraissaient sales. Ce sont des couleurs de **lecture**,
     pas de marque — on distingue un « payé » d'un « dû » à deux mètres, et
     c'est la seule chose qu'on leur demande. */
  --vert: #197b62;    --vert-pale: #e8f6f0;    --vert-trait: #a6dcca;
  --ambre: #a76913;   --ambre-pale: #fff5e4;   --ambre-trait: #edc491;
  --rouge: #b0424c;   --rouge-pale: #fff0f0;   --rouge-trait: #f0b8bc;
  --violet: #6140db;  --violet-pale: #eeebff;  --violet-trait: #c6bcf7;
  --gris: #62697e;    --gris-pale: #f0f2f7;    --gris-trait: #d3d8e4;

  --alerte: var(--ambre);

  /* Le texte posé sur la barre latérale sombre. */
  --sur-bandeau: #aeb5cb;
  --sur-bandeau-vif: #ffffff;
}


* { box-sizing: border-box; }

/* Ce que le navigateur dessine lui-même — cases à cocher, boutons radio, barres
   de défilement, curseur de saisie. Sans cette ligne il reste au bleu du
   système, et une case cochée en bleu au milieu d'un écran vermillon est le
   dernier endroit où l'ancienne palette se voit encore. */
html {
  accent-color: var(--vermillon);
  caret-color: var(--vermillon);
}

body {
  margin: 0;
  /* Jakarta d'abord, la pile système en repli : la police peut ne pas être
     arrivée, l'écran doit rester lisible. */
  font-family: "Jakarta", -apple-system, BlinkMacSystemFont, "Segoe UI",
               Helvetica, sans-serif;
  /* 15 px et non 17 : la maquette est plus dense, et Jakarta a un œil plus
     grand qu'une police système à taille égale. */
  font-size: 15px;
  line-height: 1.6;
  font-synthesis: none;
  color: var(--texte);
  background: var(--fond);
  -webkit-font-smoothing: antialiased;
}

/* ==========================================================================
   LA COQUILLE — reprise du fichier de maquette, à l'identique
   ==========================================================================
   Deuxième passe, 10/09/2026. La première avait porté les couleurs et trois
   composants ; la réponse a été « tu as laissé l'ancienne mise en page ».
   Elle était juste. Ce bloc-ci n'est plus une adaptation : ce sont les règles
   du fichier fourni, recopiées, avec les seuls écarts que notre balisage
   impose — les sous-menus dépliants et le pied de barre, que la maquette ne
   connaît pas parce que son menu est plat.

   Les valeurs sont en pixels comme dans le fichier d'origine, et c'est
   volontaire : les convertir en `rem` produirait des arrondis, donc une mise
   en page qui **ressemble** à la maquette au lieu d'être la maquette.
   ========================================================================== */

/* --- Les icônes ----------------------------------------------------------- */
/* Trait de 1,7 et bouts arrondis : c'est ce qui donne au menu son allure. Une
   icône pleine ferait tache à côté. */
.icon {
  width: 19px;
  height: 19px;
  stroke: currentColor;
  stroke-width: 1.7;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}
.icon.sm { width: 16px; height: 16px; }
.icon.lg { width: 23px; height: 23px; }

/* --- La barre latérale ---------------------------------------------------- */
.sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  width: 224px;
  z-index: 30;
  background: var(--navy);
  color: #b0b5ca;
  padding: 30px 16px 16px;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  /* Une barre de défilement fine plutôt que celle du système : quinze pixels
     pris à une colonne de 224 se voient, six ne se voient pas. C'est la moitié
     de la correction du chevauchement du logotype. */
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, .18) transparent;
  transition: width .22s, transform .22s;
}

/* La rangée du haut : le logotype à gauche, le bouton qui replie à droite.
   `.brand` est la **rangée** et non le lien — un `<button>` posé dans un `<a>`
   n'est pas du HTML valide, et le clic partirait sur les deux. */
.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  color: #fff;
  padding: 0 9px;
}

.brand-lien {
  display: flex;
  align-items: center;
  gap: 10px;
  color: inherit;
  text-decoration: none;
  /* **Les deux lignes qui empêchent le nom de passer par-dessus le bouton.**
     Signalé le 11/09/2026 : « le bouton pour replier la barre est sur
     l'écriture prospecto ». La cause était l'`overflow-y: auto` posé sur la
     barre la veille — dès que le menu dépasse la hauteur de l'écran, sa barre
     de défilement prend quinze pixels de large, et le nom n'avait plus la place
     de tenir à côté du bouton. Il ne rétrécissait pas pour autant : un élément
     de flexbox refuse de passer sous la largeur de son contenu tant qu'on ne
     lui a pas dit qu'il le pouvait.
     Mesuré à cinq largeurs d'écran plutôt que corrigé à l'œil. */
  min-width: 0;
  overflow: hidden;
}

.brand-name { min-width: 0; }

/* Le logotype : trois barres inclinées de 14°, la deuxième plus haute, la
   troisième courte et alignée en haut. C'est ce décalage qui fait la marque —
   trois barres égales ne diraient rien. */
.brand-mark {
  width: 33px;
  height: 37px;
  position: relative;
  display: flex;
  gap: 4px;
  align-items: center;
  flex: none;
}
.brand-mark i {
  display: block;
  width: 8px;
  height: 29px;
  background: var(--accent);
  border-radius: 4px;
  transform: skew(-14deg);
}
.brand-mark i:nth-child(2) { height: 36px; background: #927cfb; }
.brand-mark i:nth-child(3) {
  height: 22px;
  background: var(--cyan);
  align-self: flex-start;
  margin-top: 4px;
}

.brand-name { font-size: 22px; font-weight: 800; letter-spacing: -.9px; }
.brand-name small {
  display: block;
  color: #8c92ac;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 2px;
  margin-top: 2px;
  text-transform: uppercase;
}

/* La carte d'espace, sous le logotype. Chez nous elle ne dit pas « Webuild ·
   Équipe » en dur : elle porte le module ouvert, qui est la seule chose qui
   change d'une coquille à l'autre. */
.workspace {
  border: 1px solid rgba(255, 255, 255, .075);
  border-radius: 10px;
  margin: 31px 2px 29px;
  padding: 11px;
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(255, 255, 255, .015);
}
.workspace .avatar {
  width: 30px;
  height: 30px;
  background: #32364a;
  color: #e2dff9;
  border-radius: 7px;
  font-size: 11px;
}
.workspace strong { font-size: 12px; color: #e4e6f1; display: block; }
.workspace small { display: block; font-size: 10px; margin-top: 3px; color: #858ea9; }

.nav-label {
  color: #737c9d;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.7px;
  padding: 0 13px;
  margin-bottom: 10px;
  text-transform: uppercase;
}

.nav { display: flex; flex-direction: column; gap: 5px; }

/* `a` en plus de `button` : la maquette navigue en JavaScript, nous en liens.
   Un menu qui ne serait pas fait de liens perdrait le clic-milieu, le survol
   qui montre l'adresse, et le retour arrière du navigateur. */
.nav a,
.nav button,
.nav summary {
  border: 0;
  background: transparent;
  color: #aeb5cb;
  text-align: left;
  display: flex;
  align-items: center;
  gap: 11px;
  border-radius: 9px;
  padding: 12px 13px;
  font-weight: 550;
  font-size: 13px;
  min-height: 43px;
  text-decoration: none;
  cursor: pointer;
}
.nav a:hover,
.nav button:hover,
.nav summary:hover { background: rgba(255, 255, 255, .035); color: #fff; }

.nav a.active,
.nav button.active,
.nav summary.active {
  background: var(--accent);
  color: #fff;
  box-shadow: 0 5px 18px rgba(8, 5, 34, .145);
}

.nav .count {
  margin-left: auto;
  background: rgba(255, 255, 255, .1);
  border-radius: 5px;
  padding: 2px 6px;
  font-size: 10px;
}

.nav-secondary { margin-top: 32px; }

/* --- Les sous-menus, que la maquette n'a pas -------------------------------
   Son menu est plat : six entrées, aucune n'en cache d'autres. Le nôtre en a
   trente. On garde donc `<details>`, mais habillé comme une entrée de menu,
   pour que le dépliant ne se voie pas comme une pièce rapportée. */
.nav details { display: block; }
.nav summary { list-style: none; }
.nav summary::-webkit-details-marker { display: none; }
.nav summary .chevron { margin-left: auto; transition: transform .18s; }
.nav details[open] summary .chevron { transform: rotate(180deg); }

.nav .volet {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 2px 0 6px 34px;
  padding-left: 9px;
  border-left: 1px solid rgba(255, 255, 255, .09);
}
.nav .volet a {
  font-size: 12px;
  padding: 8px 11px;
  min-height: 0;
  gap: 8px;
}

/* --- Le pied de la barre --------------------------------------------------- */
.sidebar-bottom { margin-top: auto; padding-top: 28px; }

.local-card {
  background: linear-gradient(125deg, #2c294d, #242d45);
  border: 1px solid rgba(255, 255, 255, .06);
  padding: 14px;
  border-radius: 11px;
  margin: 0 3px 19px;
  font-size: 12px;
  line-height: 1.6;
}
.local-card .dot {
  height: 6px;
  width: 6px;
  background: #62c8d7;
  border-radius: 50%;
  box-shadow: 0 0 8px rgba(98, 200, 215, .25);
  flex: none;
}
.local-card .local-detail { font-size: 10px; color: #999fba; margin-top: 5px; line-height: 1.7; }

.user {
  display: flex;
  align-items: center;
  gap: 10px;
  border-top: 1px solid rgba(255, 255, 255, .07);
  padding: 17px 7px 0;
}
.user .avatar { background: #393050; color: #dfd8fd; border-radius: 50%; }
.user-info strong { display: block; color: #eaecf6; font-size: 12px; }
.user-info small { font-size: 10px; color: #8790ab; }
.user .sortir {
  background: transparent;
  color: #8991ad;
  border: 0;
  margin-left: auto;
  display: flex;
  padding: 6px;
  min-height: 0;
}
.user .sortir:hover { color: #fff; background: rgba(255, 255, 255, .06); }

/* --- Ce que la barre laisse à droite --------------------------------------- */
.app { margin-left: 224px; min-height: 100vh; transition: margin .22s; }

.topbar {
  height: 73px;
  border-bottom: 1px solid var(--bordure);
  padding: 0 32px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  background: #fff;
  position: sticky;
  top: 0;
  z-index: 20;
}

.breadcrumb {
  font-size: 12px;
  display: flex;
  align-items: center;
  gap: 13px;
  color: #969aab;
}
.breadcrumb strong { color: #54596d; font-weight: 550; }

/* La recherche globale de la maquette mène chez nous à `/fiches` : c'est le
   même geste — trouver une fiche par son nom — et un champ qui ne chercherait
   nulle part serait un décor. */
.global-search {
  width: 284px;
  display: flex;
  align-items: center;
  gap: 9px;
  background: #f7f8fb;
  border: 1px solid #edeef4;
  border-radius: 8px;
  padding: 8px 11px;
  text-align: left;
  color: #858b9e;
  font-size: 12px;
  text-decoration: none;
}
.global-search:hover,
.global-search:focus-within { border-color: var(--accent-trait); color: var(--accent); }

/* Le champ ne dessine rien : c'est le formulaire qui porte le cadre, sinon on
   verrait deux bordures l'une dans l'autre. */
.global-search input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: none;
  outline: 0 !important;
  box-shadow: none !important;
  padding: 0;
  font: inherit;
  font-size: 12px;
  color: var(--texte);
}

.global-search input::placeholder { color: #858b9e; }
.global-search kbd {
  margin-left: auto;
  border: 1px solid #e5e7ee;
  background: #fff;
  border-radius: 4px;
  font-family: inherit;
  padding: 2px 4px;
  font-size: 10px;
}

.top-actions { display: flex; align-items: center; gap: 15px; }
.top-actions > .avatar { border-radius: 50%; height: 32px; width: 32px; }
.top-date { font-size: 12px; color: #71788c; }
.topbar .icon-btn { border: 0; color: #737a8e; }
/* Le bouton « revenir à l'écran d'avant » (25/09/2026), à gauche du fil
   d'Ariane. Caché tant que le script ne l'a pas révélé : un bouton mort est
   pire qu'un bouton absent. */
.retour-page[hidden] { display: none; }
.retour-page { margin-right: 2px; }
.mobile-menu { display: none; }

.main { max-width: 1690px; margin: auto; padding: 30px 32px 24px; }

/* Deux largeurs héritées, gardées parce que deux écrans les demandent. */
main.etroit { max-width: 26rem; }

/* h1 / h2 : voir le bloc de la maquette, plus bas. L'ancienne paire a été
   retirée le 10/09/2026 pour ne pas recouvrir celle du fichier fourni. Les
   gabarits qui espaçaient leurs `h2` par la marge de cette règle la reprennent
   ici, à la même valeur qu'avant. */
.carte h2, .liste-simple h2, main > h2 { margin: 2.5rem 0 1rem; }
main > h2:first-child { margin-top: 0; }

a { color: var(--accent-fort); }

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .9em;
  background: var(--gris-pale);
  padding: .1em .35em;
  border-radius: 5px;
}

.muted { color: var(--texte-doux); }
.warn { color: var(--alerte); }

/* --- Cartes --------------------------------------------------------------- */

/* **Le format de la maquette, porté par l'ancien nom.** Les 54 gabarits ne se
   réécrivent pas en une fois sans en casser un qu'on n'ouvre qu'une fois par
   mois ; en revanche `.carte` et `.card` peuvent rendre pareil dès aujourd'hui.
   Les écrans se convertissent ensuite à leur rythme, et le jour où le dernier
   passe, cette règle disparaît sans que rien ne bouge à l'œil. */
.carte {
  padding: 1.35rem 1.4rem;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}

.carte > h2:first-child { margin-top: 0; }

/* Deux cartes qui se suivent doivent se lire comme deux blocs, pas comme un
   seul : sans cette marge elles se touchent, et l'ombre ne suffit pas à les
   séparer sur un fond crème. Se voyait sur l'écran des notifications, le
   premier à en empiler deux. */
.carte + .carte { margin-top: 1.1rem; }

/* --- Champs de saisie ------------------------------------------------------
   Un socle pour **tout** champ, y compris ceux d'un formulaire qui ne porte
   aucune classe. La refonte du 10/09/2026 a habillé les boutons et oublié les
   champs : `email_boites.html` s'est retrouvé avec des cases grises de
   navigateur au milieu de cartes dessinées, et ça ne s'est vu qu'en capture.
   Sélecteur d'élément nu, donc la spécificité la plus basse qui soit : tout ce
   qui habille déjà ses champs (`form.edition`, `.creneau`, `.filtres`) continue
   de gagner sans qu'on ait à toucher à ces règles. */
input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
select,
textarea {
  font: inherit;
  color: var(--texte);
  background: #fff;
  padding: .55rem .75rem;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-petit);
}

input:not([type="checkbox"]):not([type="radio"]):focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -1px;
}

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

/* Volontairement grands : cliquables sans viser, pendant qu'on parle. */
button, .bouton {
  font: inherit;
  font-weight: 650;
  font-size: .84rem;
  padding: .55rem .9rem;
  min-height: 2.5rem;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon-petit);
  background: var(--carte);
  color: var(--texte);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  text-decoration: none;
  transition: border-color .15s, background .15s, box-shadow .15s, transform .06s;
}

button:hover, .bouton:hover {
  background: #f8f7ff;
  border-color: var(--accent-trait);
  color: var(--accent-fort);
}

button:active, .bouton:active { transform: translateY(1px); }

/* **Vermillon : c'est la couleur de ce qu'on clique.** Demandé le 31/08/2026.
   Le risque était de la confondre avec le rouge « dette » — il ne se produit
   pas, parce que les deux ne se présentent jamais pareil : un bouton est un
   aplat vermillon plein avec du texte blanc, un état est une pastille pâle
   avec du texte rouge foncé. L'un se clique, l'autre se lit ; l'œil ne les
   mélange pas. Ce qui reste interdit, c'est de teinter un fond de ligne ou un
   badge en vermillon — là, la confusion serait réelle. */
/* **L'action principale.** Le violet ne peut se confondre avec aucun état —
   c'est ce qui a permis de réunir sélection et action sur une seule couleur le
   10/09/2026, là où le vermillon frôlait le rouge de la dette. Ce qui reste
   interdit est inchangé : teinter un fond de ligne ou une étiquette avec la
   couleur d'action. Un bouton est un aplat plein à texte blanc, un état une
   pastille pâle à texte foncé ; l'œil ne les mélange pas. */
.bouton.demarrer, button.demarrer {
  display: inline-flex;
  margin: .5rem 0 0;
  text-decoration: none;
  color: #fff;
  background: var(--accent);
  border-color: var(--accent);
  box-shadow: 0 4px 10px rgba(91, 61, 240, .18);
}

.bouton.demarrer:hover, button.demarrer:hover {
  color: #fff;
  background: var(--accent-fort);
  border-color: var(--accent-fort);
}

/* Action de rattrapage, pas d'usage courant : présente sans attirer l'œil. */
button.discret, .bouton.discret {
  margin-top: .6rem;
  font-weight: 600;
  font-size: .78rem;
  min-height: 2.1rem;
  padding: .35rem .7rem;
  color: var(--texte-doux);
}

/* Une rangée de gros boutons, la même partout : fiche, script, liste. */
.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem;
  margin: 1.5rem 0;
}

.actions .bouton { text-decoration: none; }

/* Dans une carte de liste, la marge basse creuserait un vide sous les boutons. */
ol.prospects .actions { margin-bottom: 0; }

/* `discret` porte une marge haute quand il est seul en fin d'écran ; dans une
   rangée elle décalerait le bouton d'un cran vers le bas. */
.actions .discret { margin-top: 0; }

/* Rouge sur le mot seulement, pas de bouton rouge plein : « ne plus jamais
   appeler » doit se lire avant d'être cliqué, sans pour autant dominer l'écran
   d'une fiche qu'on ouvre le plus souvent pour la relire. */
button.discret.danger { color: var(--rouge); }

/* Les deux rattrapages de la fiche vivent sous un trait, à distance du bouton
   « Appeler » : rien ne doit rendre confondables « composer le numéro » et
   « effacer l'historique ». */
.actions.rattrapage {
  margin-bottom: .5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--bordure);
}

.fiche > .aide { margin: 0 0 1.5rem; font-size: .85rem; }

/* La saisie du prix et le transfert, à l'intérieur de la ligne du rendez-vous : ce
   sont des gestes *sur ce rendez-vous-là*, pas sur la fiche. D'où leur place dans
   le journal plutôt que dans la rangée d'actions du haut. */
form.vente {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem;
  margin: .6rem 0 0;
  font-size: .9rem;
  color: var(--texte-doux);
}

form.vente button.discret { margin-top: 0; }
form.vente input[type="text"] { width: 6rem; }

/* Le réglage de l'objectif : sur une ligne, à hauteur du texte qui l'annonce.
   C'est un ajustement occasionnel, il ne doit pas peser autant qu'un filtre. */
form.objectif {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin: 0 0 1.5rem;
  font-size: .9rem;
  color: var(--texte-doux);
}

form.objectif label {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin: 0;
}

form.objectif input {
  width: 4.5rem;
  padding: .4rem .5rem;
  text-align: center;
}

form.objectif .discret { margin-top: 0; }

/* --- Badges et pastilles de statut ---------------------------------------- */

.badges {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin: .6rem 0 0 3.5rem;
}

.badges:empty { display: none; }

/* Le format `.tag` de la maquette, porté par l'ancien nom : plus de bordure,
   un rayon serré, et le point de couleur qui rend l'étiquette lisible de loin
   sans avoir à lire le mot. */
.badge, .pastille {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  font-size: .72rem;
  font-weight: 650;
  padding: .25rem .55rem;
  border-radius: 6px;
  border: 0;
  color: var(--gris);
  background: var(--gris-pale);
  white-space: nowrap;
}

.badge::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

/* Une couleur par sens — réutilisée à l'identique partout dans l'appli. */
.badge.vert,   .pastille.vert   { color: var(--vert);   border-color: var(--vert-trait);   background: var(--vert-pale); }
.badge.ambre,  .pastille.ambre  { color: var(--ambre);  border-color: var(--ambre-trait);  background: var(--ambre-pale); }
.badge.rouge,  .pastille.rouge  { color: var(--rouge);  border-color: var(--rouge-trait);  background: var(--rouge-pale); }
.badge.violet, .pastille.violet { color: var(--violet); border-color: var(--violet-trait); background: var(--violet-pale); }
.badge.bleu,   .pastille.bleu   { color: var(--accent-fort); border-color: var(--accent-trait); background: var(--accent-pale); }
/* Le badge qui dit « ce rendez-vous vient d'un message ». Aplat plein et non
   pastille pâle comme les états : c'est une provenance, pas une alerte. */
.badge.acide,  .pastille.acide  { color: var(--texte); border-color: var(--acide); background: var(--acide); }

/* Le signal qui porte l'offre : pas de site web. Il doit sauter aux yeux. */
.badge.fort {
  color: var(--vert);
  border-color: var(--vert-trait);
  background: var(--vert-pale);
}

.badge.prudence {
  color: var(--ambre);
  border-color: var(--ambre-trait);
  background: var(--ambre-pale);
}

.badge.rappel {
  color: var(--accent-fort);
  border-color: var(--accent-trait);
  background: var(--accent-pale);
}

/* --- Filtres et onglets --------------------------------------------------- */

/* **Une grille et non une colonne**, comme le `filter-panel` de la maquette.
   Empilés, six filtres poussaient la liste sous la ligne de flottaison : on
   descendait pour voir ce que le filtre venait de produire. `auto-fit` range
   les champs sur deux ou trois colonnes selon la place, sans point de rupture
   à maintenir. */
.filtres {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  align-items: end;
  gap: .9rem;
  margin: 1.25rem 0 1.6rem;
  padding: 1.2rem 1.35rem;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}

/* Les actions occupent toute la largeur et se rangent à droite : un bouton
   « Filtrer » coincé dans une colonne du milieu se cherche. */
.filtres .actions {
  grid-column: 1 / -1;
  display: flex;
  gap: .5rem;
  justify-content: flex-end;
  margin: 0;
}

.filtres label {
  display: flex;
  flex-direction: column;
  gap: .25rem;
  font-size: .85rem;
  font-weight: 600;
  color: var(--texte-doux);
}

.filtres select, .filtres input[type="text"], .filtres input[type="search"] {
  font: inherit;
  font-size: .85rem;
  min-height: 2.5rem;
  width: 100%;
  padding: 0 .65rem;
  border: 1px solid #dfe2ed;
  border-radius: var(--rayon-petit);
  background: var(--carte);
  color: var(--texte);
}

.filtres select:focus, .filtres input:focus {
  outline: 0;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(91, 61, 240, .12);
}

.filtres .bouton { text-decoration: none; }

/* Filtres à cocher : les deux groupes s'empilent, chacun sur toute la largeur.
   Un menu déroulant n'aurait pas pu dire « Albertville et Moûtiers ». */
/* **Les groupes de cases prennent la largeur, les champs simples se rangent en
   colonnes.** C'est la nuance : « BTP et coiffure » est une seule matinée et se
   lit d'un bloc, alors qu'une ville, un site et un téléphone sont trois
   questions indépendantes qui tiennent côte à côte. Tout empiler poussait la
   liste sous la ligne de flottaison — on descendait pour voir ce que le filtre
   venait de produire. */
.filtres.cases { gap: 1rem; }

.filtres.cases fieldset { margin: 0; padding: 0; border: 0; }
.filtres fieldset, .filtres .cherche { grid-column: 1 / -1; }

.filtres.cases legend {
  padding: 0 0 .6rem;
  font-size: .85rem;
  font-weight: 600;
  color: var(--texte-doux);
}

/* Un groupe de cases défile plutôt que de repousser la liste d'appels hors de
   l'écran : les secteurs tiennent en une ligne, les départements aussi, mais la
   hauteur est bornée une fois pour toutes plutôt qu'à surveiller. */
.filtres.cases .choix {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  max-height: 9.5rem;
  overflow-y: auto;
}

/* Toute la pastille est cliquable, pas seulement la petite case : c'est la même
   règle que les gros boutons d'appel.

   **`min-width: 0` et le texte qui passe à la ligne** (29/09/2026) : mesuré à
   900 px, les pastilles de secteur sortaient de l'écran de cent pixels, sans
   aucun moyen de les atteindre — ni défilement, ni retour à la ligne. Une case
   à cocher qu'on ne peut pas cliquer est un filtre qui n'existe pas. */
.filtres.cases label.case {
  display: flex;
  flex-direction: row;
  align-items: center;
  min-width: 0;
  max-width: 100%;
  gap: .45rem;
  padding: .5rem .75rem;
  font-size: .9rem;
  font-weight: 500;
  color: var(--texte);
  border: 1px solid var(--bordure);
  border-radius: 999px;
  background: var(--carte);
  cursor: pointer;
}

.filtres.cases label.case:has(input:checked) {
  color: var(--accent-fort);
  border-color: var(--accent);
  background: var(--accent-pale);
}

.filtres.cases label.case:has(input:focus-visible) {
  outline: 2px solid var(--vermillon);
  outline-offset: 2px;
}

.filtres.cases label.case input { width: 1.05rem; height: 1.05rem; margin: 0; }

.filtres.cases label.case .muted { font-weight: 400; }
.filtres.cases label.case > span { min-width: 0; overflow-wrap: anywhere; }

.filtres.cases .actions { margin: 0; }

/* La ville se tape depuis le 16/08/2026 : à trois départements en base, le mur
   de cases n'était plus lisible. Le champ est plus large que les autres — c'est
   celui qu'on vise, et un nom de commune est long (« Bourg-Saint-Maurice »). */
.filtres .cherche input[type="search"] { max-width: 22rem; width: 100%; }

/* Onglets par état : le compteur fait partie de l'onglet, sinon il faut
   cliquer pour savoir s'il y a quelque chose derrière.

   **Ils prennent la forme des onglets de la maquette** (10/09/2026) plutôt que
   les pastilles d'hier : un trait sous l'onglet courant, pas un aplat. Le
   vocabulaire ancien (`.onglets`, `.ici`, `.combien`) est conservé — vingt
   gabarits le nomment — mais il rend désormais comme `.tabs`, `.active` et
   `.tab-count`. Réécrire les vingt d'un coup serait la façon la plus sûre d'en
   casser un qu'on n'ouvre qu'une fois par mois. */
.onglets {
  display: flex;
  gap: 21px;
  margin: 0 0 22px;
  padding: 0 0 0 2px;
  border-bottom: 1px solid var(--bordure);
  overflow: auto;
  list-style: none;
}

.onglets a {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 0 0 14px;
  border: 0;
  background: transparent;
  font-size: 12px;
  color: #80869a;
  font-weight: 600;
  white-space: nowrap;
  position: relative;
  text-decoration: none;
}

.onglets a:hover { color: var(--accent); }

/* Sélectionné = le violet de la marque et un trait dessous, la même règle que
   l'entrée courante de la barre latérale : on apprend le repère une fois. */
.onglets a.ici { color: var(--accent); }

.onglets a.ici:after {
  content: '';
  height: 2px;
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--accent);
  border-radius: 2px;
}

.onglets .combien {
  font-variant-numeric: tabular-nums;
  font-size: 10px;
  background: #f2f3f7;
  border-radius: 4px;
  padding: 2px 5px;
  margin-left: 5px;
  color: #82889c;
}

.onglets a.ici .combien { color: var(--accent); background: var(--accent-pale); }

/* Remonter dans le temps : les deux flèches aux extrémités, la période lue au
   milieu. Le nom au centre parce que c'est lui qu'on cherche des yeux en arrivant —
   lire « juillet 2026 » évite de prendre ces chiffres pour ceux du mois en cours. */
nav.recul {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin: -1rem 0 1.5rem;
  font-size: .95rem;
}

nav.recul strong { font-size: 1.05rem; }
nav.recul a { color: var(--accent-fort); font-weight: 600; text-decoration: none; }
nav.recul a:hover { text-decoration: underline; }

/* Même traitement que `.empty` de la maquette : un écran vide se lit comme un
   message, pas comme une page qui n'a pas fini de charger. */
.vide {
  padding: 2rem 1.75rem;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
  color: var(--texte-doux);
}

/* --- Calendrier de l'agenda ---------------------------------------------- */

/* Au dashboard la navigation suit un titre, d'où sa marge haute négative. Ici
   elle suit les cartes du retard : sans cette reprise, « mois précédent » colle
   au bas de la dernière carte et a l'air de lui appartenir. */
nav.recul.mois { margin-top: 2.5rem; }

/* La seule grille de l'application, et le seul tableau : un mois **est** une
   grille, l'étaler en liste perdrait justement ce qu'on vient y chercher — quelle
   semaine est chargée, laquelle est vide. Les couleurs sont celles des badges de
   l'agenda : vert pour un déplacement, ambre pour une relance de devis, bleu pour
   un rappel. On lit le mois sans lire les noms. */
table.calendrier {
  width: 100%;
  margin: 0 0 2rem;
  border-collapse: separate;
  border-spacing: 4px;
  table-layout: fixed;      /* sept colonnes égales, qu'un nom long ne déforme pas */
}

table.calendrier th {
  padding: .2rem;
  font-size: .85rem;
  font-weight: 600;
  color: var(--texte-doux);
  text-align: left;
}

table.calendrier td {
  height: 5.5rem;
  vertical-align: top;
  padding: .35rem .4rem;
  border-radius: 9px;
  background: var(--carte);
  box-shadow: var(--ombre);
}

/* Les jours des mois voisins restent là — une case vide en fin de ligne ferait
   croire à une semaine tronquée — mais s'effacent. */
table.calendrier td.hors-mois { background: transparent; box-shadow: none; }
table.calendrier td.hors-mois .numero { color: var(--bordure); }

table.calendrier .numero {
  display: block;
  font-size: .9rem;
  font-variant-numeric: tabular-nums;
  color: var(--texte-doux);
}

/* Aujourd'hui : le repère depuis lequel tout le reste se lit. */
table.calendrier td.est-aujourdhui {
  outline: 2px solid var(--vermillon);
  outline-offset: -2px;
}

table.calendrier td.est-aujourdhui .numero {
  color: var(--accent-fort);
  font-weight: 700;
}

/* Une échéance par pastille, l'heure au-dessus du nom : côte à côte dans une
   colonne de 96 px, l'heure ne laisserait au nom que quatre lettres. Le nom est
   coupé plutôt qu'il n'élargisse la colonne — la liste dessous porte le détail. */
table.calendrier .case {
  display: block;
  margin-top: .25rem;
  padding: .15rem .3rem;
  border-radius: 5px;
  font-size: .8rem;
  line-height: 1.35;
}

table.calendrier .case b { font-variant-numeric: tabular-nums; }

table.calendrier .case .qui {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

table.calendrier .case.rdv     { color: var(--vert);   background: var(--vert-pale); }
/* **L'origine d'un rendez-vous, pas son état.** Demandé le 09/09/2026 : voir
   d'un coup d'œil ce qui a été décroché au téléphone et ce qui l'a été par
   message. L'acide est le marqueur du module Messages — le même que le filet
   de son bandeau — et non une quatrième couleur d'état : vert, ambre et rouge
   restent réservés aux données, la règle tient. Texte noir : l'acide est trop
   clair pour porter du texte, c'est déjà pourquoi les onglets du module
   s'écrivent en noir dessus. */
table.calendrier .case.rdv-sms { color: var(--texte); background: var(--acide); }
table.calendrier .case.relance { color: var(--ambre);  background: var(--ambre-pale); }
table.calendrier .case.rappel  { color: var(--accent-fort); background: var(--accent-pale); }
/* Un client à relancer (15/09/2026) : **en rouge, à la demande du propriétaire**,
   d'abord posé en violet. Le rouge dit ici « à ne pas laisser filer » — une
   affaire qui refroidit si personne ne la reprend, ce qui reste un problème à
   traiter et donc dans le sens du rouge de la maison. */
table.calendrier .case.relance-client { color: var(--rouge); background: var(--rouge-pale); }

/* La semaine et la journée (15/09/2026) : moins de colonnes, donc des cases plus
   hautes et des noms entiers — c'est la vue d'ensemble qu'on vient y chercher. */
table.calendrier[data-vue="semaine"] td { height: 11rem; }
table.calendrier[data-vue="jour"] td { height: 8rem; padding: .6rem .9rem; }
table.calendrier[data-vue="jour"] .case { font-size: .95rem; padding: .35rem .6rem; }
table.calendrier[data-vue="semaine"] .case .qui,
table.calendrier[data-vue="jour"] .case .qui { white-space: normal; }

/* --- Pipeline ------------------------------------------------------------- */

/* Les six colonnes tiennent **à l'écran en même temps** : le pipeline *est* la
   gauche-droite de la vente, et une sixième colonne qu'il faut aller chercher au
   défilement ne se lit plus d'un coup d'œil. Elles se partagent donc la largeur à
   parts égales et ne se resserrent pas en dessous de 10,5 rem — un nom
   d'établissement en trois lettres ne se reconnaît pas. Sur un écran vraiment
   étroit c'est le bloc qui défile, jamais la page entière. */
.pipeline {
  display: flex;
  gap: .75rem;
  overflow-x: auto;
  padding-bottom: .75rem;
  align-items: flex-start;
}

.pipeline .colonne {
  flex: 1 1 0;
  min-width: 10.5rem;
  padding: .75rem .7rem 1rem;
  border-radius: 12px;
  background: var(--gris-pale);
  /* Le trait du haut porte la couleur du statut : on voit de loin où en est la
     masse des fiches, sans lire les titres. */
  border-top: 4px solid var(--bordure);
}

.pipeline .colonne.bleu   { border-top-color: var(--accent); }
.pipeline .colonne.violet { border-top-color: var(--violet-trait); }
.pipeline .colonne.ambre  { border-top-color: var(--ambre-trait); }
.pipeline .colonne.vert   { border-top-color: var(--vert-trait); }
.pipeline .colonne.rouge  { border-top-color: var(--rouge-trait); }

.pipeline h2 {
  margin: 0 0 .5rem;
  font-size: .95rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .4rem;
}

/* Le total est sur le titre, pas en dessous : « Devis envoyé 7 » se lit d'un
   coup, et c'est le chiffre qu'on vient chercher. */
.pipeline h2 .combien {
  font-variant-numeric: tabular-nums;
  font-size: .85rem;
  font-weight: 600;
  padding: 0 .45rem;
  border-radius: 999px;
  background: var(--carte);
  color: var(--gris);
}

/* Le compte des immobilisés de la colonne. Un bloc et non une pastille de badge :
   la phrase tient sur deux lignes dans une colonne de 170 px, et un badge en
   pastille ne se coupe pas — il déborderait. */
.pipeline .alerte-colonne {
  margin: 0 0 .6rem;
  padding: .3rem .45rem;
  border-radius: 7px;
  font-size: .78rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ambre);
  background: var(--ambre-pale);
}

.pipeline .vide { margin: 0; padding: .5rem 0; font-size: .85rem; }

.pipeline ol.cartes {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.pipeline ol.cartes li {
  padding: .5rem .55rem;
  border-radius: 9px;
  background: var(--carte);
  box-shadow: var(--ombre);
}

/* L'immobilité se voit avant qu'on lise le badge : c'est toute la raison de
   l'écran. Un trait à gauche plutôt qu'un fond ambre — six cartes ambre côte à
   côte ne se distingueraient plus les unes des autres. */
.pipeline ol.cartes li.immobile {
  border-left: 4px solid var(--ambre-trait);
  padding-left: .4rem;
}

.pipeline .nom {
  font-weight: 600;
  font-size: .92rem;
  line-height: 1.3;
  color: var(--texte);
  text-decoration: none;
}

.pipeline .nom:hover { color: var(--accent-fort); }

/* `margin-left: 0` : ailleurs le détail est décalé pour laisser passer la pastille
   de score dans la marge — ici le score est dans le texte, et le renfoncement se
   lirait comme un alinéa. */
.pipeline .detail { margin: .15rem 0 0; font-size: .78rem; }

.pipeline .badges {
  margin: .35rem 0 0;
  gap: .25rem;
}

.pipeline .badges .badge { font-size: .72rem; padding: .05rem .3rem; }

.pipeline .reste { margin: .6rem 0 0; font-size: .82rem; }

/* Où corriger un statut à la main. Sous les colonnes et en petit : c'est la
   réponse à une question qu'on se pose une fois, pas une action de l'écran. */
.pipeline + .aide { margin: 1.5rem 0 0; font-size: .85rem; }

/* --- Liste de prospects --------------------------------------------------- */

/* Une fiche par carte, jamais de tableau à déchiffrer. */
ol.prospects {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

ol.prospects li {
  padding: 1.4rem 1.6rem;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
  border-left: 4px solid transparent;
}

/* Un rappel dû n'est pas un prospect ordinaire : il a été promis. */
ol.prospects li.rappel { border-left-color: var(--accent); }

/* Un rendez-vous engage un déplacement : vert, comme partout où la vente avance. */
ol.prospects li.rdv { border-left-color: var(--vert); }

.tete {
  display: flex;
  align-items: center;
  gap: .9rem;
}

/* Le score décide de l'ordre de la file : il se lit avant le nom. */
.score {
  flex: none;
  min-width: 2.8rem;
  padding: .3rem 0;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 1.05rem;
  text-align: center;
  border-radius: 9px;
  color: var(--gris);
  background: var(--gris-pale);
}

/* Chaud = à appeler en premier. L'échelle suit le poids de « pas de site web »
   (40 points) : au-dessus de 60, la fiche coche presque toujours ce signal. */
/* Le vermillon dit ici exactement ce qu'il doit dire : un prospect brûlant.
   Ce n'est pas un état négatif mais une intensité, et un score ne côtoie jamais
   un badge de dette — aucun risque de le lire comme une alerte. */
.score.chaud   { color: #fff; background: var(--vermillon); }
.score.tiede   { color: var(--ambre); background: var(--ambre-pale); }

.nom {
  font-size: 1.2rem;
  font-weight: 650;
  letter-spacing: -.01em;
}

/* Le nom est le lien vers la fiche : c'est là qu'on clique naturellement. */
a.nom { color: var(--texte); text-decoration: none; }
a.nom:hover { color: var(--accent-fort); text-decoration: underline; }

.detail {
  margin: .5rem 0 0 3.7rem;
  font-size: .95rem;
}

.note {
  margin: .6rem 0 0 3.7rem;
  padding: .5rem .9rem;
  border-radius: 8px;
  background: var(--fond);
  font-style: italic;
  font-size: .95rem;
}

.bouton.appeler {
  display: inline-block;
  margin: 1rem 0 0 3.7rem;
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}

/* Sans badge de score, il n'y a rien sous quoi aligner : on retire le retrait. */
ol.prospects.sans-score .detail,
ol.prospects.sans-score .badges,
ol.prospects.sans-score .note,
ol.prospects.sans-score .bouton.appeler { margin-left: 0; }

/* Les secteurs d'un compte, repliés sous son nom. Repliés parce qu'on ouvre
   l'écran des comptes pour créer quelqu'un ou lui redonner un mot de passe :
   six listes de cases dépliées d'office noieraient ces deux gestes-là. Le
   `<summary>` reste du texte et non un bouton — contrairement à celui des
   arguments, il n'ouvre pas ce qu'on est venu chercher. */
details.secteurs { margin-top: 1rem; font-size: .9rem; }

details.secteurs > summary {
  cursor: pointer;
  user-select: none;
  color: var(--texte-doux);
}

details.secteurs > summary:hover { color: var(--texte); }

details.secteurs form {
  margin-top: .9rem;
  padding: .9rem 1.1rem;
  border-radius: var(--rayon);
  background: var(--fond);
}

/* En colonnes qui se replient, comme le type d'établissement : sept cases
   empilées éloigneraient le bouton du premier choix qu'on vient faire. */
details.secteurs label.case {
  display: inline-flex;
  align-items: center;
  gap: .6rem;
  width: 15.5rem;
  margin: 0 1.25rem .6rem 0;
}

details.secteurs label.case input { width: auto; margin: 0; }
details.secteurs .aide { margin: .5rem 0 .9rem; font-size: .85rem; }

/* --- Confirmation d'enregistrement --------------------------------------- */

/* L'écran est déjà passé au suivant : c'est la seule preuve que le clic a été
   pris en compte. */
ul.flash {
  margin: 0 0 2rem;
  padding: 1rem 1.25rem;
  list-style: none;
  border-left: 4px solid var(--accent);
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
  font-weight: 600;
}

/* --- Écran d'état -------------------------------------------------------- */

dl.status {
  margin-top: 2rem;
  padding: .5rem 1.75rem 1.5rem;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}

dl.status dt {
  font-weight: 600;
  padding-top: 1rem;
}

dl.status dd {
  margin: 0 0 1rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--bordure);
}

dl.status dd:last-child { border-bottom: 0; margin-bottom: 0; }

dl.status ul {
  margin: .5rem 0 0;
  padding-left: 1.2rem;
}

/* --- Dashboard ----------------------------------------------------------- */

/* Le chiffre qui décide si la journée est faite : lisible de loin, sans lire. */
.bilan {
  margin: 2rem 0;
  padding: 1.75rem;
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  color: #fff;
  /* **Le seul dégradé de l'application**, repris de la maquette du 10/09/2026.
     Il n'est pas décoratif : cette carte porte le chiffre qu'on vient chercher
     en ouvrant l'écran, et l'aplat sombre d'avant la laissait se confondre avec
     n'importe quel encadré. Le cyan n'apparaît qu'ici et en appui — jamais sur
     une donnée, la règle des couleurs d'état tient. */
  background: linear-gradient(112deg, var(--accent) 5%, #6451e7 67%, #547cdb);
  position: relative;
  overflow: hidden;
}

.bilan::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse at 100% 0,
                              rgba(79, 179, 217, .4), transparent 65%);
}

.bilan > * { position: relative; z-index: 1; }

/* Objectif atteint : le vert reprend la main. C'est un **état**, et un état
   passe toujours devant l'habillage. */
.bilan.atteint { background: var(--vert); }
.bilan.atteint::after { display: none; }

.bilan .chiffre {
  margin: 0;
  font-size: 3.4rem;
  font-weight: 750;
  line-height: 1;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}

.bilan .chiffre .sur {
  font-size: 1.6rem;
  font-weight: 600;
  opacity: .65;
}

.bilan .dit { margin: .5rem 0 0; opacity: .9; }

/* Sur quoi l'objectif est calculé : sans ça, « 42 / 150 » a l'air arbitraire. */
.bilan .assise { margin: .9rem 0 0; font-size: .85rem; color: rgba(255, 255, 255, .7); }

/* Le rythme jour après jour : les totaux ne disent pas si le travail a été
   régulier ou fait d'un bloc. Les jours sans appel restent visibles — c'est
   précisément l'information. */
ul.rythme {
  display: flex;
  align-items: flex-end;
  gap: .4rem;
  margin: 0;
  padding: 1.5rem 1.25rem 1rem;
  list-style: none;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
  overflow-x: auto;
}

ul.rythme li {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  gap: .35rem;
  min-width: 1.6rem;
}

ul.rythme .colonne {
  display: flex;
  align-items: flex-end;
  width: 100%;
  height: 7rem;
  border-radius: 6px;
  background: var(--fond);
  overflow: hidden;
}

ul.rythme .tige {
  width: 100%;
  min-height: 3px;
  border-radius: 6px;
  background: var(--accent);
}

/* `sans-appel` et non `vide` : `.vide` est la carte des écrans sans contenu, elle
   habillerait chaque jour creux en carte blanche. */
ul.rythme li.sans-appel .tige { background: none; }

/* Hauteur réservée même sans chiffre, sinon les étiquettes des jours creux
   remontent d'une ligne et la base du graphique ondule. */
ul.rythme .nombre {
  min-height: 1.25rem;
  font-size: .8rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

ul.rythme .etiquette { font-size: .7rem; white-space: nowrap; }

dl.mesures {
  margin: 2rem 0;
  padding: .5rem 1.75rem;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}

dl.mesures div {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 0;
  border-bottom: 1px solid var(--bordure);
}

dl.mesures div:last-child { border-bottom: 0; }

dl.mesures dt { color: var(--texte-doux); }

dl.mesures dd {
  margin: 0;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

dl.mesures dd .muted { font-weight: 400; font-size: .9rem; }

/* **Les couleurs d'état, sur un chiffre de mesure.** Le gabarit des SMS pose
   `class="rouge"` sur les STOP reçus depuis le 08/09/2026, et E-mail fait de
   même sur le taux de rebond — mais aucune règle ne les servait, et les deux
   chiffres sortaient en noir. Un coût qu'on a décidé de signaler et qui ne se
   signale pas est pire que pas de signal : on croit l'avoir vu. */
dl.mesures dd.rouge { color: var(--rouge); }
dl.mesures dd.ambre { color: var(--ambre); }
dl.mesures dd.vert  { color: var(--vert); }

/* Les chiffres d'une campagne e-mail (22/09/2026) : huit mesures côte à côte,
   pour que deux campagnes se comparent d'un coup d'œil. En liste, une campagne
   prenait un écran entier. */
dl.mesures.grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10.5rem, 1fr));
  gap: .5rem;
  padding: 0;
  box-shadow: none;
  background: none;
}
dl.mesures.grille div {
  display: block;
  border: 1px solid var(--bordure);
  border-radius: 10px;
  padding: .6rem .75rem;
}
dl.mesures.grille dt { font-size: .85rem; }
dl.mesures.grille dd { text-align: left; margin: .15rem 0 0; font-size: 1.35rem; }
dl.mesures.grille dd.muted { font-size: .85rem; font-weight: 400; }

ul.repartition {
  margin: 0;
  padding: 1.5rem 1.75rem;
  list-style: none;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}

ul.repartition li {
  display: grid;
  grid-template-columns:11rem minmax(0,1fr) 2rem;
  align-items: center;
  gap: 1rem;
  padding: .45rem 0;
}

ul.repartition .barre {
  height: 1rem;
  border-radius: 999px;
  background: var(--fond);
  overflow: hidden;
}

ul.repartition .barre span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--gris-trait);
}

/* La barre reprend la couleur du résultat : le graphique se lit sans légende. */
ul.repartition .barre span.vert   { background: var(--vert); }
ul.repartition .barre span.ambre  { background: var(--ambre); }
ul.repartition .barre span.rouge  { background: var(--rouge); }
ul.repartition .barre span.bleu   { background: var(--accent); }
ul.repartition .barre span.violet { background: var(--violet); }

ul.repartition .nombre {
  text-align: right;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Qui a appelé : la décomposition du chiffre du haut, une personne par ligne.
   Même grammaire visuelle que la répartition des résultats — nom, barre, nombre —
   pour que l'écran ne demande pas à réapprendre à se lire à mi-hauteur. */
ul.par-personne {
  margin: 0;
  padding: 1.5rem 1.75rem;
  list-style: none;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}

ul.par-personne li {
  display: grid;
  grid-template-columns:11rem minmax(0,1fr) 6rem;
  align-items: center;
  gap: .5rem 1rem;
  padding: .8rem 0;
  border-top: 1px solid var(--gris-pale);
}

ul.par-personne li:first-child { border-top: 0; padding-top: 0; }

/* Le badge partage la cellule du nom plutôt que d'avoir sa colonne : une équipe
   sans compte archivé garderait sinon une colonne vide au milieu de la ligne. */
ul.par-personne .nom { font-weight: 650; }
ul.par-personne .nom .badge { margin-left: .4rem; font-weight: 500; }

ul.par-personne .barre {
  height: 1rem;
  border-radius: 999px;
  background: var(--fond);
  overflow: hidden;
}

ul.par-personne .barre span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--gris-trait);
}

ul.par-personne .barre span.vert { background: var(--vert); }
ul.par-personne .barre span.bleu { background: var(--accent); }

ul.par-personne .nombre {
  text-align: right;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Le détail passe sous la barre : sur la même ligne, il écraserait le nom. */
ul.par-personne .detail {
  grid-column: 2 / -1;
  font-size: .85rem;
}

/* L'entonnoir : même grammaire que les deux listes du dessus — libellé, barre,
   nombre — plus une colonne pour le taux de passage. Les barres ne dessinent pas
   un entonnoir centré : alignées à gauche, deux marches se comparent en suivant un
   bord droit, ce qu'un trapèze interdit. */
ul.entonnoir {
  margin: 0;
  padding: 1.5rem 1.75rem;
  list-style: none;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}

ul.entonnoir li {
  display: grid;
  grid-template-columns:11rem minmax(0,1fr) 2.5rem 4rem;
  align-items: center;
  gap: 1rem;
  padding: .45rem 0;
}

ul.entonnoir .barre {
  height: 1rem;
  border-radius: 999px;
  background: var(--fond);
  overflow: hidden;
}

ul.entonnoir .barre span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--gris-trait);
}

/* La couleur est celle de la colonne du pipeline où mène la marche : le même
   violet pour « intéressés » sur les deux écrans. */
ul.entonnoir .barre span.bleu   { background: var(--accent); }
ul.entonnoir .barre span.violet { background: var(--violet); }
ul.entonnoir .barre span.ambre  { background: var(--ambre); }
ul.entonnoir .barre span.vert   { background: var(--vert); }

ul.entonnoir .nombre {
  text-align: right;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Le taux de passage, aligné à droite pour se comparer d'une ligne à l'autre :
   c'est la colonne où l'on cherche le décrochage. */
ul.entonnoir .passage {
  text-align: right;
  font-size: .85rem;
  font-variant-numeric: tabular-nums;
}

ul.entonnoir + .aide { margin: 1rem 0 0; font-size: .85rem; }

/* Les sites vendus : la même carte que les deux listes du dessus, mais le prix à
   la place de la barre. Pas de barre justement — une vente n'a pas d'objectif à
   côté duquel se comparer, et le chiffre qu'on vient chercher est la somme. */
ul.ventes {
  margin: 0;
  padding: 1.5rem 1.75rem;
  list-style: none;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}

ul.ventes li {
  display: grid;
  grid-template-columns:minmax(0,1fr) 8rem;
  align-items: baseline;
  gap: .3rem 1rem;
  padding: .8rem 0;
  border-top: 1px solid var(--gris-pale);
}

ul.ventes li:first-child { border-top: 0; padding-top: 0; }

ul.ventes .nom { font-weight: 650; }
ul.ventes .detail { grid-column: 1; font-size: .85rem; }

/* Tabulaire et à droite : c'est une colonne de sommes, elle doit s'additionner à
   l'œil. Verte comme partout où la vente avance. */
ul.ventes .prix {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: center;
  text-align: right;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--vert);
}

/* Le total porte le trait épais : c'est le chiffre avec lequel on rémunère. */
ul.ventes li.total {
  border-top: 2px solid var(--gris-trait);
  padding-bottom: 0;
}

ul.ventes li.total .prix { grid-row: 1; font-size: 1.15rem; }

.suite { margin-top: 2.5rem; color: var(--texte-doux); }

/* --- Écran d'appel (mode focus) ------------------------------------------ */

[x-cloak] { display: none !important; }

.appel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 25rem);
  gap: 2.5rem;
  align-items: start;
}

@media (max-width: 62rem) {
  .appel { grid-template-columns:minmax(0,1fr); }
}

.appel .fiche-appel {
  padding: 1.75rem;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}

/* Le rappel des objections traverse les deux colonnes : coincé au-dessus de la
   seule fiche, il laisserait un blanc à côté du script et se lirait comme une
   remarque sur le prospect affiché, alors qu'il vaut pour tous les appels. */
.appel .objections { grid-column: 1 / -1; margin: 0; }

.appel .compteur { margin: 0 0 1.5rem; font-size: .95rem; }
.appel .nom { margin: 0; font-size: 1.6rem; }
.appel .detail, .appel .badges, .appel .note { margin-left: 3.7rem; }

.composer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem;
  margin: 1.5rem 0 0 3.7rem;
}

.composer .appeler { margin: 0; }
.composer .aide { font-size: .85rem; }

.chrono {
  display: flex;
  align-items: center;
  gap: .6rem;
}

.chrono output {
  font-variant-numeric: tabular-nums;
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--texte-doux);
}

/* Le chrono tourne : on est en ligne, le temps court. */
.chrono.tourne output { color: var(--rouge); }

label.notes {
  display: block;
  margin: 2rem 0 1rem 3.7rem;
  font-size: .85rem;
  font-weight: 600;
  color: var(--texte-doux);
}

label.notes textarea {
  display: block;
  width: 100%;
  margin-top: .35rem;
  padding: .7rem;
  font: inherit;
  font-weight: 400;
  color: var(--texte);
  border: 1px solid var(--bordure);
  border-radius: 10px;
  background: var(--carte);
  resize: vertical;
}

label.notes textarea:focus { outline: 2px solid var(--vermillon); outline-offset: -1px; }

/* Les résultats : gros boutons, un seul clic, jamais de formulaire. */
.resultats {
  display: flex;
  flex-wrap: wrap;
  gap: .75rem;
  margin-left: 3.7rem;
}

/* Le panneau reste sur une ligne ou deux : tout doit tenir sous les yeux
   pendant que le prospect parle, sans défiler. */
.resultats.panneau {
  padding: 1.25rem;
  border-radius: var(--rayon);
  background: var(--fond);
}

.resultats.panneau p {
  width: 100%;
  margin: 0;
  font-size: .9rem;
  color: var(--texte-doux);
}

/* Ce qui fait avancer la vente : vert, comme partout ailleurs. */
.resultats button.oui {
  color: var(--vert);
  border-color: var(--vert-trait);
  background: var(--vert-pale);
}

.resultats button.retour {
  color: var(--texte-doux);
  border-style: dashed;
  background: transparent;
}

/* Définitif : il doit se distinguer des cinq motifs qu'on clique sans y penser. */
.resultats button.jamais {
  color: var(--rouge);
  border-color: var(--rouge-trait);
  background: var(--rouge-pale);
}

/* Les mêmes boutons sur la fiche (`_resultats.html`), pour qualifier un prospect
   qu'on est allé chercher au lieu de le prendre dans la file du jour.
   Le retrait de 3.7rem appartient à l'écran d'appel : il dégage la pastille de
   score posée devant le nom, et il n'y a rien à dégager ici. */
.qualifier .resultats,
.qualifier label.notes { margin-left: 0; }

.qualifier label.notes { margin-top: 0; }

/* Un trait au-dessus, comme les rattrapages plus bas : composer un numéro et
   relire une fiche sont deux gestes, et rien ne doit les rendre confondables. */
.qualifier { padding-top: .25rem; border-top: 1px solid var(--bordure); }
.qualifier .actions { margin-top: 1.25rem; }

/* Un créneau, c'est deux champs natifs déjà remplis : le seul endroit de l'écran
   d'appel où l'on peut avoir à toucher autre chose qu'un bouton. Ils restent sur
   la même ligne que le bouton qui valide, pour que le geste soit d'un seul tenant. */
.creneau label {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-size: .95rem;
  color: var(--texte-doux);
}

.creneau input {
  padding: .55rem;
  font: inherit;
  color: var(--texte);
  border: 1px solid var(--bordure);
  border-radius: 10px;
  background: var(--carte);
}

.creneau input:focus { outline: 2px solid var(--vermillon); outline-offset: -1px; }

/* Sous les trois délais, séparée d'un trait : la date précise est le recours,
   pas le chemin normal. Elle tient sur une seule ligne — deux champs et le
   bouton qui valide —, sinon le panneau gagne une rangée et déborde du regard. */
.creneau.precis {
  display: flex;
  align-items: center;
  gap: .5rem;
  width: 100%;
  padding-top: .8rem;
  border-top: 1px solid var(--bordure);
}

kbd {
  display: inline-block;
  min-width: 1.4rem;
  margin-right: .35rem;
  padding: 0 .25rem;
  font-family: inherit;
  font-size: .8em;
  text-align: center;
  color: var(--texte-doux);
  border: 1px solid var(--bordure);
  border-radius: 5px;
  background: var(--fond);
}

details.historique {
  margin: 2.5rem 0 0 3.7rem;
  font-size: .95rem;
}

details.historique summary {
  cursor: pointer;
  color: var(--texte-doux);
}

details.historique ul {
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
}

details.historique li {
  padding: .6rem 0;
  border-bottom: 1px solid var(--bordure);
}

/* Retoucher le script sans quitter l'appel du regard : discret, à droite du titre. */
aside.script h2 .retoucher {
  float: right;
  font-size: .8rem;
  font-weight: 400;
}

/* Le script : lu pendant que ça sonne, donc calme et lisible. */
aside.script {
  padding: 1.5rem 1.75rem;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
  font-size: .95rem;
  position: sticky;
  top: 1.5rem;
  max-height: calc(100vh - 3rem);
  overflow-y: auto;
}

aside.script h2 { margin: 0 0 1rem; font-size: 1.1rem; }

/* Le Markdown du script, rendu à l'identique pendant l'appel (`aside.script`) et
   dans l'aperçu de la page d'édition (`.script-lu`) : un aperçu qui ne ressemble
   pas à l'écran d'appel ne dit pas si la phrase tombe juste. */
aside.script h3, aside.script h4,
.script-lu h3, .script-lu h4 { margin: 1.5rem 0 .5rem; font-size: 1rem; }

/* Ce qui se dit à voix haute, détaché du reste. */
aside.script blockquote,
.script-lu blockquote {
  margin: .75rem 0;
  padding: .3rem 0 .3rem 1rem;
  border-left: 3px solid var(--accent);
  color: var(--texte);
}

aside.script table,
.script-lu table {
  width: 100%;
  margin: 1rem 0;
  border-collapse: collapse;
  text-align: left;
}

aside.script th, aside.script td,
.script-lu th, .script-lu td {
  padding: .5rem .4rem;
  border-bottom: 1px solid var(--bordure);
  vertical-align: top;
}

aside.script th, .script-lu th { font-size: .85rem; color: var(--texte-doux); }
aside.script em, .script-lu em { color: var(--texte-doux); }

/* --- Arguments de vente --------------------------------------------------- */

/* Repliés, à côté du script pendant l'appel et sous le bouton « Appeler » de la
   fiche. Le `<summary>` a l'allure d'un bouton discret parce que c'en est un :
   c'est le « bouton pour les consulter », il ouvre sur place plutôt que d'emmener
   sur un autre écran. */
details.arguments {
  margin: 1.5rem 0 0;
  font-size: .95rem;
}

.fiche details.arguments { margin: 0 0 1.5rem; }

details.arguments > summary {
  display: inline-block;
  padding: .5rem 1rem;
  border: 1px solid var(--bordure);
  border-radius: 999px;
  background: var(--fond);
  color: var(--texte-doux);
  cursor: pointer;
  list-style: none;
  user-select: none;
}

details.arguments > summary::-webkit-details-marker { display: none; }
details.arguments > summary::after { content: " ▾"; opacity: .7; }
details.arguments[open] > summary::after { content: " ▴"; }
details.arguments > summary:hover { color: var(--texte); border-color: var(--accent); }

details.arguments article {
  margin-top: .9rem;
  padding: .9rem 1.1rem;
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--rayon) var(--rayon) 0;
  background: var(--fond);
}

details.arguments h3 { margin: 0 0 .4rem; font-size: 1rem; }
details.arguments p:last-child { margin-bottom: 0; }

/* L'écran d'écriture. C'est le `<li>` qui porte la carte : le formulaire d'édition
   et les boutons d'ordre sont deux `<form>` voisins — ils ne s'imbriquent pas — et
   les laisser dehors ferait flotter « Retirer » sous un bloc blanc, sans lien
   visible avec la carte qu'il retire. */
.arguments-edition { margin: 0; padding: 0; list-style: none; }

.arguments-edition > li {
  margin: 1.5rem 0;
  padding: 1.75rem;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}

.arguments-edition > li form.edition {
  margin: 0;
  padding: 0;
  background: none;
  box-shadow: none;
}

.arguments-edition > li form.edition label:last-of-type { margin-bottom: 1rem; }
.arguments-edition > li .actions { margin-bottom: 0; }

/* Le rendu sous le champ : ce qui s'affichera pendant l'appel, pas ce qui est
   tapé. Un aperçu en direct exigerait du JavaScript à étape de build. */
.arguments-edition .apercu {
  margin: 0 0 .75rem;
  padding: .75rem 1rem;
  border-left: 3px solid var(--accent);
  background: var(--fond);
  font-size: .95rem;
}

.arguments-edition .apercu > :first-child { margin-top: 0; }
.arguments-edition .apercu > :last-child { margin-bottom: 0; }

/* --- Historique des mois clos --------------------------------------------- */

/* C'est le `<li>` qui porte la carte, et le `dl.mesures` qui perd la sienne : les
   mesures sont déjà une carte au dashboard, où elles sont seules sur la page.
   Empilées ici, deux fonds blancs superposés feraient un cadre dans un cadre. */
.historique { margin: 0; padding: 0; list-style: none; }

.historique > li {
  margin: 1.5rem 0;
  padding: 1.5rem 1.75rem;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}

.historique > li .tete { justify-content: space-between; }

.historique dl.mesures {
  margin: .75rem 0 0;
  padding: 0;
  background: none;
  box-shadow: none;
}

.historique dl.mesures div { padding: .6rem 0; }

/* Aucun score ne précède le nom sur cet écran : le retrait qui aligne les détails
   des fiches sous leur pastille laisserait ici une phrase flottante. */
.historique .detail { margin-left: 0; }

/* --- Fiche prospect ------------------------------------------------------ */

.fiche .entete {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .9rem;
  margin-bottom: .5rem;
}

.fiche h1 { margin: 0; }

.fiche .coordonnees {
  margin: 1.5rem 0;
  padding: .5rem 1.75rem;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}

.fiche .coordonnees div {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem 1.5rem;
  padding: .8rem 0;
  border-bottom: 1px solid var(--bordure);
}

.fiche .coordonnees div:last-child { border-bottom: 0; }

.fiche .coordonnees dt {
  flex: none;
  width: 9rem;
  color: var(--texte-doux);
  font-size: .95rem;
}

/* `min-width: 0` : sans lui, une longue valeur (les horaires des sept jours)
   pousse la ligne et retombe sous son libellé. */
.fiche .coordonnees dd {
  flex: 1;
  min-width: 0;
  margin: 0;
  font-weight: 600;
  overflow-wrap: anywhere;
}

/* --- Journal des appels -------------------------------------------------- */

/* L'historique détaillé : quel bouton a été cliqué, quand, et ce qui a été noté.
   C'est ce qui rend un rappel utile trois semaines plus tard. */
ol.journal {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: .75rem;
}

ol.journal li {
  padding: 1.1rem 1.5rem;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
  border-left: 4px solid var(--gris-trait);
}

ol.journal li.vert   { border-left-color: var(--vert-trait); }
ol.journal li.ambre  { border-left-color: var(--ambre-trait); }
ol.journal li.rouge  { border-left-color: var(--rouge-trait); }
ol.journal li.bleu   { border-left-color: var(--accent-trait); }
ol.journal li.violet { border-left-color: var(--violet-trait); }

/* Un appel annulé pour erreur de saisie : il reste lisible, mais il ne dit plus
   rien du prospect. Pas de couleur — les couleurs portent un sens ici, et celle
   du résultat cliqué par erreur en porterait un faux. */
ol.journal li.annule {
  border-left-color: var(--bordure);
  background: var(--gris-pale);
  color: var(--texte-doux);
}

ol.journal li.annule .pastille,
ol.journal li.annule .dit { text-decoration: line-through; }

ol.journal .quand {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem;
  font-size: .9rem;
  color: var(--texte-doux);
}

ol.journal .dit {
  margin: .7rem 0 0;
  padding: .6rem .9rem;
  border-radius: 8px;
  background: var(--fond);
  font-style: italic;
}

ol.journal .meta {
  margin: .5rem 0 0;
  font-size: .85rem;
  color: var(--texte-doux);
}

/* --- Recherche de prospects ---------------------------------------------- */

/* Le compteur de requêtes : dit avant de cliquer ce que le clic coûte. */
.quota {
  margin: 1.5rem 0;
  padding: .9rem 1.25rem;
  border-radius: var(--rayon);
  border: 1px solid var(--bordure);
  background: var(--carte);
  font-size: .95rem;
}

/* --- Écriture du script -------------------------------------------------- */

.entete-script {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .9rem;
  margin-bottom: .5rem;
}

.entete-script h1 { margin: 0; }

/* Le champ du script : on y écrit du texte long, il occupe donc la carte.
   Pas d'aperçu en direct — ce serait une dépendance JS avec étape de build ;
   l'aperçu vit sur la page de la version, une fois enregistrée. */
form.edition {
  margin: 1.5rem 0;
  padding: 1.75rem;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}

form.edition label {
  display: block;
  margin-bottom: 1.5rem;
  font-weight: 600;
}

/* Tous les types de champ, pas une liste à rallonge : `email`, `number` et
   `url` manquaient, et un champ oublié ne se signale pas — il reste simplement
   à sa largeur de navigateur au milieu de champs pleine largeur. Vu le
   10/09/2026 sur « Adresse d'envoi » et « Port ». Les cases à cocher, les
   boutons radio et le sélecteur de fichier gardent leur taille propre. */
form.edition input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
form.edition select,
form.edition textarea {
  display: block;
  width: 100%;
  margin-top: .5rem;
  padding: .7rem .9rem;
  border: 1px solid var(--bordure);
  border-radius: 10px;
  font: inherit;
  font-weight: 400;
  color: var(--texte);
  background: var(--fond);
}

form.edition textarea {
  /* Monospace : le Markdown a des tableaux, dont les colonnes ne s'alignent à
     l'écriture qu'en largeur fixe. */
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .95rem;
  line-height: 1.7;
  resize: vertical;
}

form.edition input:focus, form.edition select:focus, form.edition textarea:focus {
  outline: 2px solid var(--vermillon);
  outline-offset: -1px;
}

/* Une précision sous un champ : le mode d'emploi vit à côté du réglage qu'il
   explique, pas dans un paragraphe qu'on lira après avoir cliqué. */
form.edition label .aide {
  display: block;
  margin-top: .5rem;
  font-size: .85rem;
  font-weight: 400;
}

form.edition label.case {
  display: flex;
  align-items: center;
  gap: .6rem;
  margin-bottom: 0;
}

form.edition label.case input { width: auto; margin: 0; }

/* Un groupe de cases dans un formulaire d'édition : le type d'établissement d'un
   restaurant. En colonnes qui se replient — onze cases empilées repousseraient le
   bouton d'envoi sous la ligne de flottaison. */
form.edition fieldset.cases {
  margin: 0 0 1.5rem;
  padding: 0;
  border: 0;
}

form.edition fieldset.cases legend {
  padding: 0;
  margin-bottom: .75rem;
  font-weight: 600;
}

form.edition fieldset.cases label.case {
  display: inline-flex;
  width: 15.5rem;
  margin: 0 1.25rem .6rem 0;
  font-weight: 400;
}

form.edition .actions { margin-bottom: 0; }

/* L'aperçu de la version : mêmes règles typographiques que le panneau d'appel. */
.script-lu {
  padding: 1.5rem 1.75rem;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
  font-size: .95rem;
}

.script-lu > :first-child { margin-top: 0; }

/* Le mémo Markdown et la liste des variables : à consulter, pas à lire. */
.aide-script {
  margin: 2.5rem 0 0;
  padding: 1.25rem 1.75rem;
  border-radius: var(--rayon);
  border: 1px dashed var(--bordure);
  font-size: .9rem;
  color: var(--texte-doux);
}

.aide-script h2 { margin: 1.5rem 0 .5rem; font-size: 1rem; color: var(--texte); }
.aide-script h2:first-child { margin-top: 0; }

.aide-script pre, details.source pre {
  margin: .75rem 0;
  padding: .8rem 1rem;
  overflow-x: auto;
  border-radius: 8px;
  background: var(--gris-pale);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .85rem;
  color: var(--texte);
}

ul.placeholders {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin: .5rem 0;
  padding: 0;
  list-style: none;
}

.aide-script .apercu {
  margin: .5rem 0 1rem;
  font-size: .95rem;
  font-style: italic;
  color: var(--texte);
}

details.source {
  margin: 2.5rem 0 0;
  font-size: .95rem;
}

details.source summary { cursor: pointer; color: var(--texte-doux); }

details.source pre { white-space: pre-wrap; }

/* --- La maquette de site, sur la fiche ------------------------------------ */

/* Le lien qu'on dicte au prospect pendant l'appel : il doit sauter aux yeux dans
   un bloc de rendez-vous, d'où le fond et le décrochement à gauche. Une ligne,
   pas un encadré de plus — c'est un lien, pas un écran. */
.maquette {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem;
  margin: .75rem 0 0;
  padding: .7rem .9rem;
  border-radius: 8px;
  border-left: 4px solid var(--bordure);
  background: var(--gris-pale);
  font-size: .95rem;
}

/* La couleur porte le sens, comme partout : vert un site prêt, ambre une écriture
   en cours, rouge ce qui n'a rien produit. Les mêmes que les pastilles portées à
   l'intérieur. */
.maquette.prete  { border-left-color: var(--vert);  background: var(--vert-pale); }
.maquette.attente { border-left-color: var(--ambre); background: var(--ambre-pale); }
.maquette.echec  { border-left-color: var(--rouge); background: var(--rouge-pale); }

/* L'adresse est faite pour être lue à voix haute et reconnue : en chasse fixe, et
   coupée n'importe où plutôt que de déborder de la carte sur un téléphone. */
.maquette a {
  flex: 1 1 14rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .9rem;
  overflow-wrap: anywhere;
}

/* « Télécharger » est un lien et non un bouton — il ouvre une adresse, il n'écrit
   rien. Sans cette reprise il hériterait de la règle ci-dessus, faite pour
   l'adresse : chasse fixe et largeur élastique. Et la marge haute de `discret`,
   posée pour un bouton seul en fin d'écran, le décalerait d'un cran ici. */
.maquette a.bouton {
  flex: 0 0 auto;
  margin-top: 0;
  font-family: inherit;
  text-decoration: none;
}

/* Ce qui bloque l'envoi d'un formulaire, dit au-dessus du champ fautif plutôt que
   dans un message qui aurait fait perdre ce qui vient d'être tapé. */
p.alerte {
  margin: 0 0 1.5rem;
  padding: .9rem 1.1rem;
  border-radius: var(--rayon);
  border: 1px solid var(--rouge-trait);
  background: var(--rouge-pale);
  color: var(--rouge);
  font-weight: 600;
}

/* --- Agenda --------------------------------------------------------------- */

/* L'heure avant le nom, en chiffres à largeur fixe : la colonne des heures se
   parcourt d'un coup d'œil sans lire les noms. */
.agenda .quand {
  flex: none;
  min-width: 4.2rem;
  font-variant-numeric: tabular-nums;
  font-weight: 650;
  color: var(--texte-doux);
}

/* Les cartes d'un même jour se touchent presque ; c'est le titre de journée qui
   sépare, pas un vide entre deux lignes. */
.agenda { gap: .6rem; }

/* Passer une fiche sans l'appeler. **Discret par construction** : ce n'est pas
   un résultat d'appel, et il ne doit jamais se cliquer à la place d'un vrai
   bouton. Aligné sur les résultats (même retrait de 3.7rem), sous eux, sans
   couleur de statut — la couleur porte du sens dans cette application, et un
   saut n'en porte aucun. */
.sauter {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem;
  margin: 1.25rem 0 0 3.7rem;
}

.sauter button.passer {
  color: var(--texte-doux);
  border-style: dashed;
  background: transparent;
  font-weight: normal;
}

.sauter button.passer:hover {
  color: var(--texte);
  border-style: solid;
}

/* Corriger la note d'un appel. Replié : on ouvre une fiche pour **lire** son
   historique, et un champ de saisie ouvert sur chaque ligne du journal en
   ferait un formulaire au lieu d'un récit. */
.corriger-note {
  margin: .4rem 0 0 1.2rem;
  font-size: .9rem;
}

.corriger-note summary {
  color: var(--texte-doux);
  cursor: pointer;
}

.corriger-note form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: .6rem;
  margin-top: .5rem;
}

.corriger-note textarea {
  flex: 1 1 20rem;
  min-width: 0;
}

/* Déplacer un rendez-vous. Replié comme la correction de note, et pour la même
   raison : l'agenda se lit bien plus souvent qu'il ne se modifie. */
.reporter summary {
  padding: .35rem .8rem;
  color: var(--texte-doux);
  cursor: pointer;
}

.reporter form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem;
  margin-top: .5rem;
  padding: .8rem;
  border-radius: var(--rayon);
  background: var(--fond);
}

/* La phrase à dire à qui n'a jamais décroché. Même forme que le rappel sur les
   objections, en haut de l'écran d'appel : c'est la même nature de message —
   quelque chose à avoir en tête à l'instant où on décroche, pas une note à
   retrouver ailleurs. */
.argument-injoignable {
  margin-left: 3.7rem;
  font-size: .95rem;
}

/* Les formulaires d'ajout du suivi client, repliés. On ouvre ces écrans pour
   suivre des clients existants bien plus souvent que pour en ajouter un. */
.edition-repliee {
  margin: 1.5rem 0;
  padding: 1rem 1.25rem;
  border-radius: var(--rayon);
  background: var(--carte);
}

.edition-repliee summary {
  font-weight: 600;
  cursor: pointer;
}

.edition-repliee > .edition,
.edition-repliee > p,
.edition-repliee > ul {
  margin-top: 1rem;
}

/* Ce qu'il faut réclamer : en tête, et détaché du reste de la page. C'est la
   seule chose de cet écran qui demande une action aujourd'hui. */
.a-relancer {
  margin-bottom: 2rem;
  padding: 1.25rem;
  border-radius: var(--rayon);
  background: var(--carte);
}

.a-relancer h2 { margin-top: 0; }

/* Le choix du nombre de versements, sous le montant de la vente. Sur une ligne :
   c'est une seule décision — combien, et quand — prise en une seule fois, avec
   le client au téléphone. */
.paiement-choix {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem;
  margin: .6rem 0;
  font-size: .95rem;
}

/* Les liens de paiement, là où la vente a été saisie. */
.liens-paiement {
  margin: .8rem 0;
  padding: .8rem 1rem;
  border-radius: var(--rayon);
  background: var(--fond);
  font-size: .95rem;
}

.ligne-paiement {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem;
  margin-bottom: .5rem;
}

/* Une adresse de paiement est longue : elle se coupe plutôt que de pousser la
   carte hors de l'écran sur un téléphone. */
.ligne-paiement a { word-break: break-all; }

.ligne-paiement.reglee { opacity: .65; }

/* Le détail d'une vente : plusieurs postes plutôt qu'un montant seul. */
.poste-titre { margin: 0 0 .4rem; }

.poste {
  display: flex;
  align-items: center;
  gap: .4rem;
  margin-bottom: .4rem;
}

.poste-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: .8rem;
  font-size: .9rem;
}

/* Le détail d'une vente, rappelé sur la fiche client. */
.detail-vente {
  margin: 0 0 1rem;
  padding-left: 1.2rem;
  color: var(--texte-doux);
}

/* Le nom du premier poste, fixe : ce n'est jamais qu'un rappel visuel, le champ
   éditable a été retiré — c'est toujours le site. Plus large que les autres
   libellés : les boutons hébergement l'allongent jusqu'à « Site web +
   hébergement et nom de domaine (2 ans) ». */
.poste-nom-fixe {
  display: inline-block;
  min-width: 24ch;
  max-width: 46ch;
}

/* Sous-navigation entre les deux pages de l'onglet Clients. Discrète : ce n'est
   pas un menu principal, juste un aiguillage entre deux vues de la même donnée. */
.sous-nav {
  display: flex;
  gap: .5rem;
  margin-bottom: 1.5rem;
}

.sous-nav a {
  padding: .4rem .9rem;
  border-radius: var(--rayon);
  color: var(--texte-doux);
  text-decoration: none;
  font-weight: 600;
}

.sous-nav a { background: var(--carte); box-shadow: var(--ombre); }
.sous-nav a:hover { background: var(--fond); }

.sous-nav a.ici {
  color: #fff;
  background: var(--vermillon);
}

/* Les deux cases d'un rendez-vous : ce qui le prépare (transfert, Meet, site) et
   ce qui encaisse. Demandé le 26/08/2026 — les deux se lisaient à la suite,
   sans repère visuel entre « où est le lien Meet » et « où est le prix ». */
.case-rdv {
  margin: 1.25rem 0;
  padding: 1.25rem;
  border-radius: var(--rayon);
  background: var(--fond);
  border: 1px solid var(--accent-doux, rgba(0, 0, 0, .08));
}

.case-titre {
  margin: 0 0 1rem;
  font-size: 1rem;
  color: var(--texte-doux);
}

/* La case paiement se distingue de la case rendez-vous par une teinte propre,
   pour qu'un coup d'œil suffise à savoir laquelle on regarde. */
.case-paiement {
  background: var(--carte);
  border-color: var(--vert-trait, rgba(0, 0, 0, .08));
}

/* Les deux groupes d'actions d'un rendez-vous dans l'agenda : déplacer/annuler
   d'un côté, statuer une fois passé de l'autre. Cinq boutons à plat se lisaient
   comme une seule liste ; un trait et un intitulé discret suffisent à séparer
   « avant » et « après » sans alourdir l'écran. */
.actions-secondaires {
  margin: .6rem 0 0;
  padding-top: .6rem;
  border-top: 1px solid var(--bordure);
  font-size: .9rem;
}

.actions-titre {
  flex-basis: 100%;
  color: var(--texte-doux);
  font-size: .8rem;
  text-transform: uppercase;
  letter-spacing: .03em;
}

/* Chaque issue porte la couleur de son statut, la même convention que les
   badges : on lit le groupe sans lire les mots. */
.issue-vente { color: var(--vert); border-color: var(--vert-trait); }
.issue-recontacter { color: var(--ambre); }
.issue-perdu { color: var(--rouge); border-color: var(--rouge-trait); }

/* --- Le choix du modèle qui écrit les maquettes (écran Comptes) ------------
   Une liste et non un menu déroulant : il n'y a que deux entrées, et chacune
   porte plus qu'un nom — son tarif, et si sa clé est posée. Un `<select>`
   cacherait précisément ce qu'on vient regarder avant de choisir. */
ul.modeles {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  gap: .75rem;
}

ul.modeles li {
  padding: 1rem 1.15rem;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  background: var(--fond);
}

/* Le modèle actif se voit sans lire : le trait vermillon est le même repère que
   l'onglet courant — c'est ce qui est sélectionné. */
ul.modeles li.ici {
  border-color: var(--vermillon);
  border-left: 4px solid var(--vermillon);
  background: var(--carte);
}

ul.modeles .tete {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-wrap: wrap;
}

ul.modeles .nom { font-weight: 600; }
ul.modeles .detail { font-size: .875rem; margin-top: .35rem; }
ul.modeles code { font-size: .9em; }
ul.modeles form { margin-top: .75rem; }

/* --- Notifications --------------------------------------------------------
   Qui peut recevoir : une ligne par personne, l'état à droite. C'est la
   première chose à lire sur cet écran, parce qu'une notification qui n'arrive
   jamais s'explique presque toujours par « personne n'a autorisé ». */
ul.telephones {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  gap: .5rem;
}

ul.telephones li {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  padding: .6rem .9rem;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  background: var(--fond);
}

ul.telephones .nom { font-weight: 600; }

/* Les champs qui n'apparaissent que pour un moment d'envoi donné : légèrement
   en retrait, pour qu'on voie qu'ils dépendent du choix juste au-dessus. */
.quand-precis {
  display: flex;
  align-items: flex-end;
  gap: .75rem;
  flex-wrap: wrap;
  padding-left: .9rem;
  border-left: 3px solid var(--vermillon);
}

/* Le bouton d'autorisation, sur son propre compte. Il porte son état en toutes
   lettres : « autorisé » ou non se lit, il ne se devine pas à une nuance. */
.autoriser-notifications { margin-top: .75rem; }
.autoriser-notifications .etat { display: block; margin-top: .5rem; }

/* --- Le SMS du rendez-vous ------------------------------------------------
   On arrive sur cet écran depuis une notification, sur un téléphone, souvent
   entre deux appels. Le bouton est donc surdimensionné : c'est la seule action
   de la page, elle ne doit pas se chercher. */
.bouton-sms {
  display: block;
  margin: 1.5rem 0;
  padding: 1.4rem 1.5rem;
  text-align: center;
  text-decoration: none;
  font-size: 1.15rem;
  font-weight: 700;
  color: #fff;
  background: var(--vermillon);
  border: 2px solid var(--noir);
  border-radius: var(--rayon);
  box-shadow: 0 3px 14px rgba(255, 74, 28, .35);
}

.bouton-sms:active { transform: translateY(1px); }

/* Le message tel qu'il partira, lisible d'un coup d'œil : on le relit avant
   d'envoyer, c'est tout l'intérêt de ne pas l'envoyer tout seul. */
.message-sms {
  white-space: pre-wrap;
  padding: 1rem 1.15rem;
  border-left: 3px solid var(--vermillon);
  border-radius: var(--rayon);
  background: var(--carte);
  font-size: .9375rem;
  line-height: 1.6;
}

.avertissement-manque {
  padding: 1rem 1.15rem;
  margin: 1.25rem 0;
  border: 1px solid var(--ambre-trait);
  border-left: 4px solid var(--ambre);
  border-radius: var(--rayon);
  background: var(--ambre-pale);
}

.avertissement-manque p { margin: 0; }
.avertissement-manque p + p { margin-top: .5rem; }

.retour-discret {
  display: inline-block;
  margin-top: 2rem;
  font-size: .9375rem;
}

/* La liste des droits à cocher pour une clé Stripe restreinte. Affichée sur
   /etat seulement quand la clé en est une : ailleurs, ce serait du bruit. */
ul.permissions {
  margin: .5rem 0;
  padding-left: 1.25rem;
  font-size: .9375rem;
}

ul.permissions li { margin-bottom: .2rem; }

/* --- Les relances d'un rendez-vous manqué (fiche prospect) -----------------
   Repliées : on ne relance pas à chaque ouverture de fiche, et dépliées d'office
   elles repousseraient les boutons d'appel hors de l'écran. */
details.relances {
  margin: 1.5rem 0 0;
  padding: 1rem 1.15rem;
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  background: var(--fond);
}

details.relances summary {
  cursor: pointer;
  font-weight: 600;
  user-select: none;
}

details.relances .aide { margin: .75rem 0; }
details.relances .actions { margin: 0; }

/* Le choix du nombre de versements : les trois options sur une ligne, la date
   en dessous. À trois choix elle ne tenait plus à côté sans serrer les
   libellés — et « en trois fois » coupé en deux ne se lit pas. */
.paiement-choix .quand-versements {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-basis: 100%;
  margin-top: .5rem;
  font-size: .9375rem;
}

/* Les relances sur l'écran « En attente » : dépliées, mais visuellement en
   retrait des issues qui les suivent — on relance d'abord, on statue ensuite,
   et les deux rangées ne doivent pas se lire comme une seule liste. */
.actions-relance {
  border-left: 3px solid var(--vermillon);
  padding-left: .9rem;
}

/* ---------------------------------------------------------------------------
   La page Formation.

   Une vidéo par ligne, en pleine largeur. Une grille de vignettes ferait
   choisir avant de savoir ce qu'il y a dedans, alors que l'ordre de cette liste
   *est* l'ordre dans lequel on se forme.
   --------------------------------------------------------------------------- */
.formation {
  list-style: none;
  margin: 1.25rem 0 2rem;
  padding: 0;
}

.formation > li {
  background: var(--carte);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  box-shadow: var(--ombre);
  padding: 1.1rem 1.25rem 1rem;
}

.formation > li + li {
  margin-top: 1.25rem;
}

.formation h2 {
  margin: 0 0 .75rem;
  font-size: 1.0625rem;
}

/* Le cadre garde le rapport 16/9 quelle que soit la largeur : une hauteur en
   pixels donnerait des bandes noires sur téléphone et une vidéo écrasée sur
   grand écran. Plafonné, parce qu'une vidéo de 1 200 px de large sur un écran
   de bureau se regarde de trop loin — et la lecture en plein écran est à un
   clic dans le lecteur. */
.cadre-video {
  position: relative;
  aspect-ratio: 16 / 9;
  max-width: 46rem;
  background: var(--noir);
  border-radius: var(--rayon);
  overflow: hidden;
}

.cadre-video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.formation .detail {
  margin-top: .6rem;
}

.formation form {
  margin-top: .5rem;
}

/* Le formulaire d'ajout : le lien d'abord — c'est ce qu'on vient coller — le
   titre ensuite, et le bouton en bout de ligne quand la place le permet. */
.ajout-video {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: .9rem;
  margin: .75rem 0;
}

.ajout-video label {
  display: flex;
  flex-direction: column;
  gap: .3rem;
  font-size: .9375rem;
}

/* ---------------------------------------------------------------------------
   Le module Messages : la seconde interface.

   **Volontairement très peu de choses.** Les deux outils partagent la marque,
   la mise en page, les cartes et le code couleur des états — repeindre le
   second ferait croire à un autre logiciel, et surtout obligerait à tenir deux
   feuilles de style d'accord. Ce qui les distingue tient en deux traits.
   --------------------------------------------------------------------------- */

/* Le filet sous la barre du haut passe en **cyan**, la troisième couleur du
   logotype. C'est le repère qu'on lit sans lire : violet = Prospecto,
   cyan = Messages, ambre = E-mail — les mêmes couleurs que la barre du logo,
   qui change elle aussi. Aucune n'entre en concurrence avec un code d'état
   (vert / ambre / rouge) sur une donnée : ce filet n'est pas cliquable, ne dit
   rien d'un prospect, et la règle tient.

   Réécrit le 10/09/2026 avec la refonte : la règle visait `header`, le bandeau
   horizontal qui n'existe plus. Elle serait tombée sur la barre du haut par
   accident — un sélecteur qui vise le bon élément par hasard finit par viser
   le mauvais. */
body.module-messages .topbar {
  border-bottom-color: var(--cyan);
}

/* Le graphique jour après jour du module Messages : la grammaire de
   `.repartition` (libellé, barre, nombre) plus une quatrième colonne pour les
   réponses. Sans elle, le compte des réponses passait à la ligne sous la barre
   et se lisait comme un total du tableau entier.

   La colonne de gauche est resserrée : elle porte « 07/09 » et non un libellé
   de résultat, et onze rem laisseraient un trou au milieu de la carte. */
ul.repartition.jours li {
  grid-template-columns:4.5rem minmax(0,1fr) 2.5rem 6.5rem;
}

ul.repartition.jours .passage {
  font-size: .85rem;
  text-align: right;
}

/* Un formulaire d'édition **posé dans une carte** ne dessine pas sa propre
   carte : fond blanc sur fond blanc, avec deux ombres et deux bordures, on lit
   une boîte dans une boîte sans que rien ne le justifie. Même correction que
   pour les cartes d'arguments (`.arguments-edition > li form.edition`), qui
   avaient rencontré le cas les premières. */
.carte > form.edition {
  margin: 1.25rem 0 0;
  padding: 0;
  background: none;
  box-shadow: none;
}

/* Les ventilations du module Messages (métier, nombre d'avis).

   La grammaire de `.repartition` avec une quatrième colonne, comme le
   graphique jour après jour — mais des colonnes taillées pour ce qu'elles
   portent : « Coiffure et beauté » et non « 07/09 » à gauche, « 24 % » et non
   « 8 » au milieu. Sur la grille des dates, les deux se coupaient en deux
   lignes. Trouvé sur une capture, jamais par un test. */
ul.repartition.ventilation li {
  grid-template-columns:11rem minmax(0,1fr) 3.5rem 6rem;
}

ul.repartition.ventilation .nombre {
  white-space: nowrap;
}

ul.repartition.ventilation .passage {
  font-size: .85rem;
  text-align: right;
}


/* --- L'agenda du module Messages ------------------------------------------ */

/* La légende des couleurs, en haut de l'écran : trois pastilles de la même
   forme que celles du calendrier, sinon il faudrait deviner ce que la couleur
   veut dire. */
.legende { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.legende .case { position: static; display: inline-flex; padding: .15rem .5rem; }

/* Le jour et l'heure côte à côte : deux champs courts qu'on remplit d'affilée,
   empilés ils feraient descendre le bouton sous la ligne de flottaison. */
.creneau { display: flex; flex-wrap: wrap; gap: 1rem; }
.creneau label { flex: 1 1 10rem; }

.fiche-choisie { margin: .5rem 0 1rem; }
.fiche-choisie a { margin-left: .5rem; font-size: .9em; }

/* La recherche de fiche : le champ prend la place, le bouton ce qu'il faut. */
form.chercher { display: flex; gap: .5rem; align-items: center; }
form.chercher input { flex: 1 1 auto; }


/* --- Le module E-mail ------------------------------------------------------
   Troisième interface (10/09/2026). Le filet passe en **ambre**, là où
   Prospecto porte le violet et Messages le cyan — la même couleur que la
   troisième barre de son logotype, pour que les deux repères disent la même
   chose. Voir la note du module Messages ci-dessus pour le reste. */
body.module-email .topbar {
  border-bottom-color: #f0a04b;
}

/* Le module Ads (04/10/2026), quatrième volet. Le filet passe en **indigo** :
   ni vert, ni ambre, ni rouge (les couleurs d'état, qui ne décorent jamais), et
   assez loin du cyan de Messages comme de l'ambre d'E-mail pour qu'on sache
   dans quel outil on est sans lire les mots. */
body.module-ads .topbar {
  border-bottom-color: #6366f1;
}


/* ==========================================================================
   LES COMPOSANTS — repris du fichier de maquette, à l'identique
   ==========================================================================
   Placé **après** l'ancien vocabulaire, et c'est ce qui rend la conversion
   sûre : à spécificité égale, c'est la maquette qui gagne. Un écran déjà
   converti prend donc sa mise en page sans que celui d'à côté bouge.

   Deux écarts seulement avec le fichier d'origine, tous les deux notés dans le
   script d'import : les variables portent nos noms (une seule palette, pas
   deux jeux à tenir d'accord), et les règles de tableau sont portées par
   `.table-wrap` — chez nous des tableaux plus anciens vivent hors de la
   maquette, et son `white-space: nowrap` global les couperait.
   ========================================================================== */


* {
  box-sizing:border-box
}
body {
  margin:0
}
button,
input,
select,
textarea {
  font:inherit
}
button,
a,
input,
select,
textarea {
  -webkit-tap-highlight-color:transparent
}
button,
a {
  touch-action:manipulation
}
button {
  cursor:pointer
}
button {
  color:inherit
}
a {
  color:var(--accent);
  text-decoration:none
}
button:disabled {
  opacity:.45;
  cursor:not-allowed
}
button:focus-visible,
a:focus-visible,
[tabindex]:focus-visible {
  outline:3px solid #9c8cfa;
  outline-offset:3px
}
input:focus,
select:focus,
textarea:focus {
  outline:0;
  border-color:var(--accent)!important;
  box-shadow:0 0 0 3px #5b3df016
}
input,
select,
textarea {
  min-width:0
}
button {
  transition:background .18s,box-shadow .18s,transform .18s
}
button:active:not(:disabled) {
  transform:translateY(1px)
}
h1,
h2,
h3,
p {
  margin:0
}
h1 {
  font-size:30px;
  letter-spacing:-1.3px;
  line-height:1.3
}
h2 {
  font-size:17px;
  letter-spacing:-.45px
}
h3 {
  font-size:15px;
  letter-spacing:-.2px
}
.muted {
  color:var(--texte-doux)
}
.small {
  font-size:12px
}
.medium {
  font-size:14px
}
.strong {
  font-weight:700
}
.row {
  display:flex;
  align-items:center;
  gap:10px
}
.between {
  justify-content:space-between
}
.stack {
  display:flex;
  flex-direction:column;
  gap:6px
}
.grow {
  flex:1;
  min-width:0
}
.nowrap {
  white-space:nowrap
}
.btn {
  border:1px solid var(--bordure);
  border-radius:9px;
  background:white;
  min-height:40px;
  padding:10px 14px;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:8px;
  font-weight:650;
  font-size:13px;
  white-space:nowrap
}
.btn:hover {
  background:#f8f7ff;
  border-color:#d3ccf7
}
.btn.primary {
  color:white;
  background:var(--accent);
  border-color:var(--accent);
  box-shadow:0 4px 10px #5b3df024
}
.btn.primary:hover {
  background:var(--accent-fort)
}
.btn.light {
  background:white;
  color:var(--accent);
  border-color:white
}
.btn.ghost {
  background:transparent;
  border-color:transparent;
  box-shadow:none
}
.btn.ghost:hover {
  background:var(--accent-pale)
}
.btn.small {
  min-height:32px;
  padding:7px 10px;
  font-size:12px
}
.icon-btn {
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:36px;
  height:36px;
  border:1px solid var(--bordure);
  border-radius:9px;
  background:white;
  flex:none
}
.icon-btn:hover {
  background:var(--accent-pale);
  color:var(--accent)
}
.tag {
  display:inline-flex;
  align-items:center;
  gap:6px;
  padding:5px 9px;
  border-radius:6px;
  font-size:12px;
  font-weight:650;
  white-space:nowrap;
  background:#f0f2f7;
  color:#62697e
}
.tag:before {
  content:'';
  width:5px;
  height:5px;
  border-radius:50%;
  background:currentColor
}
.tag.purple {
  background:#eeebff;
  color:#6140db
}
.tag.cyan {
  background:#e8f6fb;
  color:#22799b
}
.tag.green {
  background:#e8f6f0;
  color:#197b62
}
.tag.amber {
  background:#fff5e4;
  color:#a76913
}
.tag.red {
  background:#fff0f0;
  color:#b75c65
}
.avatar {
  width:34px;
  height:34px;
  border-radius:10px;
  display:grid;
  place-items:center;
  flex:none;
  font-size:12px;
  font-weight:800;
  background:#eeebff;
  color:var(--accent)
}
.avatar.cyan {
  background:#e8f5fa;
  color:#277f9e
}
.avatar.amber {
  background:#fff4e5;
  color:#ab7b35
}
.avatar.slate {
  background:#eef0f7;
  color:#626c8a
}
.avatar.green {
  background:#e7f4ef;
  color:#36836f
}
.pill {
  border-radius:99px
}
.skip {
  position:fixed;
  left:15px;
  top:-80px;
  background:white;
  padding:15px;
  z-index:100
}
.skip:focus {
  top:12px
}
/* Structure */
.sidebar {
  position:fixed;
  inset:0 auto 0 0;
  width:224px;
  z-index:30;
  background:var(--navy);
  color:#b0b5ca;
  padding:30px 16px 16px;
  display:flex;
  flex-direction:column;
  transition:width .22s,transform .22s
}
.page-heading {
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:18px;
  margin-bottom:25px
}
.page-heading p {
  color:var(--texte-doux);
  font-size:13px;
  margin-top:7px
}
.eyebrow {
  font-size:10px;
  text-transform:uppercase;
  letter-spacing:1.65px;
  font-weight:700
}
.page-heading .eyebrow {
  color:var(--accent);
  margin-bottom:7px
}
.intro-dot {
  display:inline-block;
  width:6px;
  height:6px;
  background:var(--cyan);
  border-radius:50%;
  margin-right:6px
}
.card {
  background:white;
  border:1px solid var(--bordure);
  border-radius:var(--rayon);
  box-shadow:0 3px 8px #22263a02
}
.card-head {
  padding:21px 22px 16px;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:14px
}
.appear {
  animation:appear .32s ease-out
}
@keyframes appear {
  from {
    opacity:0;
    transform:translateY(5px)
  }
to {
    opacity:1;
    transform:translateY(0)
  }
}
/* Daily cockpit */
.overview {
  display:grid;
  grid-template-columns:minmax(365px,1.9fr) repeat(2,minmax(155px,1fr));
  gap:17px;
  margin-bottom:25px
}
.mission {
  border-radius:15px;
  position:relative;
  overflow:hidden;
  background:linear-gradient(112deg,#5b3df0 5%,#6451e7 67%,#547cdb);
  color:#fff;
  padding:23px 25px;
  display:flex;
  align-items:center;
  gap:22px;
  min-height:165px
}
.mission::after {
  content:'';
  position:absolute;
  inset:0;
  pointer-events:none;
  background:radial-gradient(ellipse at 100% 0,#4fb3d966,transparent 65%)
}
.mission>* {
  position:relative;
  z-index:1
}
.mission .eyebrow {
  color:#ded7ff;
  font-size:10px;
  letter-spacing:1.3px
}
.mission-stat {
  font-size:31px;
  font-weight:750;
  letter-spacing:-1.5px;
  margin:5px 0 10px
}
.mission-stat small {
  font-size:13px;
  font-weight:500;
  letter-spacing:0;
  color:#e0daff
}
.progress {
  height:5px;
  border-radius:5px;
  background:#ffffff30;
  overflow:hidden;
  width:100%;
  max-width:200px
}
.progress>span {
  height:100%;
  display:block;
  background:#a1e4f3;
  border-radius:5px;
  transition:width .5s
}
.mission-actions {
  text-align:right;
  flex:none
}
.mission-actions p {
  font-size:10px;
  color:#e2ddff;
  margin-top:10px
}
.mission .goal-edit {
  color:#e4dcff;
  background:transparent;
  border:0;
  text-decoration:underline;
  text-underline-offset:3px;
  font-size:10px;
  padding:0;
  margin-top:9px
}
.stat {
  padding:22px;
  display:flex;
  flex-direction:column;
  justify-content:space-between
}
.stat .stat-icon {
  display:grid;
  place-items:center;
  height:32px;
  width:32px;
  background:var(--accent-pale);
  border-radius:9px;
  color:var(--accent)
}
.stat:nth-child(3) .stat-icon {
  background:#eaf7fb;
  color:#3796b7
}
.stat-label {
  font-size:12px;
  color:var(--texte-doux)
}
.stat-number {
  font-size:32px;
  font-weight:750;
  letter-spacing:-1px;
  line-height:1.3;
  margin-top:8px
}
.stat-foot {
  font-size:11px;
  color:var(--texte-doux);
  margin-top:5px
}
.stat-foot strong {
  color:var(--vert);
  font-weight:600
}
.workspace-grid {
  display:grid;
  grid-template-columns:minmax(0,1fr) 285px;
  gap:22px;
  align-items:start
}
.work-title {
  display:flex;
  align-items:center;
  gap:10px
}
.count-badge {
  font-size:11px;
  font-weight:650;
  padding:3px 7px;
  border:1px solid var(--bordure);
  border-radius:6px;
  color:#7a8093;
  background:#fafbfe
}
.segmented {
  display:flex;
  background:#f5f6fa;
  padding:3px;
  border-radius:7px;
  gap:2px
}
.segmented button,
.segmented a {
  background:transparent;
  border:0;
  border-radius:5px;
  padding:6px 9px;
  color:#8a90a2;
  display:flex;
  align-items:center;
  gap:6px;
  font-size:11px
}
.segmented button.active,
.segmented a.active {
  background:white;
  color:var(--accent);
  box-shadow:0 1px 5px #29254012
}
.toolbar {
  display:flex;
  gap:9px;
  padding:0 21px 16px;
  /* **Elle passe à la ligne plutôt que d'écraser ses enfants** (29/09/2026).
     Mesuré à 900 px : le panneau de filtres était comprimé à 110 px, ses
     pastilles de secteur débordaient de l'écran de cent pixels, et aucun
     défilement ne permettait de les atteindre. Un filtre qu'on ne peut pas
     cliquer est un filtre qui n'existe pas. */
  flex-wrap: wrap}
.search-field {
  display:flex;
  align-items:center;
  gap:8px;
  border:1px solid var(--bordure);
  border-radius:8px;
  background:white;
  padding:0 11px;
  min-width:140px;
  flex:1;
  color:#8b90a0
}
.search-field input {
  width:100%;
  border:0;
  background:none;
  outline:0!important;
  box-shadow:none!important;
  height:38px;
  font-size:12px;
  color:var(--texte)
}
.toolbar .btn {
  min-height:38px;
  padding:8px 11px;
  font-size:12px
}
.tabs {
  display:flex;
  gap:21px;
  padding:0 22px;
  border-bottom:1px solid var(--bordure);
  overflow:auto
}
.tabs button,
.tabs a {
  border:0;
  background:transparent;
  padding:0 0 14px;
  font-size:12px;
  color:#80869a;
  font-weight:600;
  white-space:nowrap;
  position:relative
}
.tabs button.active,
.tabs a.active {
  color:var(--accent)
}
.tabs button.active:after,
.tabs a.active:after {
  content:'';
  height:2px;
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  background:var(--accent);
  border-radius:2px
}
.tabs .tab-count {
  font-size:10px;
  background:#f2f3f7;
  border-radius:4px;
  padding:2px 5px;
  margin-left:5px;
  color:#82889c
}
.tabs .active .tab-count {
  color:var(--accent);
  background:var(--accent-pale)
}
.filter-panel {
  padding:17px 21px;
  display:grid;
  grid-template-columns:repeat(3,minmax(0,1fr));
  gap:12px;
  background:#fafaff;
  border-bottom:1px solid var(--bordure)
}
.field {
  display:flex;
  flex-direction:column;
  gap:7px;
  min-width:0
}
.field label {
  font-size:12px;
  color:#61677c;
  font-weight:600
}
.field input,
.field select,
.field textarea {
  border:1px solid #dfe2ed;
  border-radius:8px;
  padding:10px 11px;
  width:100%;
  color:var(--texte);
  background:white;
  font-size:13px
}
.field textarea {
  resize:vertical;
  min-height:106px;
  line-height:1.7
}
.filter-panel .field select {
  padding:8px;
  font-size:12px
}
.filter-reset {
  grid-column:1/-1;
  text-align:right
}
.filter-reset button:not(.btn) {
  font-size:11px;
  color:var(--accent);
  border:0;
  background:transparent
}
.table-wrap {
  overflow:auto
}
.table-wrap table {
  border-collapse:collapse;
  width:100%;
  text-align:left;
  white-space:nowrap
}
.table-wrap th {
  font-size:10px;
  font-weight:600;
  color:#969bab;
  padding:13px 15px;
  background:#fcfcfe;
  border-bottom:1px solid var(--bordure)
}
.table-wrap th:first-child,
.table-wrap td:first-child {
  padding-left:22px
}
.table-wrap th:last-child,
.table-wrap td:last-child {
  padding-right:20px
}
.table-wrap td {
  padding:16px 15px;
  border-bottom:1px solid #eef0f6;
  font-size:12px
}
.table-wrap tr:last-child td {
  border-bottom:0
}
.table-wrap tbody tr {
  transition:background .15s
}
.table-wrap tbody tr:hover {
  background:#fbfaff
}
.company {
  display:flex;
  align-items:center;
  gap:11px;
  min-width:175px
}
.company button {
  background:none;
  border:0;
  padding:0;
  text-align:left
}
.company-name {
  font-size:12px;
  font-weight:750;
  line-height:1.6
}
.company-sub {
  font-size:10px;
  color:#8990a2;
  margin-top:2px
}
.place {
  font-size:12px;
  color:#626b81
}
.place small {
  display:block;
  font-size:10px;
  color:#969cad;
  margin-top:5px
}
.row-action {
  background:#f4f2ff;
  border:1px solid #ede9ff;
  color:var(--accent);
  border-radius:8px;
  display:grid;
  place-items:center;
  width:31px;
  height:31px
}
.row-action:hover {
  background:var(--accent);
  color:white
}
.table-footer {
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:8px;
  padding:16px 21px;
  border-top:1px solid var(--bordure);
  font-size:10px;
  color:#8b91a2
}
.table-footer .icon-btn {
  height:26px;
  width:26px;
  border-radius:6px
}
.table-footer .pagination {
  display:flex;
  align-items:center;
  gap:8px
}
.table-footer .page {
  background:var(--accent-pale);
  color:var(--accent);
  width:25px;
  height:25px;
  display:grid;
  place-items:center;
  border-radius:6px;
  font-weight:650
}
.open-tag {
  display:flex;
  align-items:center;
  gap:5px;
  font-size:10px;
  color:#388774
}
.open-tag:before {
  content:'';
  width:5px;
  height:5px;
  border-radius:50%;
  background:#56b898
}
.open-tag.closed {
  color:#8a90a1
}
.open-tag.closed:before {
  background:#a1a7b4
}
.empty {
  padding:45px 24px;
  text-align:center;
  color:var(--texte-doux);
  font-size:13px;
  line-height:1.8
}
.empty .icon {
  color:#b7aedf;
  width:30px;
  height:30px;
  margin-bottom:10px
}
.rail {
  display:flex;
  flex-direction:column;
  gap:19px
}
.rail .card-head {
  padding:19px 19px 15px
}
.rail .card-head h2 {
  font-size:14px
}
.rail .card-head .small {
  font-size:10px
}
.schedule {
  padding:0 19px 18px
}
.appointment {
  display:flex;
  gap:12px;
  padding:15px 0;
  border-bottom:1px solid #f0f1f6
}
.appointment:last-child {
  border:0;
  padding-bottom:3px
}
.appointment-time {
  font-size:11px;
  font-weight:700;
  width:36px;
  color:#777e92;
  padding-top:1px;
  flex:none
}
.appointment-info {
  border-left:2px solid #d7ccff;
  padding-left:12px;
  flex:1;
  min-width:0
}
.appointment-info button {
  border:0;
  background:none;
  padding:0;
  text-align:left;
  font-size:12px;
  font-weight:700;
  line-height:1.5
}
.appointment-info p {
  font-size:10px;
  color:#8b91a5;
  margin-top:4px
}
.appointment:first-child .appointment-time {
  color:var(--accent)
}
.appointment:first-child .appointment-info {
  border-color:var(--accent)
}
.appointment:nth-child(2) .appointment-info {
  border-color:var(--cyan)
}
.appointment-info .tag {
  font-size:9px;
  padding:3px 6px;
  margin-top:8px
}
.rail-link {
  display:flex;
  align-items:center;
  justify-content:center;
  gap:8px;
  color:var(--accent);
  font-size:11px;
  font-weight:600;
  width:100%;
  background:#fbfaff;
  border:0;
  border-top:1px solid var(--bordure);
  padding:13px;
  border-radius:0 0 var(--rayon) var(--rayon)
}
.tip-card {
  background:linear-gradient(135deg,#f0edff,#f0f7fc);
  border:1px solid #e4e3f8;
  border-radius:var(--rayon);
  padding:19px
}
.tip-card .icon {
  color:var(--accent)
}
.tip-card h3 {
  font-size:13px;
  margin:11px 0 7px
}
.tip-card p {
  font-size:11px;
  color:#77758e;
  line-height:1.8
}
.tip-card .btn {
  padding:9px 0;
  margin-top:9px;
  min-height:0;
  font-size:11px;
  color:var(--accent)
}
.bottom-note {
  font-size:10px;
  color:#9298aa;
  display:flex;
  align-items:center;
  gap:6px;
  margin-top:21px
}
.bottom-note .icon {
  width:13px;
  height:13px
}
.prospect-cards {
  display:grid;
  grid-template-columns:repeat(2,minmax(0,1fr));
  padding:18px;
  gap:13px
}
.prospect-tile {
  border:1px solid var(--bordure);
  border-radius:10px;
  padding:16px;
  display:flex;
  flex-direction:column;
  gap:13px;
  text-align:left;
  background:white
}
.prospect-tile:hover {
  border-color:#bab0f9;
  background:#fcfbff
}
.prospect-tile .company {
  min-width:0
}
.prospect-tile .company-name {
  white-space:normal
}
/* Additional views */
.metrics {
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:18px;
  margin-bottom:23px
}
.metrics .stat {
  min-height:160px
}
.dashboard-grid {
  display:grid;
  grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);
  gap:22px
}
.chart {
  padding:24px;
  display:flex;
  align-items:flex-end;
  gap:18px;
  /* **Il défile plutôt que de pousser la page** (29/09/2026) : mesuré à 900 px,
     les colonnes débordaient et c'était **toute la page** qui partait de
     travers — le contenu glissait sous la barre latérale fixe, et on ne lisait
     plus les titres. Un graphique serré qu'on fait défiler vaut mieux qu'un
     écran qui se décale. */
  overflow-x:auto;
  height:270px;
  border-bottom:1px solid var(--bordure);
  background:repeating-linear-gradient(to top,transparent 0,transparent 48px,#f0f1f7 49px,#f0f1f7 50px);
  margin:0 24px
}
.chart-col {
  height:100%;
  flex:1;
  display:flex;
  flex-direction:column;
  justify-content:flex-end;
  align-items:center;
  gap:10px;
  font-size:12px;
  color:var(--texte-doux)
}
.chart-col b {
  color:var(--texte);
  font-size:11px
}
/* L'étiquette tient sur une ligne. Sans ça, « mar. 01 » se coupe en deux quand
   les colonnes sont nombreuses alors que « lun. 07 » tient : un pied de
   graphique où une date sur deux est sur deux lignes ne se lit plus comme une
   suite de jours. Au-delà de quinze jours, seuls les lundis sont étiquetés — la
   place est donc toujours là (voir `graphique.points`). */
.chart-col > span {
  white-space:nowrap;
  font-size:11px;
  letter-spacing:-.1px
}
.bar {
  width:72%;
  max-width:57px;
  border-radius:7px 7px 2px 2px;
  background:#e4dffc;
  min-height:3px
}
.chart-col.today .bar {
  background:linear-gradient(var(--cyan),var(--accent));
  box-shadow:0 6px 12px #5b3df01a
}
.chart-col.today {
  color:var(--accent);
  font-weight:700
}
/* Une colonne cliquable doit *se voir* cliquable : sans ce retour visuel, on ne
   découvre la descente qu'en cliquant au hasard. Le `<a>` reprend la mise en
   page de `.chart-col`, il n'y a que l'état survolé à ajouter. */
a.chart-col {
  text-decoration:none;
  cursor:pointer;
  border-radius:8px;
  transition:background .12s
}
a.chart-col:hover,
a.chart-col:focus-visible {
  background:#f4f2fe;
  outline:none
}
a.chart-col:hover .bar {
  filter:brightness(.94)
}
a.chart-col:focus-visible {
  box-shadow:0 0 0 2px var(--accent)
}
/* La mesure d'appoint, posée au pied de la colonne : côté Messages, les réponses
   reçues se lisent dans la barre des envois plutôt que dans une barre jumelle
   qui diviserait la largeur par deux. */
.bar {
  position:relative;
  overflow:hidden
}
.bar-second {
  position:absolute;
  left:0;
  right:0;
  bottom:0;
  /* **Le navy et non le dégradé de marque.** La colonne du jour est déjà peinte
     en cyan→violet : une part d'appoint dans la même gamme s'y fondait, et les
     réponses du jour devenaient illisibles précisément sur la colonne qu'on
     regarde en premier. Le navy tranche sur les deux fonds. Ni vert ni ambre ni
     rouge : ce sont les couleurs d'état de la charte, elles ne décorent pas. */
  background:var(--navy);
  border-radius:0 0 2px 2px;
  opacity:.88;
  /* Une arête claire en haut du segment. Selon le module, la part d'appoint va
     de quelques pour cent (les réponses à un SMS) à plus des trois quarts (les
     sites à refaire) : sans cette ligne, une part écrasante mange toute la
     colonne et on ne voit plus où elle commence — ni, sur la colonne du jour,
     le dégradé qui la signale. */
  box-shadow:inset 0 1px 0 rgba(255,255,255,.6)
}
/* Le chemin de retour d'une descente dans le graphique. */
.fil-retour {
  display:inline-flex;
  align-items:center;
  gap:6px;
  margin-bottom:14px;
  font-size:13px;
  font-weight:600;
  color:var(--accent);
  text-decoration:none
}
.fil-retour:hover { text-decoration:underline }
.chart-foot {
  padding:18px 24px;
  font-size:12px;
  color:var(--texte-doux)
}
.activity-list {
  padding:0 24px 22px
}
.activity-item {
  display:flex;
  gap:12px;
  padding:16px 0;
  border-bottom:1px solid var(--bordure)
}
.activity-item:last-child {
  border:0
}
.activity-item .avatar {
  width:30px;
  height:30px
}
.activity-item p {
  font-size:12px;
  line-height:1.7
}
.activity-item small {
  font-size:10px;
  color:var(--texte-doux)
}
.agenda-toolbar {
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:15px;
  margin-bottom:20px
}
.week-grid {
  display:grid;
  grid-template-columns:repeat(7,minmax(130px,1fr));
  overflow:auto;
  gap:0
}
.day-column {
  min-height:450px;
  border-right:1px solid var(--bordure);
  padding:17px
}
.day-column:last-child {
  border:0
}
.day-header {
  display:flex;
  align-items:center;
  gap:10px;
  border-bottom:1px solid var(--bordure);
  padding-bottom:18px;
  margin-bottom:20px;
  color:var(--texte-doux);
  font-size:12px
}
.day-header strong {
  font-size:22px;
  color:var(--texte)
}
.day-column.today {
  background:#fdfcff
}
.day-column.today .day-header strong {
  color:var(--accent)
}
.event-card {
  padding:13px 12px;
  border:1px solid #e4ddfd;
  border-left:3px solid var(--accent);
  background:#f3f0ff;
  border-radius:8px;
  display:block;
  width:100%;
  text-align:left;
  margin-bottom:12px;
  line-height:1.6
}
.event-card strong {
  display:block;
  font-size:12px
}
.event-card span {
  font-size:10px;
  color:#77748c;
  display:block
}
.event-card b {
  font-size:11px;
  color:var(--accent);
  display:block;
  margin-bottom:8px
}
.event-card.cyan {
  background:#edf8fc;
  border-color:#d8edf5;
  border-left-color:var(--cyan)
}
.event-card.cyan b {
  color:#318fae
}
.day-empty {
  font-size:11px;
  color:#a0a5b3;
  padding:20px 0;
  text-align:center
}
.scripts-grid {
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.5fr);
  gap:22px
}
.script-step {
  padding:20px 23px;
  border-bottom:1px solid var(--bordure)
}
.script-step span {
  font-size:10px;
  font-weight:700;
  color:var(--accent);
  text-transform:uppercase;
  letter-spacing:1px
}
.script-step p {
  font-size:14px;
  line-height:1.9;
  margin-top:10px
}
.script-step:last-child {
  border:0
}
.settings-grid {
  max-width:740px;
  padding:25px;
  display:grid;
  gap:22px
}
.setting-row {
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:25px
}
.setting-row p {
  font-size:12px;
  color:var(--texte-doux);
  margin-top:6px;
  line-height:1.7
}
.switch {
  width:42px;
  height:25px;
  background:#dfe2ec;
  border:0;
  border-radius:15px;
  padding:3px;
  flex:none
}
.switch:after {
  content:'';
  display:block;
  width:19px;
  height:19px;
  background:white;
  border-radius:50%;
  transition:transform .2s;
  box-shadow:0 1px 4px #0002
}
.switch[aria-checked=true] {
  background:var(--accent)
}
.switch[aria-checked=true]:after {
  transform:translateX(17px)
}
/* Dialogs and work panel */
dialog {
  border:1px solid #e3e2ef;
  padding:0;
  border-radius:19px;
  box-shadow:0 24px 100px #11132933;
  color:var(--texte);
  width:min(540px,calc(100vw - 32px));
  max-height:90vh;
  background:white
}
dialog[open] {
  animation:appear .2s ease
}
dialog::backdrop {
  background:#171b3055;
  backdrop-filter:blur(3px)
}
.dialog-header {
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:16px;
  padding:22px 25px;
  border-bottom:1px solid var(--bordure)
}
.dialog-header h2 {
  font-size:18px
}
.dialog-content {
  padding:24px 25px;
  display:flex;
  flex-direction:column;
  gap:18px
}
.dialog-footer {
  display:flex;
  justify-content:flex-end;
  gap:9px;
  padding:18px 25px;
  border-top:1px solid var(--bordure);
  background:#fcfcfe
}
.form-grid {
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:16px
}
.span-2 {
  grid-column:1/-1
}
.drawer {
  position:fixed;
  inset:12px 12px 12px auto;
  margin:0;
  width:425px;
  max-height:calc(100vh - 24px);
  height:calc(100vh - 24px);
  border-radius:18px
}
.drawer[open] {
  display:flex;
  flex-direction:column;
  animation:slidein .25s ease
}
@keyframes slidein {
  from {
    transform:translateX(35px);
    opacity:0
  }
to {
    transform:translateX(0);
    opacity:1
  }
}
.drawer .dialog-header {
  padding:19px 23px
}
.drawer .dialog-content {
  overflow:auto;
  flex:1;
  padding:24px
}
.detail-company {
  display:flex;
  gap:14px;
  align-items:center
}
.detail-company .avatar {
  width:51px;
  height:51px;
  font-size:17px;
  border-radius:14px
}
.detail-company h2 {
  font-size:21px;
  line-height:1.4
}
.detail-company p {
  font-size:12px;
  color:var(--texte-doux);
  margin-top:5px
}
.detail-section {
  border-top:1px solid var(--bordure);
  padding-top:19px
}
.detail-label {
  font-size:10px;
  text-transform:uppercase;
  letter-spacing:1.3px;
  color:#8b91a5;
  font-weight:700;
  margin-bottom:14px
}
.detail-info {
  display:flex;
  align-items:center;
  gap:12px;
  padding:9px 0;
  font-size:13px;
  color:#606980
}
.detail-info .icon {
  color:#9299ac;
  width:17px;
  height:17px
}
.detail-info a {
  font-size:12px
}
.detail-history {
  display:flex;
  gap:10px;
  padding:10px 0;
  font-size:12px;
  line-height:1.7
}
.detail-history:before {
  content:'';
  background:#d9d1ff;
  flex:none;
  width:7px;
  height:7px;
  margin-top:6px;
  border-radius:50%
}
.focus-dialog {
  width:min(700px,calc(100vw - 32px))
}
.focus-top {
  background:linear-gradient(125deg,#5b3df0,#5b6cd5);
  color:white;
  padding:25px
}
.focus-top .icon-btn {
  background:#ffffff15;
  color:white;
  border-color:#ffffff22
}
.focus-progress {
  display:flex;
  gap:5px;
  margin-top:20px
}
.focus-progress i {
  display:block;
  height:4px;
  flex:1;
  background:#ffffff26;
  border-radius:4px
}
.focus-progress i.done {
  background:#94dfef
}
.focus-top h2 {
  font-size:25px;
  margin-top:16px
}
.focus-top p {
  font-size:12px;
  color:#e4ddff;
  margin-top:6px
}
.focus-main {
  padding:25px
}
.focus-script {
  background:#f7f6fc;
  border:1px solid #eeebf8;
  border-radius:11px;
  padding:17px;
  line-height:1.85;
  font-size:13px;
  margin:18px 0
}
.outcomes {
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:10px;
  margin-top:17px
}
.outcomes button {
  justify-content:flex-start;
  padding:13px;
  font-size:12px
}
.focus-footer {
  display:flex;
  justify-content:space-between;
  align-items:center;
  padding:16px 25px;
  border-top:1px solid var(--bordure);
  font-size:11px;
  color:var(--texte-doux)
}
.command-dialog {
  width:min(610px,calc(100vw - 32px))
}
.command-search {
  display:flex;
  align-items:center;
  gap:12px;
  padding:18px 21px;
  border-bottom:1px solid var(--bordure)
}
.command-search input {
  border:0;
  outline:0;
  box-shadow:none!important;
  width:100%;
  font-size:15px
}
.command-results {
  max-height:400px;
  overflow:auto;
  padding:9px
}
.command-result {
  display:flex;
  align-items:center;
  gap:11px;
  padding:12px;
  width:100%;
  border:0;
  background:white;
  text-align:left;
  border-radius:8px
}
.command-result:hover,
.command-result:focus {
  background:var(--accent-pale)
}
.command-result strong {
  font-size:13px
}
.command-result small {
  font-size:11px;
  color:var(--texte-doux)
}
.command-caption {
  font-size:10px;
  color:#9297a8;
  letter-spacing:1px;
  text-transform:uppercase;
  padding:13px 12px 8px
}
.toast {
  position:fixed;
  bottom:24px;
  left:calc(50% + 100px);
  transform:translate(-50%,20px);
  border-radius:11px;
  background:var(--navy);
  color:white;
  padding:14px 21px;
  font-size:12px;
  box-shadow:0 10px 40px #171b3029;
  z-index:100;
  opacity:0;
  pointer-events:none;
  transition:opacity .2s,transform .2s;
  max-width:calc(100vw - 30px)
}
.toast.show {
  opacity:1;
  transform:translate(-50%,0)
}
.sr-only {
  position:absolute;
  width:1px;
  height:1px;
  padding:0;
  margin:-1px;
  overflow:hidden;
  clip:rect(0,0,0,0);
  white-space:nowrap;
  border:0
}
/* **L'état « replié » n'existe que sur grand écran** (24/09/2026). Sous 590 px
   la barre sort de l'écran et s'ouvre en entier au bouton ☰ : « replié » n'y
   veut plus rien dire. Sans cette media query, `.collapsed .sidebar` (deux
   classes) l'emportait sur le `.sidebar { width:224px }` de la vue téléphone
   (une seule), et le menu s'ouvrait sur une bande de 76 px avec les libellés
   qui débordaient par-dessus la page — un menu qui paraît ne pas s'afficher.
   Et comme l'état vit dans le navigateur **de l'appareil**, la panne frappait
   un téléphone et pas l'autre : signalée sur un Samsung, invisible sur
   l'iPhone. C'est le premier des deux verrous, `barre.js` porte l'autre. */
@media (min-width: 591px) {
.collapsed .sidebar {
  width:76px;
  padding-left:12px;
  padding-right:12px
}
.collapsed .app {
  margin-left:76px
}
.collapsed .brand {
  padding:0 7px
}
.collapsed .brand-name,
.collapsed .workspace,
.collapsed .nav-label,
.collapsed .nav-text,
.collapsed .nav .count,
.collapsed .local-card,
.collapsed .user-info {
  display:none
}
.collapsed .nav {
  margin-top:35px
}
.collapsed .nav-secondary {
  margin-top:0
}
.collapsed .nav button,
.collapsed .nav a,
.collapsed .nav summary {
  justify-content:center;
  padding:13px
}

/* Repliée, la barre n'a plus la place d'un sous-menu ni d'une flèche : seule
   l'icône reste, et c'est elle qui doit rester centrée. Les `<details>` gardent
   leur état — les rouvrir en dépliant ne demande rien. */
.collapsed .nav .volet,
.collapsed .nav summary .chevron,
.collapsed .nav a .icon.sm {
  display:none
}

/* Le bouton passe sous le logotype : côte à côte, il ne rentre pas dans 76 px. */
.collapsed .brand {
  flex-direction:column;
  gap:12px
}
.collapsed .user {
  flex-direction:column;
  padding:17px 0 0
}
.collapsed .collapse {
  margin:0
}
.collapsed .brand-mark {
  transform:scale(.85)
}
}  /* fin de @media (min-width: 591px) — l'état replié */
.compact td {
  padding-top:10px;
  padding-bottom:10px
}
.no-motion * {
  animation:none!important;
  transition:none!important
}
/* --- Les tailles d'écran, reprises du fichier de maquette -------------------
   **Réécrit le 10/09/2026, après « l'app web n'est pas responsive mobile ».**
   Elle avait raison, et la cause était dans mon import : le script qui a porté
   le CSS de la maquette filtrait les règles de coquille déjà écrites à la main
   — et il les a filtrées **aussi à l'intérieur des media queries**, où elles
   n'étaient justement écrites nulle part ailleurs. Trente-neuf règles perdues,
   dont les deux qui font tout : sous 590 px la barre part hors écran
   (`translateX(-100%)`) et `.app` doit alors perdre sa marge de 224 px. Sans la
   seconde, le contenu restait poussé hors de l'écran à droite ; et sans le
   bouton d'ouverture, la barre partie ne revenait pas.

   Ces blocs sont donc ceux du fichier d'origine, à trois retouches près :
   nos noms de variables, les règles de tableau portées par `.table-wrap`, et
   `.nav button` étendu à `.nav a` / `.nav summary` — la maquette navigue en
   boutons, nous en liens.
   ========================================================================== */

@media(min-width:1550px) {
  :root { font-size:15px }
  .sidebar { width:238px }
  .app { margin-left:238px }
  .main { padding:38px 42px }
  .workspace-grid { grid-template-columns:minmax(0,1fr) 310px }
  .overview { grid-template-columns:minmax(420px,1.9fr) repeat(2,minmax(195px,1fr)) }
  .company-name { font-size:14px }
  .table-wrap td { padding-top:19px;padding-bottom:19px }
  .company-sub,
  .place small { font-size:12px }
  .place,
  .tag { font-size:13px }
  .rail .card-head h2 { font-size:16px }
  .appointment-info button { font-size:14px }
  .appointment-info p { font-size:12px }
  .tip-card p { font-size:13px }
  .mission-stat { font-size:37px }
  .stat-number { font-size:36px }
  .toolbar .btn,
  .search-field input,
  .tabs button { font-size:13px }
  .topbar { padding:0 42px }
  .nav button,
  .nav a,
  .nav summary { font-size:14px }
}

@media(max-width:1250px) {
  .sidebar { width:194px }
  .app { margin-left:194px }
  .brand-name { font-size:19px }
  .sidebar { padding-left:12px;padding-right:12px }
  .main { padding:25px 24px }
  .topbar { padding:0 24px }
  .workspace-grid { grid-template-columns:minmax(0,1fr) 250px;gap:17px }
  .overview { grid-template-columns:minmax(325px,1.75fr) repeat(2,minmax(125px,1fr));gap:13px }
  .mission { padding:20px;gap:13px }
  .mission .btn { font-size:11px;padding:11px }
  .stat { padding:18px }
  .hide-medium { display:none }
  .table-wrap td,
  .table-wrap th { padding-left:12px;padding-right:12px }
  .table-wrap td:first-child,
  .table-wrap th:first-child { padding-left:20px }
  .company { min-width:160px }
  .toolbar { padding-left:19px;padding-right:19px }
  .tabs { gap:15px }
  .top-date { display:none }
}

@media(max-width:1080px) {
  .workspace-grid { grid-template-columns:minmax(0,1fr) }
  .rail { display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr) }
  .rail .schedule { display:flex;gap:18px }
  .appointment { flex:1;border:0;gap:8px;padding-top:6px }
  .appointment:nth-child(n+3) { display:none }
  .tip-card { display:flex;flex-direction:column;justify-content:center }
  .tip-card h3 { margin-top:5px }
  .overview { grid-template-columns:minmax(325px,1.65fr) repeat(2,minmax(120px,1fr)) }
  .main { padding:25px 22px }
  .company-name { font-size:13px }
  .company-sub { font-size:11px }
  .metrics { gap:12px }
  .global-search { width:240px }
}

@media(max-width:850px) {
  .sidebar { width:76px;padding-left:12px;padding-right:12px }
  .app { margin-left:76px }
  .brand { padding:0 7px }
  .brand-name,
  .workspace,
  .nav-label,
  .nav-text,
  .nav .count,
  .local-card,
  .user-info { display:none }
  .nav { margin-top:35px }
  .nav-secondary { margin-top:0 }
  .nav button,
  .nav a,
  .nav summary { justify-content:center;padding:13px }
  .user { flex-direction:column;padding:17px 0 0 }
  .collapse { margin:0 }
  .brand-mark { transform:scale(.85) }
  .overview { grid-template-columns:minmax(0,1fr) minmax(0,1fr) }
  .mission { grid-column:1/-1;justify-content:space-between;min-height:145px }
  .stat { min-height:125px }
  .stat-number { font-size:28px }
  .mission-actions .btn { font-size:13px;padding:12px 18px }
  .page-heading .btn { font-size:12px }
  .page-heading { align-items:flex-start }
  .page-heading h1 { font-size:27px }
  .rail { grid-template-columns:minmax(0,1fr) minmax(0,1fr) }
  .rail .schedule { display:block }
  .appointment:nth-child(n+3) { display:none }
  .appointment { padding:12px 0 }
  .dashboard-grid,
  .scripts-grid { grid-template-columns:minmax(0,1fr) }
  .metrics { grid-template-columns:minmax(0,1fr) minmax(0,1fr) }
  .metrics .stat { min-height:135px }
  .topbar { padding:0 22px }
  .breadcrumb { display:none }
  .top-actions { gap:10px }
  .filter-panel { grid-template-columns:minmax(0,1fr) minmax(0,1fr) }
  .toast { left:50% }
}

@media(max-width:590px) {
  .sidebar { transform:translateX(-100%);width:224px }
  .app,
  .collapsed .app { margin-left:0 }
  .sidebar.open { transform:translateX(0);box-shadow:10px 0 50px #171b3040 }
  .sidebar.open .brand-name,
  .sidebar.open .nav-text,
  .sidebar.open .user-info,
  .sidebar.open .nav-label,
  .sidebar.open .local-card { display:block }
  .sidebar.open .workspace { display:flex }
  .sidebar.open .nav { margin-top:0 }
  .sidebar.open .nav button,
  .nav a,
  .nav summary { justify-content:flex-start }
  .sidebar.open .user { flex-direction:row }
  .sidebar.open .brand { padding:0 9px }
  .sidebar.open .nav-secondary { margin-top:32px }
  .mobile-menu { display:inline-flex }
  .topbar { height:62px;padding:0 17px }
  .global-search { width:auto;flex:1 }
  .global-search kbd { display:none }
  .top-actions { gap:8px }
  .top-actions .top-help { display:none }
  .main { padding:23px 16px }
  .page-heading { margin-bottom:20px;gap:10px }
  .page-heading h1 { font-size:25px }
  .page-heading p { font-size:12px;max-width:215px;line-height:1.6 }
  .page-heading .btn .add-label { display:none }
  .page-heading .btn { padding:10px }
  .overview { gap:12px;margin-bottom:20px }
  .mission { padding:20px;gap:10px;min-height:157px }
  .mission-stat { font-size:29px }
  .mission-stat small { font-size:11px }
  .mission .eyebrow { font-size:9px }
  .mission-actions .btn { padding:11px 12px;font-size:11px }
  .mission-actions .btn .icon { display:none }
  .mission-actions p { font-size:9px }
  .stat { padding:17px }
  .stat .stat-icon { width:27px;height:27px }
  .stat-label { font-size:11px }
  .stat-foot { font-size:10px }
  .card-head { padding:19px 17px 15px }
  .toolbar { padding:0 16px 14px;flex-wrap:wrap }
  .toolbar .search-field { flex-basis:190px }
  .tabs { padding:0 17px;gap:19px }
  .table-wrap th:first-child,
  .table-wrap td:first-child { padding-left:17px }
  .hide-mobile { display:none }
  .company { min-width:163px;gap:9px }
  .company .avatar { width:29px;height:29px;font-size:10px }
  .company-name { font-size:11px }
  .company-sub { font-size:10px }
  .table-wrap th,
  .table-wrap .table-wrap td { padding-left:9px;padding-right:9px }
  .tag { font-size:10px;padding:5px 7px }
  .rail { grid-template-columns:minmax(0,1fr) }
  .rail .schedule { display:flex }
  .tip-card { display:none }
  .bottom-note { font-size:9px;line-height:1.7 }
  .filter-panel { padding:15px;gap:11px }
  .filter-panel label { font-size:11px }
  .table-footer { padding:13px 16px;font-size:9px }
  .prospect-cards { grid-template-columns:minmax(0,1fr) }
  .drawer { inset:0;margin:0;width:100%;height:100dvh;max-height:100dvh;border-radius:0 }
  .form-grid { grid-template-columns:minmax(0,1fr) }
  .span-2 { grid-column:auto }
  .dialog-content { padding:21px }
  .dialog-header { padding:19px 21px }
  .outcomes { grid-template-columns:minmax(0,1fr) }
  .focus-top { padding:22px }
  .focus-main { padding:20px }
  .focus-dialog { max-height:94dvh }
  .week-grid { grid-template-columns:repeat(7,180px) }
  .agenda-toolbar { flex-wrap:wrap }
  .settings-grid { padding:20px }
  .metrics .stat { padding:17px }
  .chart { gap:10px;margin:0 15px;padding:20px 7px }
  /* Sur un téléphone, l'étiquette reprend le droit de passer à la ligne. Forcée
     sur une seule, elle pose une largeur minimale à chaque colonne et fait
     déborder le graphique hors de l'écran. Ici toutes les dates se coupent de la
     même façon — c'est régulier, donc ça se lit — et la hauteur ne coûte rien
     sur un écran qui défile de toute façon. */
  .chart-col > span { white-space:normal;font-size:10px }
  .stat-number { font-size:27px }
  .card-head h2 { font-size:15px }
}

@media(prefers-reduced-motion:reduce) {
  *,
  *::before,
  *::after { animation:none!important;transition:none!important;scroll-behavior:auto!important }
}


/* --- Ce que la maquette n'avait pas prévu, et qu'un téléphone révèle --------
   Cinq corrections, toutes mesurées et non devinées : à 390 px la page
   débordait de 83 px vers la droite, et le coupable se lit dans les rectangles
   (`getBoundingClientRect`), pas à l'œil. C'est la même méthode que le
   débordement écarté par la mesure le 04/09/2026.

   Aucune ne change quoi que ce soit sur un grand écran : elles ne s'appliquent
   qu'en dessous de la largeur où le défaut existe. */

/* **La cause principale.** Un élément de grille vaut `minmax(auto, 1fr)` par
   défaut : sa largeur minimale est celle de son contenu, donc un tableau large
   fait grossir la colonne au lieu de défiler dedans. La maquette écrit bien
   `minmax(0, 1fr)` sur son grand écran, et le perd en repassant à `1fr` sous
   1080 px — là où le tableau est justement le plus large par rapport à la
   page. `minmax(0, …)` rend la main à l'`overflow: auto` de `.table-wrap`. */
@media (max-width: 1080px) {
  .workspace-grid { grid-template-columns: minmax(0, 1fr); }
  .rail { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); }
  .dashboard-grid, .scripts-grid { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 850px) {
  .metrics { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}

@media (max-width: 590px) {
  .rail { grid-template-columns: minmax(0, 1fr); }

  /* Un titre de carte et son bouton d'action ne tiennent pas sur une ligne de
     390 px : ils passent l'un sous l'autre plutôt que de pousser la carte. */
  .card-head { flex-wrap: wrap; }

  /* Deux colonnes de filtres à 390 px font deux colonnes illisibles. */
  .filter-panel { grid-template-columns:minmax(0,1fr); }

  .metrics { grid-template-columns:minmax(0,1fr); }
}

/* Nos cases à cocher en ligne — secteurs, départements — n'existent pas dans la
   maquette, dont les filtres sont tous des menus déroulants. Elles se replient
   sur autant de lignes qu'il faut : un mur de cases sur une seule ligne est ce
   qui a fait passer la ville en champ de saisie le 16/08/2026. */
.cases-en-ligne {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
}

.cases-en-ligne label,
.cases-en-ligne .case {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 500;
  color: var(--texte);
  white-space: nowrap;
}

.cases-en-ligne input {
  width: 15px;
  height: 15px;
  margin: 0;
  flex: none;
}


/* --- Deux débordements que seule la mesure a montrés -----------------------
   `.table-wrap` devient un **contexte de positionnement**. Sans lui, le
   `<span class="sr-only">` de la dernière colonne — le libellé lu par un
   lecteur d'écran, en `position: absolute` — se positionne par rapport à la
   page entière : il se retrouvait à 462 px sur un écran de 390, **hors du
   conteneur qui défile**, et étirait le document de 73 px. Un carré d'un pixel,
   invisible, qui faisait glisser toute la page vers la droite.

   Il ne se voyait ni à l'œil ni dans les rectangles des blocs : `body` mesurait
   bien 390, c'est `documentElement` qui débordait. Trouvé le 10/09/2026 en
   listant les éléments positionnés, après « l'app web n'est pas responsive ». */
.table-wrap { position: relative; }

/* L'écran d'appel garde sa grille d'origine, avec le même défaut de piste que
   `.workspace-grid` : `1fr` vaut `minmax(auto, 1fr)`, donc le tableau des
   objections du script poussait la colonne au lieu de défiler dedans. */
@media (max-width: 62rem) {
  .appel { grid-template-columns: minmax(0, 1fr); }
}

/* Sur un téléphone, les 3,7 rem qui alignent les lignes sous la pastille de
   score mangent un sixième de la largeur. La pastille reste, l'alignement
   part : c'est lui qui coûte, pas elle. */
@media (max-width: 590px) {
  .appel .detail,
  .appel .badges,
  .appel .note,
  .composer,
  .detail,
  .note,
  label.notes { margin-left: 0; }

  .appel .fiche-appel { padding: 1.1rem; }
}


/* ==========================================================================
   CE QUI VIENT APRÈS LES TAILLES D'ÉCRAN
   ==========================================================================
   Ces trois blocs vivaient plus haut et ont été emportés le 10/09/2026 par une
   réécriture de la fin du fichier : le garde-fou vérifiait ce qu'il **coupait**
   (« la queue ne contient que des media queries ») et non ce qu'il **gardait**.
   Ils sont désormais en dernier, où rien ne se réécrit en bloc.
   ========================================================================== */

/* --- Le bouton qui replie la barre -----------------------------------------
   Demandé le 10/09/2026. La maquette le pose en bas, contre le compte ; il est
   ici **en haut, dans la barre**, à côté du logotype — c'est là qu'on l'a
   demandé, et c'est le seul endroit qui ne bouge pas quand la barre rétrécit.

   Il replie **et** déplie : un bouton qui ne saurait faire qu'un des deux
   laisserait la barre fermée pour toujours à qui a cliqué sans le vouloir. Son
   `aria-expanded` et son libellé de survol disent lequel des deux il fera —
   l'icône seule ne le dit pas. */
.collapse {
  background: transparent;
  color: #8991ad;
  border: 0;
  margin-left: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px;
  min-height: 0;
  border-radius: 8px;
  flex: none;
}

.collapse:hover { color: #fff; background: rgba(255, 255, 255, .07); }

/* Décalé de quelques pixels dans la marge de la barre : demandé le 11/09/2026
   (« décale-le un peu »). Il gagne l'air qui lui manquait sans que le nom
   rétrécisse. */
.collapse { margin-right: -5px; }
.collapsed .collapse { margin: 0; }

/* Sur un téléphone la barre n'est pas repliable : elle est **sortie de
   l'écran**, et c'est le bouton de la barre du haut qui la ramène. Un bouton
   « replier » y ferait un troisième état dont personne n'a besoin. */
@media (max-width: 590px) {
  .collapse { display: none; }
}

/* --- Les titres de page en dégradé ----------------------------------------
   Demandé le 10/09/2026 : « je veux que pour chaque titre de page tu les
   affiches en dégradé avec les couleurs présentes sur le site ». Les trois
   couleurs sont celles du logotype — violet, violet clair, cyan — donc le titre
   dit la marque sans qu'on ait à la répéter.

   **Le titre d'une page seulement**, jamais un nom de prospect ni un titre de
   carte : un dégradé sur une donnée la ferait ressembler à une décoration, et
   la règle « la couleur porte du sens » tient dans les deux sens.

   Le repli n'est pas décoratif : sans `background-clip: text`, `color:
   transparent` rendrait le titre **invisible**. Un navigateur qui ne sait pas
   découper le fond garde donc l'encre pleine. */
.page-heading h1 {
  background: linear-gradient(96deg, var(--accent) 0%, #6451e7 42%, #2b7f9e 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .page-heading h1 { color: var(--texte); background: none; }
}

/* La carte d'objectif porte déjà un dégradé de fond : un titre découpé dedans
   disparaîtrait. */
.mission h1, .mission h2 { background: none; color: #fff; }

/* --- Les marques de module -------------------------------------------------
   La troisième barre du logotype et le filet sous la barre du haut changent de
   couleur d'un outil à l'autre : violet = Prospecto, cyan = Messages,
   ambre = E-mail. Deux repères qui disent la même chose, lus sans lire. */
body.module-messages .brand-mark i:nth-child(3) { background: var(--cyan); }
body.module-email .brand-mark i:nth-child(3) { background: #f0a04b; }
body.module-ads .brand-mark i:nth-child(3) { background: #6366f1; }
body.module-ads .brand-name { color: #c7cbff; }
body.module-refonte .brand-mark i:nth-child(3) { background: #3fae86; }
body.module-refonte .brand-name { color: #bfe9d8; }
body.module-messages .brand-name { color: #bfe6f3; }

/* Le « 2 » du logotype. **Une pastille et non un mot** : « prospecto 2 » à
   22 px ne tient pas dans les 224 px de la barre, et le nom passait à la ligne
   en emportant « PAR WEBUILD » avec lui. Vu en capture, jamais par un test —
   aucun ne rend de police. En pastille il se lit comme un numéro d'espace,
   qu'il est, et la ligne tient. */
.brand-name b {
  display: inline-block;
  margin-left: 5px;
  padding: 1px 6px;
  border-radius: 6px;
  background: rgba(255, 255, 255, .12);
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0;
  vertical-align: 3px;
}

/* « prospecto 2 » est plus long que « prospecto », « messages » et
   « e-mail » : à 22 px il ne laissait plus la place du bouton qui replie, et le
   badge passait par-dessus. Le nom du plus long des quatre est donc posé plus
   petit — mesuré, pas ajusté à l'œil. */
body.module-refonte .brand-name { white-space: nowrap; font-size: 16px; }
body.module-refonte .brand-name b { font-size: 11px; padding: 1px 5px; vertical-align: 2px; }
body.module-refonte .brand-name small { letter-spacing: 1.5px; }
body.module-refonte .brand { min-height: 53px; }

body.module-refonte .topbar { border-bottom-color: #3fae86; }
body.module-email .brand-name { color: #f7d3ae; }


/* --- Le bouton du menu sur téléphone ---------------------------------------
   **Redéclaré ici, et c'est nécessaire.** Il porte `.icon-btn` pour avoir la
   forme des boutons de la barre du haut, et `.icon-btn { display: inline-flex }`
   vit dans le bloc des composants, **après** le `.mobile-menu { display: none }`
   d'origine. À spécificité égale, c'est le dernier qui gagne : le hamburger
   s'affichait donc sur un écran de 1500 px, à côté d'une barre latérale
   parfaitement visible. Vu en capture, jamais par un test.

   La règle vit en fin de feuille pour la même raison, et la bascule mobile
   l'accompagne — les séparer les remettrait dans le désordre qui a causé le
   défaut. */
.mobile-menu { display: none; }

@media (max-width: 590px) {
  .mobile-menu { display: inline-flex; }
  /* **Le repli sans JavaScript** (24/09/2026) : le bouton ☰ est un lien vers
     `#menu`, et le navigateur ouvre la barre tout seul. Le script continue de
     faire le travail quand il tourne (il annule le saut d'ancre) ; s'il ne
     tourne pas, la navigation reste atteignable au lieu de disparaître. */
  .sidebar:target { transform: translateX(0); box-shadow: 10px 0 50px #171b3040; }
  .sidebar:target .brand-name,
  .sidebar:target .nav-text,
  .sidebar:target .user-info,
  .sidebar:target .nav-label,
  .sidebar:target .local-card { display: block; }
  .sidebar:target .workspace { display: flex; }
}


/* --- La répartition du potentiel de refonte --------------------------------
   Une barre par tranche de dix points, à côté du champ qui pose le seuil :
   c'est elle qui rend le curseur choisissable. `.barre` n'a pas été
   réemployée — elle n'existe que sous `ul.repartition` et `ul.par-personne`,
   et l'étendre ici aurait fait dépendre trois écrans d'une même règle pour des
   raisons différentes.

   Ambre au-dessus du seuil (ce qui entre dans la file), gris en dessous : la
   couleur ne dit pas un état de donnée, elle dit **de quel côté du trait** on
   est — et elle change quand on déplace le trait. */
.jauge {
  flex: 1;
  height: 7px;
  border-radius: 4px;
  background: var(--gris-pale);
  overflow: hidden;
  min-width: 40px;
}

.jauge span { display: block; height: 100%; border-radius: 4px; }
.jauge span.dedans { background: var(--ambre); }
.jauge span.dehors { background: var(--gris-trait); }


/* Une ligne de tableau qui mène quelque part le dit : le curseur change, et le
   survol souligne le nom comme le ferait un lien. Sans ces deux signes, la
   ligne serait cliquable **sans que personne ne le sache** — ce qui ne vaut
   pas mieux que de ne pas l'être. */
tr[data-fiche] { cursor: pointer; }
tr[data-fiche]:hover .company-name { text-decoration: underline; }


/* Chrome et Safari ne lisent pas `scrollbar-width` : ils ont leur propre
   vocabulaire, et la barre latérale est le seul endroit de l'outil qui défile
   dans un cadre étroit. */
/* **Un champ de fichier ne rétrécit pas tout seul** (29/09/2026). Sa largeur
   native dépend du navigateur et de la langue — 318 px ici, à cause du bouton
   « Choisir un fichier » et du « Aucun fichier sélectionné » à côté — et il
   ignore la place disponible. Mesuré sur la fiche à 1470 px, barre repliée :
   celui du formulaire « Déposer mon propre site » finissait **84 px hors de
   l'écran**.

   Chrome le rognait sans broncher ; c'est un défaut qui ne se voit donc pas
   là-dessus, et qui pousse la page sur d'autres moteurs — d'où un écran qui
   part en travers sur Safari et pas sur Chrome, exactement la famille de pannes
   du menu Samsung.

   `min-width: 0` sur le conteneur en plus de `max-width` sur le champ : un
   enfant de flex ou de grille refuse de descendre sous sa taille intrinsèque
   tant qu'on ne le lui permet pas, et `max-width` seul n'y suffit pas. Posé sur
   les quatre champs de fichier de l'application, pas seulement sur celui qui a
   été pris en défaut. */
/* **Un grand tableau défile au lieu d'être coupé** (29/09/2026). Mesuré sur la
   liste du jour à 1280 px : le tableau dépassait de 572 px — la moitié de ses
   colonnes était invisible, et rien à l'écran ne disait qu'il y avait quelque
   chose de plus à droite. Un tableau qu'on ne peut pas atteindre est pire qu'un
   tableau serré.

   `:has()` plutôt qu'une classe posée à la main dans chaque gabarit : c'est la
   seule façon de le faire **une fois** et que ça vaille pour le tableau qu'on
   ajoutera demain. Le défilement porte sur la carte, pas sur le tableau — un
   `display:block` sur un `<table>` casserait sa mise en colonnes. */
/* **Le panneau de filtres prend une ligne entière** quand la barre d'outils
   passe à la ligne (29/09/2026). Sans ça, il restait un enfant de flex comme un
   autre : à 900 px il était comprimé à 110 px de large, ses trois colonnes à
   14 px chacune, et les pastilles de secteur débordaient de l'écran sans aucun
   moyen de les atteindre. `flex-basis: 100 %` le sort de la mêlée ; `min-width:
   0` lui permet de descendre sous la largeur de son contenu, ce qu'un enfant de
   flex refuse par défaut. */
details.filtrage { flex: 1 1 100%; min-width: 0; }
.filter-panel { min-width: 0; }

.carte:has(> table), .card:has(> table) { overflow-x: auto; }

input[type="file"] { max-width: 100%; box-sizing: border-box; }
form, .edition, details > form { min-width: 0; }

.sidebar::-webkit-scrollbar { width: 6px; }
.sidebar::-webkit-scrollbar-track { background: transparent; }
.sidebar::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, .18);
  border-radius: 3px;
}


/* --- Le logotype quand la barre est étroite ---------------------------------
   La barre fait 238 px au-dessus de 1550, 224 entre 1250 et 1550, 194 en
   dessous. Aux deux largeurs basses, « prospecto » à 22 px ne tient plus à côté
   du bouton qui replie : il se faisait couper en « prospect ».

   Le nom est donc posé plus petit et la marque resserrée, plutôt que rogné — un
   logotype tronqué se lit comme un défaut d'affichage, pas comme un choix.

   **Mesuré à six largeurs, pas ajusté à l'œil** : on compare la largeur
   **rendue** du nom à sa largeur **naturelle** (`scrollWidth`). Un texte coupé
   ne se voit pas autrement qu'en regardant, et on ne regarde pas toutes les
   largeurs. */
@media (max-width: 1549px) {
  .brand { gap: 8px; }
  .brand-name { font-size: 19px; letter-spacing: -.7px; }
  .brand-mark { width: 30px; }
  .brand-mark i { width: 7px; }
  .collapse { padding: 4px; }
}

@media (max-width: 1250px) {
  .brand-name { font-size: 16px; letter-spacing: -.6px; }
  .brand-name small { letter-spacing: 1.2px; font-size: 9px; }
  .brand-mark { width: 26px; height: 32px; }
  .brand-mark i { width: 6px; height: 25px; }
  .brand-mark i:nth-child(2) { height: 31px; }
  .brand-mark i:nth-child(3) { height: 19px; }
}

/* Le choix du script, dans le titre de l'encart (14/09/2026). */
.script-tete { display:flex; align-items:center; gap:8px; flex-wrap:wrap }
.script-choix {
  font:inherit; font-size:13px; font-weight:600; padding:4px 8px;
  border:1px solid var(--bordure); border-radius:var(--rayon-petit);
  background:var(--carte); color:var(--texte); max-width:100%
}

/* Le bandeau « Activer les notifications » (14/09/2026) : dans l'app installée,
   tant que le téléphone n'a pas donné la permission. Il prend la couleur de ce
   qui se clique, pas celle d'une alerte : ce n'est pas une erreur, c'est un geste
   à faire une fois. */
.activer-notifications {
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  margin-bottom:18px; padding:14px 16px;
  border:1px solid var(--bordure); border-radius:var(--rayon-petit);
  background:#f4f2fe; color:var(--texte); font-size:14px
}
.activer-notifications .texte { flex:1; min-width:200px }
.activer-notifications button {
  font:inherit; font-weight:600; padding:8px 14px; border:0;
  border-radius:var(--rayon-petit); background:var(--accent); color:#fff; cursor:pointer
}
.activer-notifications button[disabled] { opacity:.6; cursor:wait }

/* `display:flex` l'emporterait sur l'attribut `hidden` : sans cette ligne le
   bandeau s'afficherait partout, même là où il n'a rien à dire. */
.activer-notifications[hidden] { display:none }

/* --- Suivi client : En attente et Relancer (15/09/2026) ---------------------
   Sur la maquette du propriétaire : quatre chiffres, la progression du jour, des
   pastilles de température, une carte par client bordée de sa température. Les
   températures prennent les couleurs d'état de la maison — rouge, ambre, bleu —
   jamais le vermillon de la marque, réservé à ce qu'on clique. */
.suivi-chiffres .stat { min-height: 0; padding: 18px 20px; }
.suivi-chiffres .stat-number.rouge { color: var(--rouge); }
.suivi-chiffres .stat-number.vert { color: var(--vert); }

.point {
  display: inline-block;
  width: .45rem;
  height: .45rem;
  margin-right: .35rem;
  border-radius: 50%;
  vertical-align: middle;
  background: var(--texte-doux);
}
.point.chaud { background: var(--rouge); }
.point.tiede { background: var(--ambre); }
.point.froid { background: var(--accent); }

.suivi-progression { padding: 16px 20px; margin-bottom: 22px; }
.suivi-progression .ligne { display: flex; justify-content: space-between; margin-bottom: .5rem; font-size: .9rem; }
.suivi-progression .barre { height: 8px; border-radius: 6px; background: var(--fond); overflow: hidden; }
.suivi-progression .barre span { display: block; height: 100%; border-radius: 6px; background: var(--vert); }

.suivi-outils {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: .75rem;
  margin-bottom: 1rem;
}
.puces { display: flex; flex-wrap: wrap; gap: .5rem; }
.puce {
  display: inline-flex;
  align-items: center;
  padding: .45rem .85rem;
  border: 1px solid var(--bordure);
  border-radius: 999px;
  background: var(--carte);
  color: var(--texte-doux);
  font-size: .85rem;
  font-weight: 600;
  text-decoration: none;
}
.puce:hover { background: var(--fond); text-decoration: none; }
.puce.active { border-color: var(--accent-fort); background: var(--accent-pale); color: var(--accent-fort); }
.puce.chaud.active { border-color: var(--rouge); background: var(--rouge-pale); color: var(--rouge); }
.puce.tiede.active { border-color: var(--ambre); background: var(--ambre-pale); color: var(--ambre); }

ol.suivi-cartes { display: flex; flex-direction: column; gap: 12px; margin: 0; padding: 0; list-style: none; }
.suivi-carte {
  padding: 18px 20px;
  border-left: 4px solid var(--bordure);
  border-radius: 14px;
  background: var(--carte);
  box-shadow: var(--ombre);
}
.suivi-carte.chaud { border-left-color: var(--rouge); }
.suivi-carte.tiede { border-left-color: var(--ambre); }
.suivi-carte.froid { border-left-color: var(--accent); }

.suivi-haut { display: flex; align-items: flex-start; gap: 14px; }
.suivi-corps { flex: 1; min-width: 0; }
.initiales {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  font-weight: 700;
  background: var(--fond);
}
.initiales.chaud { background: var(--rouge-pale); color: var(--rouge); }
.initiales.tiede { background: var(--ambre-pale); color: var(--ambre); }
.initiales.froid { background: var(--accent-pale); color: var(--accent-fort); }
.suivi-titre { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin-bottom: .4rem; }
.suivi-titre .nom { font-size: 1.15rem; font-weight: 700; color: var(--texte); }
.suivi-motif { margin: 0 0 .25rem; }
.suivi-date { display: flex; flex-direction: column; flex-shrink: 0; text-align: right; }
.suivi-date strong.rouge { color: var(--rouge); }
.suivi-gestes { align-items: center; margin: 14px 0 0; }
/* « Appeler » en bouton plein, comme la maquette : c'est le geste principal de la
   carte. Le retrait hérité des listes à score (3,7 rem) n'a rien à aligner ici. */
.suivi-gestes .bouton.appeler {
  margin: 0;
  border-color: var(--accent-fort);
  background: var(--accent-fort);
  color: #fff;
}
.marquer-relance { display: inline-flex; flex-wrap: wrap; align-items: center; gap: .5rem; }

/* **Le bouton du volet se voit** : en couleur, avec sa flèche qui tourne à
   l'ouverture — demandé explicitement, un lien gris « plus » ne se remarquait
   pas, et c'est derrière lui que vivent les SMS et les issues. */
details.plus-actions { margin-top: 12px; }
details.plus-actions > summary {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
  padding: .5rem .95rem;
  border: 1px solid var(--accent-fort);
  border-radius: 9px;
  background: var(--accent-pale);
  color: var(--accent-fort);
  font-size: .9rem;
  font-weight: 650;
  list-style: none;
  cursor: pointer;
}
details.plus-actions > summary::-webkit-details-marker { display: none; }
details.plus-actions > summary::after { content: "▾"; transition: transform .15s; }
details.plus-actions[open] > summary { background: var(--accent-fort); color: #fff; }
details.plus-actions[open] > summary::after { transform: rotate(180deg); }
button.choisie { background: var(--accent-pale); color: var(--accent-fort); font-weight: 700; }

.suivi-faits { margin-top: 28px; }
.suivi-faits ol { margin: 0; padding: 0; list-style: none; }
.suivi-faits li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
  padding: 10px 16px;
  border-radius: 12px;
  background: var(--vert-pale);
}
.suivi-faits .texte-barre { color: var(--texte-doux); text-decoration: line-through; }

@media (max-width: 640px) {
  .suivi-haut { flex-wrap: wrap; }
  .suivi-date { text-align: left; }
}

/* Le gérant, en clair sous le nom (16/09/2026) : on le demande par son prénom en
   décrochant, il doit se lire avant de composer. */
.gerant {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .4rem;
  margin: .35rem 0 .5rem;
  font-size: 1rem;
  color: var(--texte);
}
.gerant strong { font-weight: 700; }

/* La recherche de fiche du module Messages (16/09/2026). */
.recherche-sms { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 1.25rem; }
.recherche-sms input { flex: 1; min-width: 14rem; }

/* La dernière note, en haut de la fiche (16/09/2026). */
.note-en-tete { margin: 0 0 18px; }
.note-en-tete textarea { width: 100%; margin-top: .6rem; }
.note-en-tete .actions { margin: .6rem 0 0; }

/* Prendre un rendez-vous depuis une conversation (16/09/2026). */
form.rdv-sms .creneau { display: flex; flex-wrap: wrap; gap: .75rem; }
form.rdv-sms label { display: block; margin-top: .5rem; }
form.rdv-sms input[type="text"] { width: 100%; }
.rdv-conversation { margin-top: .5rem; }

/* --- La page d'un client dans Messages (16/09/2026) --------------------------
   Pleine largeur, deux colonnes : ce qu'on fait avec lui à gauche, ce qui le range
   à droite. La conversation en bulles, comme toute messagerie : ce qu'il écrit à
   gauche, ce qu'on lui écrit à droite, en vermillon pâle — la couleur de ce qu'on
   fait, jamais d'un état. */
.fil-entete { margin-bottom: 18px; flex-wrap: wrap; }
.fil-entete h2 { margin: 0; }
.fil-entete .avatar { background: var(--accent-pale); color: var(--accent-fort); display: grid; place-items: center; font-weight: 700; }
.fil-entete .gerant { margin: .2rem 0 0; }
.fil-grille { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 18px; align-items: start; }
.fil-principal, .fil-cote { display: flex; flex-direction: column; gap: 18px; }
.fil-grille .carte + .carte { margin-top: 0; }
@media (max-width: 900px) { .fil-grille { grid-template-columns:minmax(0,1fr); } }

details.volet > summary {
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  flex-wrap: wrap; list-style: none; cursor: pointer;
}
details.volet > summary::-webkit-details-marker { display: none; }
details.volet > summary .volet-titre { font-weight: 700; font-size: 1.05rem; }
details.volet > summary .volet-titre::before {
  content: "▸"; display: inline-block; margin-right: .5rem; color: var(--accent-fort);
  transition: transform .15s;
}
details.volet[open] > summary .volet-titre::before { transform: rotate(90deg); }
details.volet[open] > summary { margin-bottom: 1rem; }

ol.bulles { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .7rem; }
.bulle { max-width: 78%; padding: .7rem .95rem; border-radius: 16px; }
.bulle.recu { align-self: flex-start; background: var(--fond); border-bottom-left-radius: 4px; }
.bulle.envoye { align-self: flex-end; background: var(--accent-pale); border-bottom-right-radius: 4px; }
.bulle-texte { margin: 0; white-space: pre-wrap; line-height: 1.5; }
.bulle-meta { display: block; margin-top: .3rem; font-size: .78rem; color: var(--texte-doux); }
.bulle.envoye .bulle-meta { text-align: right; }

/* La zone de texte prend toute la largeur de sa carte : « élargis la zone texte,
   ça ne sert à rien une barre au milieu ». */
.zone-message textarea { display: block; width: 100%; box-sizing: border-box; }
.zone-message .actions { margin: .75rem 0 0; }
ul.liste-rdv { margin: 0 0 .75rem; padding-left: 1.1rem; }
ul.liste-rdv li + li { margin-top: .4rem; }

/* --- Les événements libres de l'agenda (17/09/2026) ------------------------
   Bleu nuit : ni vert, ni ambre, ni rouge (les couleurs d'état), ni violet
   (l'action). Un événement n'est pas une donnée de vente, il ne doit pas se
   lire comme tel. */
table.calendrier .case.evenement { color: #fff; background: var(--navy); }
/* **L'appel de confirmation** posé tout seul quand un rendez-vous est pris pour
   un autre jour (28/09/2026, migration 060). Une couleur à lui, demandée : sur
   le navy des événements libres il se serait confondu avec une réunion, et
   c'est celui des deux qui fait perdre un rendez-vous quand on le saute.

   **Le teal n'est pris par rien d'autre** dans le calendrier — vert un
   rendez-vous décroché au téléphone, acide par message, cyan pâle Prospecto 2,
   ambre une relance de devis, rouge un client à relancer, violet un rappel. Il
   est volontairement **proche du vert du rendez-vous** qu'il sert, et assez
   franc pour ne pas s'y fondre : ce qu'on lit d'un coup d'œil, c'est « il y a
   un rendez-vous ce jour-là, et un appel à passer avant ». */
table.calendrier .case.confirmation { color: #0d5c66; background: #d6f2f4; }
ol.prospects li.evenement { border-left-color: var(--navy); }
.badge.nuit { color: #fff; background: var(--navy); }
details.nouvel-evenement { margin-top: 1.5rem; }
.ligne-evenement { display: flex; flex-wrap: wrap; gap: .75rem; }
.ligne-evenement label { flex: 1 1 9rem; }
/* Le volet est déjà une carte : le formulaire n'en redessine pas une dedans. */
details.nouvel-evenement > form.edition { box-shadow: none; background: none; padding: 0; border: 0; }

/* --- Ajouter un prospect dans En attente / Relancer (17/09/2026) --------- */
details.ajout-suivi { margin: 1.25rem 0; }
details.ajout-suivi > form.edition { box-shadow: none; background: none; padding: 0; border: 0; }
.ligne-ajout { display: flex; flex-wrap: wrap; gap: .75rem; }
.ligne-ajout label { flex: 1 1 12rem; }

/* Une case du calendrier ouvre la fiche (17/09/2026) : un lien qui garde
   l'allure de la case, et se signale au survol. */
table.calendrier a.case { text-decoration: none; }
table.calendrier a.case:hover { filter: brightness(.94); box-shadow: 0 0 0 2px var(--accent-trait); }

/* --- Qualifier un rendez-vous depuis la fiche (17/09/2026) ---------------
   Bien visible : c'est la question qu'on vient régler sur la fiche après
   l'appel. Fond violet pâle et trait d'accent, trois boutons pleins aux
   couleurs de leur issue. */
.qualifier-rdv {
  margin: .9rem 0;
  padding: 1rem 1.1rem;
  border-radius: var(--rayon-petit);
  background: var(--accent-pale);
  border-left: 4px solid var(--accent);
}
.qualifier-titre { display: block; font-weight: 700; margin-bottom: .6rem; }
.qualifier-boutons { display: flex; flex-wrap: wrap; gap: .6rem; align-items: flex-start; }
.qualifier-boutons form { margin: 0; }
.qualifier-boutons .bouton, .qualifier-boutons > form > button, .qualifier-boutons summary.bouton {
  font-weight: 700; color: #fff; border: 0; cursor: pointer; list-style: none;
}
.qualifier-boutons .issue-vente { background: var(--vert); }
.qualifier-boutons .issue-recontacter { background: var(--ambre); }
.qualifier-boutons .issue-perdu { background: var(--rouge); }
.qualifier-boutons details[open] { flex-basis: 100%; }
.qualifier-boutons details form { margin-top: .6rem; display: grid; gap: .5rem; }
.qualifier-boutons details form { max-width: 34rem; background: var(--carte); padding: .9rem; border-radius: var(--rayon-petit); }
.qualifier-boutons details form label { display: grid; gap: .3rem; }
.qualifier-boutons details form textarea,
.qualifier-boutons details form input,
.qualifier-boutons details form select { width: 100%; }

/* « + Nouvel événement » en bouton violet (17/09/2026) : le volet replié se
   lisait comme une ligne de texte. Fermé, on ne voit que le bouton ; ouvert, le
   formulaire se pose dans sa carte juste en dessous. */
details.nouvel-evenement { background: none; padding: 0; margin: 1.5rem 0 0; }
details.nouvel-evenement > summary {
  display: inline-flex; align-items: center; gap: .5rem;
  list-style: none;
  padding: .75rem 1.35rem;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--violet-marque), var(--violet-fonce));
  color: #fff; font-weight: 700; font-size: 1rem;
  box-shadow: 0 8px 20px -8px rgba(91, 61, 240, .55);
  transition: transform .12s ease, box-shadow .12s ease;
  user-select: none;
}
details.nouvel-evenement > summary::-webkit-details-marker { display: none; }
details.nouvel-evenement > summary:hover {
  transform: translateY(-1px);
  box-shadow: 0 12px 26px -8px rgba(91, 61, 240, .65);
}
details.nouvel-evenement > summary:focus-visible { outline: 3px solid var(--accent-trait); outline-offset: 3px; }
details.nouvel-evenement[open] > summary { box-shadow: none; }
details.nouvel-evenement > form.edition {
  margin-top: 1rem;
  padding: 1.25rem 1.4rem;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}
details.nouvel-evenement > form.edition button {
  background: var(--accent); color: #fff; border: 0; font-weight: 700;
}

/* Relancer par SMS sous un rendez-vous passé (17/09/2026). */
.relancer-apres-rdv {
  margin: .9rem 0;
  padding: 1rem 1.1rem;
  border-radius: var(--rayon-petit);
  background: var(--carte);
  border: 1px solid var(--accent-trait);
}
.relancer-apres-rdv .actions { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0; }
a.bouton.relance-sms {
  background: var(--accent-pale); color: var(--accent-fort);
  border: 1px solid var(--accent-trait); font-weight: 600;
}
a.bouton.relance-sms:hover { background: var(--accent); color: #fff; }
/* Les trois issues à la même taille, lien, volet ou bouton de formulaire. */
.qualifier-boutons .bouton, .qualifier-boutons > form > button, .qualifier-boutons summary.bouton {
  padding: .55rem 1rem; font-size: .95rem; line-height: 1.3; border-radius: var(--rayon-petit); min-height: 0;
}

/* --- Comptabilité › Coûts (17/09/2026) ----------------------------------- */
.liste-couts li .tete { display: flex; justify-content: space-between; gap: 1rem; align-items: baseline; }
.liste-couts li .prix { font-weight: 700; white-space: nowrap; }
.liste-couts li.arrete { opacity: .6; }
.liste-couts details form.edition { margin-top: .8rem; }
details.nouveau-cout { margin: 1.5rem 0; }
/* Le détail des coûts : un coût n'est pas une vente, pas de vert. */
ul.couts-detail { list-style: none; margin: 0 0 1.5rem; padding: .4rem 1.4rem; background: var(--carte); border-radius: var(--rayon); box-shadow: var(--ombre); }
ul.couts-detail li { display: grid; grid-template-columns:minmax(0,1fr) auto; gap: .1rem 1rem; padding: .8rem 0; border-bottom: 1px solid var(--bordure); }
ul.couts-detail li:last-child { border-bottom: 0; }
ul.couts-detail .nom { font-weight: 600; }
ul.couts-detail .detail { grid-column: 1; font-size: .85rem; }
ul.couts-detail .prix { grid-column: 2; grid-row: 1 / span 2; align-self: center; font-weight: 700; color: var(--texte); white-space: nowrap; }
ul.couts-detail li.total .nom, ul.couts-detail li.total .prix { font-size: 1.1rem; font-weight: 800; }
ul.couts-detail li.total .prix { color: var(--rouge); grid-row: auto; }
ul.couts-detail .detail { margin: 0; padding: 0; }

/* --- L'assistant, sur toutes les pages (17/09/2026) -----------------------
   Une bulle violette en bas à droite ; le panneau s'ouvre au-dessus. Violet :
   c'est une commande, pas un état. */
.assistant { position: fixed; right: 20px; bottom: 20px; z-index: 900; display: flex; flex-direction: column; align-items: flex-end; gap: 12px; }
.assistant[hidden] { display: none; }
.assistant-bulle {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .75rem 1.2rem; border: 0; border-radius: 999px; cursor: pointer;
  background: linear-gradient(135deg, var(--violet-marque), var(--violet-fonce));
  color: #fff; font-weight: 700; font-size: .95rem;
  box-shadow: 0 10px 24px -8px rgba(91, 61, 240, .6);
}
.assistant-bulle:hover { transform: translateY(-1px); }
.assistant-panneau {
  order: -1; width: min(390px, calc(100vw - 32px)); height: min(540px, calc(100vh - 120px));
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--carte); border-radius: var(--rayon); box-shadow: var(--ombre-haute);
  border: 1px solid var(--bordure);
}
.assistant-panneau[hidden] { display: none; }
.assistant-tete { display: flex; justify-content: space-between; gap: .5rem; align-items: center; padding: .85rem 1rem; background: var(--accent-pale); border-bottom: 1px solid var(--accent-trait); }
.assistant-tete strong { display: block; color: var(--accent-fort); }
.assistant-tete .muted { font-size: .8rem; }
.assistant-actions { display: flex; gap: .35rem; align-items: center; }
.assistant-actions button { border: 0; background: none; cursor: pointer; color: var(--texte-doux); font-size: .8rem; padding: .3rem .45rem; border-radius: 6px; }
.assistant-actions .assistant-fermer { font-size: 1.3rem; line-height: 1; }
.assistant-actions button:hover { background: var(--carte); color: var(--texte); }
.assistant-fil { flex: 1; overflow-y: auto; padding: 1rem; display: flex; flex-direction: column; gap: .6rem; }
.assistant-message { max-width: 88%; padding: .6rem .8rem; border-radius: 12px; font-size: .9rem; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
.assistant-message.question { align-self: flex-end; background: var(--accent); color: #fff; border-bottom-right-radius: 4px; }
.assistant-message.reponse { align-self: flex-start; background: var(--fond); color: var(--texte); border-bottom-left-radius: 4px; }
.assistant-message.info { color: var(--texte-doux); }
.assistant-message.attente { color: var(--texte-doux); animation: assistant-pulse 1.2s ease-in-out infinite; }
.assistant-message.echec { background: var(--rouge-pale); color: var(--rouge); }
@keyframes assistant-pulse { 50% { opacity: .45; } }
.assistant-formulaire { display: flex; gap: .5rem; padding: .75rem; border-top: 1px solid var(--bordure); }
.assistant-formulaire textarea { flex: 1; resize: none; min-height: 2.6rem; font: inherit; font-size: .9rem; }
.assistant-formulaire button { border: 0; border-radius: var(--rayon-petit); padding: 0 .9rem; background: var(--accent); color: #fff; font-weight: 700; cursor: pointer; }
.assistant-formulaire button:disabled { opacity: .5; cursor: default; }
@media (max-width: 600px) { .assistant { right: 12px; bottom: 12px; } }
@media print { .assistant { display: none; } }

/* --- L'agent CEO (25/09/2026) --------------------------------------------
   Il réutilise le panneau de l'assistant — même fil, mêmes bulles, même
   formulaire — et n'en change que deux choses : il s'ouvre **en bas à gauche**,
   contre la barre latérale d'où on le déclenche, et il est plus large parce
   qu'on y lit des chiffres et des listes, pas une phrase.

   Deux feuilles pour le même panneau finiraient par ne plus se ressembler ;
   c'est le raisonnement qui a gardé une seule feuille pour Prospecto et
   Messages. */
.ceo { right: auto; left: 20px; align-items: flex-start; }
.ceo .assistant-panneau { width: min(460px, calc(100vw - 32px)); height: min(620px, calc(100vh - 100px)); }
.ceo .assistant-tete { background: var(--violet-pale, var(--accent-pale)); }
.ceo .assistant-actions a { font-size: .8rem; padding: .3rem .45rem; border-radius: 6px; color: var(--texte-doux); }
.ceo .assistant-actions a:hover { background: var(--carte); color: var(--texte); }
/* Le point du vendredi ou du lundi : une question que personne n'a posée. Il se
   range du côté des questions mais s'en distingue, sinon on le lirait comme
   quelque chose qu'on a tapé soi-même.

   **Nommée `ceo-point` et non `point`** : `.point` existe depuis le 15/09/2026,
   c'est la pastille de température de Clients — un rond de .45rem de côté. La
   première version écrasait la bulle à cette taille-là, texte débordant
   par-dessus le message suivant. Trouvé sur une capture puis mesuré (19 px de
   haut pour 72 px de contenu) ; aucun test ne pouvait le voir, ils ne rendent
   pas de CSS. Un nom de classe générique se réserve à ce qui l'a pris. */
.ceo .assistant-message.ceo-point { background: var(--accent-fort); opacity: .92; font-style: italic; }
@media (max-width: 600px) { .ceo { left: 12px; right: 12px; } .ceo .assistant-panneau { width: auto; } }

/* La carte de la barre latérale qui l'ouvre, à la place de la carte d'espace.
   Même boîte que `.workspace` — elle occupe la même place — mais cliquable, et
   marquée du violet de l'agent pour qu'elle ne se lise pas comme un libellé. */
.ceo-carte {
  width: calc(100% - 4px); cursor: pointer; text-align: left; font: inherit;
  border-color: rgba(147, 124, 255, .35); background: rgba(147, 124, 255, .1);
}
.ceo-carte:hover { background: rgba(147, 124, 255, .18); }
.ceo-carte .avatar { background: linear-gradient(135deg, var(--violet-marque), var(--violet-fonce)); color: #fff; }
.ceo-carte .grow { min-width: 0; }

/* L'écran de sa mémoire. */
.ceo-memoire li { display: flex; flex-direction: column; gap: .5rem; }
.ceo-note { display: grid; gap: .5rem; }
.ceo-note-tete { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin: 0; }
.ceo-note textarea, .ceo-note input[type="text"] { width: 100%; font: inherit; font-size: .9rem; }

/* L'écran « Assistant » du propriétaire. */
.assistant-conversations li .echange { margin: .5rem 0 0; }
.assistant-conversations .q { font-weight: 600; }
.assistant-conversations .r { color: var(--texte-doux); white-space: pre-wrap; margin: .2rem 0 .6rem; }
.assistant-conversations .r.echec { color: var(--rouge); }
.guide-assistant { white-space: pre-wrap; font-size: .85rem; max-height: 28rem; overflow: auto; background: var(--fond); padding: 1rem; border-radius: var(--rayon-petit); }

/* --- « Un commentaire ou un problème ? » (17/09/2026) --------------------- */
.retour-topbar { position: relative; }
.retour-topbar > summary {
  list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 12px; border-radius: 8px; font-size: 12px; font-weight: 600;
  color: var(--accent-fort); background: var(--accent-pale); border: 1px solid var(--accent-trait);
  white-space: nowrap;
}
.retour-topbar > summary::-webkit-details-marker { display: none; }
.retour-topbar > summary:hover, .retour-topbar[open] > summary { background: var(--accent); color: #fff; border-color: var(--accent); }
.retour-panneau {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 50;
  width: min(340px, calc(100vw - 24px)); display: grid; gap: .6rem;
  padding: 1rem; background: var(--carte); border: 1px solid var(--bordure);
  border-radius: var(--rayon); box-shadow: var(--ombre-haute);
}
.retour-panneau p { margin: 0; font-size: .85rem; }
.retour-genres { display: grid; gap: .35rem; font-size: .9rem; }
.retour-genres label { display: flex; gap: .45rem; align-items: center; cursor: pointer; }
.retour-genres input { width: auto; margin: 0; accent-color: var(--accent); }
.retour-panneau textarea { width: 100%; resize: vertical; font: inherit; font-size: .9rem; }
.retour-pied { display: flex; justify-content: space-between; align-items: center; gap: .5rem; }
.retour-pied .retour-etat { font-size: .8rem; }
.retour-pied button { border: 0; border-radius: var(--rayon-petit); padding: .5rem 1rem; background: var(--accent); color: #fff; font-weight: 700; cursor: pointer; }
.compteur-menu { display: inline-block; min-width: 1.3em; padding: 0 .4em; border-radius: 999px; background: var(--rouge); color: #fff; font-size: .72rem; font-weight: 700; line-height: 1.5; text-align: center; margin-left: .3rem; }
.liste-retours li.probleme { border-left-color: var(--rouge); }
.liste-retours li.amelioration { border-left-color: var(--accent); }
.liste-retours .tete { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.liste-retours .retour-message { white-space: pre-wrap; margin: .6rem 0; }
@media (max-width: 900px) { .retour-topbar .retour-libelle { display: none; } }

/* --- La file d'appel de Prospecto 2 (17/09/2026) -------------------------- */
.liste-appels-refonte li.haute { border-left-color: var(--rouge); }
.liste-appels-refonte li.moyenne { border-left-color: var(--ambre); }
.liste-appels-refonte .tete { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
/* **Les captures se dessinent pareil partout** (24/09/2026) : ces règles
   étaient préfixées par l'écran « À appeler », si bien que les mêmes images
   posées sur la fiche sortaient en pleine largeur avec leur libellé à côté.
   Le bloc vit maintenant dans `_bilan_site.html`, donc son style aussi. */
.captures { display: flex; gap: 1rem; margin: .8rem 0; flex-wrap: wrap; }
.captures a { display: grid; gap: .25rem; justify-items: center; font-size: .75rem; text-decoration: none; }
.captures img { width: 300px; max-width: 100%; height: 190px; object-fit: cover; object-position: top;
  border: 1px solid var(--bordure); border-radius: var(--rayon-petit); background: var(--carte); }
.captures img.mobile { width: 110px; height: 190px; }
.liste-appels-refonte .scores-audit dd { font-size: 1.05rem; }
.motifs-appel { margin: .6rem 0; padding-left: 1.1rem; font-size: .9rem; }
.motifs-appel li { margin: .15rem 0; }
/* Les six scores en une bande compacte, et non six lignes pleine largeur. */
.liste-appels-refonte dl.scores-audit {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  gap: .5rem; margin: .8rem 0; padding: .8rem; background: var(--fond);
  border-radius: var(--rayon-petit); box-shadow: none;
}
.liste-appels-refonte dl.scores-audit > div { padding: 0; background: none; box-shadow: none; border: 0; text-align: center; }
.liste-appels-refonte dl.scores-audit dt { font-size: .72rem; text-transform: uppercase; letter-spacing: .03em; color: var(--texte-doux); }
.liste-appels-refonte dl.scores-audit dd { margin: .1rem 0 0; font-size: 1.15rem; font-weight: 700; }
/* Les motifs sont une liste, pas des cartes : `ol.prospects li` ne doit pas
   habiller les puces imbriquées. */
.liste-appels-refonte .motifs-appel li {
  padding: 0; margin: .2rem 0; background: none; box-shadow: none; border: 0;
  border-radius: 0; display: list-item; list-style: disc;
}
.liste-appels-refonte dl.scores-audit > div { display: grid; gap: 0; }
/* Un rendez-vous décroché depuis Prospecto 2 : cyan, la couleur d'appui de la
   charte. Ni vert, ni ambre, ni rouge — une provenance n'est pas un état. */
table.calendrier .case.rdv-refonte { color: var(--navy); background: #d9f1fa; }
.badge.cyan { color: var(--navy); background: #d9f1fa; }
ol.prospects li.rdv { border-left-color: var(--vert); }

/* --- Le no-show et « pas maintenant » sur la fiche (18/09/2026) -----------
   « Plus visible et plus design. » Deux cartes de la même famille : un
   pictogramme dans une pastille, un texte qui dit la situation, un bouton plein
   en pilule. Rouge pour le no-show (un problème qu'on compte), ambre pour « pas
   maintenant » (une affaire en attente, pas perdue). */
.carte-no-show,
.carte-pas-maintenant > summary,
.carte-pas-maintenant.rangee {
  display: flex; align-items: center; gap: 1rem;
  padding: 1rem 1.15rem;
  border-radius: var(--rayon);
  background: var(--carte);
  box-shadow: var(--ombre);
}
.carte-no-show { margin: .9rem 0; border: 1px solid var(--rouge-trait); }
.carte-no-show.notee { background: var(--rouge-pale); }
.carte-no-show .texte,
.carte-pas-maintenant .texte { flex: 1; display: grid; gap: .2rem; min-width: 0; }
.carte-no-show .texte span,
.carte-pas-maintenant summary .texte span { color: var(--texte-doux); font-size: .92rem; }
.carte-no-show form { margin: 0; }
.pictogramme {
  flex: none; display: grid; place-items: center;
  width: 2.75rem; height: 2.75rem; border-radius: 50%;
}
.carte-no-show .pictogramme { background: var(--rouge-pale); color: var(--rouge); }
.carte-pas-maintenant .pictogramme { background: var(--ambre-pale); color: var(--ambre); }
.bouton-no-show, .bouton-pas-maintenant {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .7rem 1.25rem; border: 0; border-radius: 999px;
  color: #fff; font-weight: 700; font-size: .95rem; cursor: pointer; white-space: nowrap;
  transition: transform .12s ease, box-shadow .12s ease;
}
.bouton-no-show {
  background: linear-gradient(135deg, #d0525d, var(--rouge));
  box-shadow: 0 8px 20px -8px rgba(176, 66, 76, .6);
}
.bouton-no-show.annuler { background: var(--carte); color: var(--rouge); box-shadow: inset 0 0 0 1px var(--rouge-trait); }
.bouton-pas-maintenant {
  background: linear-gradient(135deg, #d08a24, var(--ambre));
  box-shadow: 0 8px 20px -8px rgba(167, 105, 19, .6);
}
.bouton-no-show:hover, .bouton-pas-maintenant:hover { transform: translateY(-1px); }

.carte-pas-maintenant { margin: 0 0 1.75rem; }
.carte-pas-maintenant > summary { list-style: none; cursor: pointer; border: 1px solid var(--ambre-trait); }
.carte-pas-maintenant > summary::-webkit-details-marker { display: none; }
.carte-pas-maintenant[open] > summary { border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.carte-pas-maintenant[open] > summary .bouton-pas-maintenant { display: none; }
.carte-pas-maintenant > form {
  display: grid; gap: 1rem;
  padding: 1.1rem 1.15rem 1.25rem;
  background: var(--ambre-pale);
  border: 1px solid var(--ambre-trait); border-top: 0;
  border-radius: 0 0 var(--rayon) var(--rayon);
}
.dans-combien { border: 0; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.dans-combien legend { font-weight: 700; margin-bottom: .5rem; }
.dans-combien label input[type=radio] { position: absolute; opacity: 0; pointer-events: none; }
.dans-combien label span {
  display: inline-block; padding: .5rem 1rem; border-radius: 999px;
  background: var(--carte); border: 1px solid var(--ambre-trait); cursor: pointer; font-weight: 600;
}
.dans-combien label input:checked + span { background: var(--ambre); border-color: var(--ambre); color: #fff; }
.dans-combien label input:focus-visible + span { outline: 3px solid var(--ambre-trait); }
.dans-combien .date-precise { color: var(--texte-doux); display: inline-flex; gap: .4rem; align-items: center; }
.ce-qu-il-a-dit { display: grid; gap: .35rem; font-weight: 700; }
.ce-qu-il-a-dit textarea { width: 100%; font-weight: 400; }
.carte-pas-maintenant > form .bouton-pas-maintenant { justify-self: start; }

.carte-pas-maintenant.rangee { align-items: flex-start; background: var(--ambre-pale); border: 1px solid var(--ambre-trait); }
.carte-pas-maintenant.rangee .surtitre {
  font-size: .72rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ambre);
}
.carte-pas-maintenant.rangee strong { font-size: 1.1rem; }
.carte-pas-maintenant.rangee blockquote { margin: .2rem 0; font-style: italic; }
.carte-pas-maintenant.rangee .gestes { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: .5rem; }
.carte-pas-maintenant.rangee .gestes form { display: flex; gap: .4rem; align-items: center; margin: 0; }

@media (max-width: 640px) {
  .carte-no-show, .carte-pas-maintenant > summary { flex-wrap: wrap; }
  .bouton-no-show, .bouton-pas-maintenant { width: 100%; justify-content: center; }
}
.bouton-no-show.petit { padding: .45rem .9rem; font-size: .85rem; }
.deplacer-rdv { margin: .6rem 0; } .deplacer-rdv > summary { list-style: none; display: inline-flex; align-items: center; gap: .4rem; cursor: pointer; } .deplacer-rdv > summary::-webkit-details-marker { display: none; } .deplacer-rdv form { margin-top: .6rem; }

/* --- L'historique de la fiche (18/09/2026) --------------------------------
   Une ligne par geste : une pastille qui dit le genre (sa couleur est celle de
   la famille : violet l'appel, cyan le SMS, vert le rendez-vous et la vente,
   ambre la relance et le « plus tard », rouge la liste noire), le texte, la
   date à droite. */
.historique-actions { margin: 1.5rem 0; }
.actions-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: .1rem; }
.actions-liste li {
  display: grid; grid-template-columns:6.2rem minmax(0,1fr) auto; gap: .8rem; align-items: baseline;
  padding: .6rem 0; border-bottom: 1px solid var(--trait, #eceef4);
}
.actions-liste li:last-child { border-bottom: 0; }
.pastille-action {
  justify-self: start; font-size: .72rem; font-weight: 700; letter-spacing: .04em;
  padding: .2rem .55rem; border-radius: 999px; background: var(--accent-pale); color: var(--accent);
}
.action-sms .pastille-action { background: #e6f4fa; color: #1f7ea3; }
.action-rdv .pastille-action, .action-vente .pastille-action { background: var(--vert-pale, #e8f6ee); color: var(--vert); }
.action-relance .pastille-action, .action-plus_tard .pastille-action { background: var(--ambre-pale); color: var(--ambre); }
.action-liste_noire .pastille-action { background: var(--rouge-pale); color: var(--rouge); }
.action-site .pastille-action { background: var(--violet-pale); color: var(--violet); }
.action-corps { display: grid; gap: .15rem; min-width: 0; }
.action-detail { color: var(--texte-doux); font-size: .9rem; overflow-wrap: anywhere; }
.action-quand { white-space: nowrap; }
.historique-actions details summary { cursor: pointer; color: var(--accent); margin-top: .6rem; }
@media (max-width: 640px) {
  .actions-liste li { grid-template-columns:minmax(0,1fr); gap: .25rem; }
}
/* Sur la fiche, « Classer sans suite » et la date de relance (18/09/2026) :
   le blanc des boutons d'issue rendait le bouton discret invisible. */
.qualifier-boutons > form > button.discret,
.qualifier-boutons > form > button.bouton.discret {
  background: var(--carte); color: var(--texte-doux); font-weight: 600;
  box-shadow: inset 0 0 0 1px var(--accent-trait);
}
.suivi-fiche .marquer-relance { display: inline-flex; align-items: center; gap: .5rem; flex-wrap: wrap; }
.suivi-fiche .dit { margin: .2rem 0 .8rem; }

/* --- Confier une fiche, et le paiement replié (21/09/2026) ----------------
   « Confier doit devenir un bouton à part entière, bien visible » : la même
   carte que le no-show et « pas maintenant », en violet — c'est une commande,
   pas un état. */
.carte-confier {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  margin: 1.25rem 0; padding: 1rem 1.15rem;
  border-radius: var(--rayon); background: var(--carte);
  border: 1px solid var(--accent-trait); box-shadow: var(--ombre);
}
.carte-confier .pictogramme { background: var(--accent-pale); color: var(--accent); }
.carte-confier .texte { flex: 1; display: grid; gap: .2rem; min-width: 12rem; }
.carte-confier .texte span { color: var(--texte-doux); font-size: .92rem; }
.carte-confier select { min-width: 10rem; }
.bouton-confier {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .7rem 1.35rem; border: 0; border-radius: 999px;
  background: linear-gradient(135deg, var(--violet-marque), var(--violet-fonce));
  color: #fff; font-weight: 700; cursor: pointer; white-space: nowrap;
  box-shadow: 0 8px 20px -8px rgba(91, 61, 240, .55);
  transition: transform .12s ease;
}
.bouton-confier:hover { transform: translateY(-1px); }

/* Le paiement ne se déplie qu'à la vente : un formulaire de prix ouvert sur
   chaque fiche, c'est le plus long des blocs pour le geste le plus rare. */
details.case-paiement > summary {
  display: flex; align-items: center; gap: .5rem;
  list-style: none; cursor: pointer; font-weight: 700;
}
details.case-paiement > summary::-webkit-details-marker { display: none; }
details.case-paiement > summary:hover { color: var(--accent); }
@media (max-width: 640px) {
  .carte-confier { flex-direction: column; align-items: stretch; }
  .bouton-confier { justify-content: center; }
}

/* --- Le bilan de son site (21/09/2026) -------------------------------------
   « Le score de manière très claire, et les points qui ne vont pas. » Un grand
   chiffre dans une pastille aux couleurs de la priorité — rouge quand il y a
   beaucoup à refaire, puisque c'est là que la vente se fait —, une phrase qui
   dit comment le lire, puis les défauts en liste à croix rouges. */
.bilan-site {
  margin: 1.1rem 0 1.5rem; padding: 1.2rem 1.3rem;
  border-radius: var(--rayon); background: var(--carte); box-shadow: var(--ombre);
  border: 1px solid var(--accent-trait); border-left: 5px solid var(--texte-doux);
}
.bilan-site.haute { border-left-color: var(--rouge); }
.bilan-site.moyenne { border-left-color: var(--ambre); }
.bilan-tete { display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap; }
.bilan-score {
  display: grid; place-items: center; width: 6rem; height: 6rem; border-radius: 50%;
  background: var(--accent-pale); color: var(--texte-doux); flex: none; line-height: 1;
}
.bilan-site.haute .bilan-score { background: var(--rouge-pale); color: var(--rouge); }
.bilan-site.moyenne .bilan-score { background: var(--ambre-pale); color: var(--ambre); }
.bilan-score .chiffre { font-size: 2.4rem; font-weight: 800; }
.bilan-score .sur { font-size: .8rem; font-weight: 600; margin-top: -.9rem; }
.bilan-lecture { display: grid; gap: .25rem; flex: 1; min-width: 14rem; }
.bilan-lecture .surtitre {
  font-size: .72rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--texte-doux);
}
.bilan-lecture strong { font-size: 1.15rem; }
.bilan-titre { font-size: .95rem; margin: 1.1rem 0 .5rem; }
.bilan-defauts { list-style: none; margin: 0; padding: 0; display: grid; gap: .45rem; }
.bilan-defauts li {
  display: flex; gap: .6rem; align-items: baseline;
  padding: .55rem .75rem; border-radius: var(--rayon-petit); background: var(--rouge-pale);
}
.bilan-defauts .croix { color: var(--rouge); font-weight: 800; }
.notes-google { display: flex; flex-wrap: wrap; gap: 1rem 1.4rem; }
.note-google { display: grid; justify-items: center; gap: .35rem; width: 6.5rem; text-align: center; }
.note-google .anneau {
  --couleur: var(--texte-doux);
  display: grid; place-items: center; width: 3.6rem; height: 3.6rem; border-radius: 50%;
  background: conic-gradient(var(--couleur) calc(var(--valeur) * 1%), var(--accent-pale) 0);
}
.note-google .anneau b {
  display: grid; place-items: center; width: 2.8rem; height: 2.8rem; border-radius: 50%;
  background: var(--carte); color: var(--couleur); font-size: 1rem;
}
.note-google.vert .anneau { --couleur: var(--vert); }
.note-google.ambre .anneau { --couleur: var(--ambre); }
.note-google.rouge .anneau { --couleur: var(--rouge); }
.note-google .libelle { font-size: .78rem; color: var(--texte-doux); line-height: 1.2; }
.bilan-avis { font-style: italic; margin: .8rem 0 0; color: var(--texte-doux); }
.bilan-portes { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: .45rem; }
.bilan-portes li {
  display: inline-flex; gap: .4rem; align-items: center;
  padding: .35rem .75rem; border-radius: 999px; font-size: .88rem; font-weight: 600;
}
.bilan-portes li.oui { background: var(--vert-pale); color: var(--vert); }
.bilan-portes li.non { background: var(--rouge-pale); color: var(--rouge); }
@media (max-width: 640px) {
  .bilan-score { width: 4.8rem; height: 4.8rem; }
  .bilan-score .chiffre { font-size: 1.9rem; }
}

/* La note de la fiche sur l'écran d'appel (22/09/2026) : lue avant de composer. */
.note-appel {
  margin: 10px 0 4px;
  padding: 10px 14px;
  border-left: 3px solid var(--ambre);
  background: var(--carte);
  border-radius: 8px;
}
.note-appel .dit { margin: 4px 0 0; white-space: pre-line; }
.note-en-tete textarea { width: 100%; }

/* L'équipe, volet par volet (22/09/2026) : un tableau de chiffres qu'on lit en
   ligne (une personne) et en colonne (un volet). Défile sur téléphone. */
.equipe-volets .defilement, .journees .defilement { overflow-x: auto; }
.journees h3 { margin: 26px 0 4px; font-size: 1rem; }
.journees h4 { margin: 14px 0 0; font-size: .92rem; }
.journees-heures { margin-top: 10px; }
.journees-heures summary { cursor: pointer; font-weight: 600; font-size: .9rem; }
.journees-du-mois { margin-top: 10px; }
.journees-du-mois summary { cursor: pointer; font-weight: 600; font-size: .9rem; }
.journees-du-mois .defilement { overflow-x: auto; margin-top: 8px; }
table.equipe { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
table.equipe th, table.equipe td { padding: 7px 9px; text-align: right; white-space: nowrap;
  border-bottom: 1px solid var(--bordure); }
table.equipe th { font-size: .78rem; color: var(--texte-doux); font-weight: 600; }
table.equipe th.groupe { text-align: center; border-bottom: 2px solid var(--bordure); }
table.equipe .nom { text-align: left; font-weight: 600; }
table.equipe .debut-groupe { border-left: 1px solid var(--bordure); }
table.equipe td.zero { color: var(--texte-doux); opacity: .55; }
table.equipe td.fort { font-weight: 700; color: var(--vert); }
table.equipe tfoot td { font-weight: 700; border-bottom: 0; }

/* Fixer un rendez-vous depuis la fiche (22/09/2026). */
.fixer-rdv > summary { display: inline-flex; margin-bottom: 10px; }
.fixer-rdv form.vente { flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.fixer-rdv .grandir { flex: 1 1 14rem; }
