/* =========================================================
   DoctoCRM — un produit Opticontact
   Palette dérivée du logo : bleu #375DD3, turquoise #20C6C6,
   bleu clair #5B6EF5 (couleur de thème du site opticontact.fr).
   ========================================================= */

:root {
  /* Marque */
  --bleu:        #375dd3;
  --bleu-vif:    #5b6ef5;
  --bleu-fonce:  #2a46a4;
  --turquoise:   #20c6c6;
  --turquoise-f: #149a9a;

  /* Neutres froids, teintés vers le bleu de marque */
  --canvas:      #eef1f9;
  --canvas-deep: #dde3f2;
  --ink:         #101a33;
  --ink-soft:    #3a466b;
  --muted:       #6f7b9c;
  --line:        rgba(16, 26, 51, .10);

  /* Verre */
  --glass:        rgba(255, 255, 255, .60);
  --glass-strong: rgba(255, 255, 255, .80);
  --glass-edge:   rgba(255, 255, 255, .74);
  --glass-shadow: 0 14px 44px -20px rgba(16, 26, 51, .40);

  /* Les lignes de la liste sont du papier posé sur le verre : on y lit des
     coordonnées et des statuts, pas une ambiance. Elles restent donc bien
     plus opaques que les panneaux qui les entourent. */
  --ligne-fond:        rgba(255, 255, 255, .92);
  --ligne-fond-survol: rgba(255, 255, 255, .99);

  /* Hauteur de la barre supérieure. Le rail des filtres et l'en-tête de la
     liste s'y accrochent tous les deux : une seule valeur les garde alignés. */
  --dessous-barre: 84px;

  /* Rôles */
  --accent:      var(--bleu);
  --accent-ink:  var(--bleu-fonce);
  --accent-2:    var(--turquoise);
  --danger:      #b1332f;
  --warn:        #a06a08;
  --ok:          #10795d;

  --radius:    18px;
  --radius-sm: 11px;

  --display: 'Bricolage Grotesque', system-ui, sans-serif;
  --body: 'IBM Plex Sans', system-ui, -apple-system, sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, monospace;
}

* { -webkit-tap-highlight-color: transparent; }
/* min-height et non height : un élément collant ne colle que dans les limites
   de son bloc conteneur. Avec height: 100%, le <body> mesurait une hauteur
   d'écran et la barre supérieure repartait avec la page dès le premier écran
   franchi — elle était bien en sticky, mais dans une boîte trop courte. */
html, body { min-height: 100%; }

body {
  font-family: var(--body);
  color: var(--ink);
  background: var(--canvas);
  /* clip plutôt que hidden : hidden fait du <body> un conteneur de défilement
     dans plusieurs moteurs, ce qui casse position:sticky sur ses descendants.
     clip découpe sans créer de conteneur. La ligne hidden reste en repli. */
  overflow-x: hidden;
  overflow-x: clip;
  font-size: 15px;
}

/* Halos d'ambiance : ce sont eux qui donnent sa matière au verre. */
.ambiance {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  background: linear-gradient(158deg, var(--canvas) 0%, var(--canvas-deep) 100%);
}
.ambiance span {
  position: absolute;
  border-radius: 50%;
  filter: blur(96px);
}
.ambiance span:nth-child(1) { width: 46vw; height: 46vw; left: -9vw;  top: -13vw;    background: var(--turquoise); opacity: .40; }
.ambiance span:nth-child(2) { width: 40vw; height: 40vw; right: -7vw; top: 4vh;      background: var(--bleu-vif);  opacity: .34; }
.ambiance span:nth-child(3) { width: 34vw; height: 34vw; left: 32vw;  bottom: -16vw; background: var(--bleu);      opacity: .18; }

/* ------------------------------- Verre ----------------------------------- */

/* backdrop-filter crée un contexte d'empilement : tout z-index posé à
   l'intérieur d'un .glass y reste enfermé. C'est pourquoi les panneaux
   déroulants sont élevés au niveau de leur conteneur, jamais du panneau. */
.glass {
  background: var(--glass);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius);
  box-shadow: var(--glass-shadow);
}

/* ----------------------------- Typographie ------------------------------- */

.titre-section {
  font-size: .68rem;
  font-weight: 600;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 .55rem;
}

.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* ------------------------------- Marque ---------------------------------- */

.logo-opticontact { display: block; height: 28px; width: auto; }
.logo-opticontact.grand { height: 46px; }

.marque {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  text-decoration: none;
  color: inherit;
}
/* Le nom du sous-produit, discret à côté du logo de la marque mère. */
.marque .sous-produit {
  font-family: var(--display);
  font-weight: 600;
  font-size: .82rem;
  letter-spacing: .02em;
  color: var(--muted);
  padding-left: .55rem;
  border-left: 1px solid var(--line);
  white-space: nowrap;
}

/* --------------------------- Barre supérieure ---------------------------- */

.barre {
  position: sticky;
  top: 0;
  z-index: 1030;
  margin: 0;
  border-radius: 0;
  border-left: 0;
  border-right: 0;
  border-top: 0;
  background: rgba(255, 255, 255, .66);
}

.recherche { position: relative; flex: 1 1 auto; max-width: 480px; }
.recherche i {
  position: absolute;
  left: .85rem;
  top: 50%;
  transform: translateY(-50%);
  color: var(--muted);
  font-size: .85rem;
  pointer-events: none;
}
.recherche input {
  width: 100%;
  padding: .55rem .85rem .55rem 2.2rem;
  border-radius: 100px;
  border: 1px solid var(--glass-edge);
  background: rgba(255, 255, 255, .72);
  color: var(--ink);
  font-size: .92rem;
}
.recherche input::placeholder { color: var(--muted); }
.recherche input:focus {
  outline: 2px solid rgba(55, 93, 211, .35);
  outline-offset: 1px;
  background: #fff;
}

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

.btn-verre, .btn-plein {
  border-radius: 100px;
  font-size: .85rem;
  font-weight: 500;
  padding: .42rem .9rem;
  border: 1px solid var(--glass-edge);
  transition: transform .12s ease, background .12s ease, box-shadow .12s ease;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .35rem;
}
.btn-verre { background: rgba(255, 255, 255, .58); color: var(--ink-soft); }
.btn-verre:hover { background: #fff; color: var(--ink); }
.btn-plein {
  background: var(--bleu);
  border-color: var(--bleu);
  color: #fff;
  box-shadow: 0 6px 18px -8px rgba(55, 93, 211, .8);
}
.btn-plein:hover { background: var(--bleu-fonce); color: #fff; }
.btn-verre:active, .btn-plein:active { transform: translateY(1px); }
.btn-verre:focus-visible, .btn-plein:focus-visible {
  outline: 2px solid var(--turquoise);
  outline-offset: 2px;
}

.icone-btn {
  width: 30px; height: 30px;
  display: grid;
  place-items: center;
  border-radius: 9px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--muted);
  font-size: .82rem;
  text-decoration: none;
  flex: none;
}
.icone-btn:hover { background: rgba(255, 255, 255, .9); color: var(--bleu); border-color: var(--glass-edge); }
.icone-btn.danger:hover { color: var(--danger); }
.icone-btn.arme { background: var(--danger); color: #fff; border-color: var(--danger); }
.icone-btn:focus-visible { outline: 2px solid var(--turquoise); outline-offset: 2px; }

/* ------------------------------ Cases à cocher ---------------------------- */

/* Une case de 13 px est une cible dérisoire quand on en coche cinquante à la
   suite. On redessine donc la case native : la coche est une image de fond
   plutôt qu'un pseudo-élément, seule forme qui tienne dans tous les moteurs
   sur un <input>. */
input[type="checkbox"].case {
  appearance: none;
  -webkit-appearance: none;
  width: 21px;
  height: 21px;
  margin: 0;
  flex: none;
  border-radius: 7px;
  border: 1.5px solid rgba(16, 26, 51, .24);
  background-color: rgba(255, 255, 255, .92);
  background-repeat: no-repeat;
  background-position: center;
  background-size: 14px 14px;
  cursor: pointer;
  transition: background-color .12s ease, border-color .12s ease, transform .1s ease;
}
input[type="checkbox"].case:hover { border-color: var(--bleu); }
input[type="checkbox"].case:active { transform: scale(.9); }
input[type="checkbox"].case:focus-visible { outline: 2px solid var(--turquoise); outline-offset: 2px; }

input[type="checkbox"].case:checked,
input[type="checkbox"].case:indeterminate {
  background-color: var(--bleu);
  border-color: var(--bleu);
}
input[type="checkbox"].case:checked {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23ffffff' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.2 8.4l3.3 3.3 6.3-6.9'/%3E%3C/svg%3E");
}
input[type="checkbox"].case:indeterminate {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' stroke='%23ffffff' stroke-width='2.6' stroke-linecap='round'%3E%3Cpath d='M4 8h8'/%3E%3C/svg%3E");
}
input[type="checkbox"].case:disabled {
  opacity: .4;
  cursor: default;
  border-color: rgba(16, 26, 51, .16);
}

/* --------------------------- Panneau de filtres -------------------------- */

.rail {
  padding: 1rem;
  position: sticky;
  top: var(--dessous-barre);
  max-height: calc(100vh - var(--dessous-barre) - 20px);
  overflow-y: auto;
  scrollbar-width: thin;
}

/* En-tête collant du rail : compteur et actions restent toujours visibles. */
.rail-entete {
  position: sticky;
  top: -1rem;
  z-index: 5;
  margin: -1rem -1rem .9rem;
  padding: .85rem 1rem;
  background: rgba(255, 255, 255, .78);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
  border-radius: var(--radius) var(--radius) 0 0;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .5rem;
}
.rail-entete .intitule {
  font-family: var(--display);
  font-weight: 700;
  font-size: .95rem;
  letter-spacing: -.01em;
}
.compteur-filtres {
  font-size: .68rem;
  font-weight: 600;
  padding: .1rem .42rem;
  border-radius: 100px;
  background: var(--bleu);
  color: #fff;
}
.compteur-filtres.zero { background: rgba(16, 26, 51, .1); color: var(--muted); }

/* Les deux actions occupent leur propre ligne : le rail descend à ~190 px en
   xl, où « Mémoriser » et « Réinitialiser » ne tiendraient pas à côté du
   titre. Elles se replient l'une sous l'autre si la place manque encore. */
.rail-actions {
  display: flex;
  flex-wrap: wrap;
  gap: .35rem;
  width: 100%;
}
.rail-actions .btn-verre {
  flex: 1 1 96px;
  font-size: .76rem;
  padding: .3rem .55rem;
  white-space: nowrap;
}
#btn-reinit[disabled] { opacity: .4; pointer-events: none; }
#btn-memoire.memorise {
  background: var(--bleu);
  border-color: var(--bleu);
  color: #fff;
}
#btn-memoire.memorise:hover { background: var(--bleu-fonce); }

/* Chaque groupe est une carte à part entière. Un filet de séparation ne
   suffisait pas : dans une colonne haute où tout se ressemble, il faut une
   bordure fermée pour que « Suivi » se distingue de « Coordonnées ». */
.groupe-filtre {
  padding: .85rem .75rem .95rem;
  margin-bottom: .6rem;
  border: 1px solid rgba(255, 255, 255, .55);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, .44);
  transition: border-color .16s ease, background .16s ease;
}
.groupe-filtre:last-child { margin-bottom: 0; }
/* Un groupe qui filtre se détache du lot, sans avoir à lire son compteur. */
.groupe-filtre.actif {
  border-color: rgba(55, 93, 211, .34);
  background: rgba(255, 255, 255, .74);
}

/* L'intitulé porte deux informations plutôt qu'aucune : l'icône donne un
   repère de balayage dans une colonne haute, le compteur dit lesquels
   filtrent réellement. Sa taille et sa graisse doivent nettement dépasser
   celles des libellés de champ, sinon la hiérarchie s'aplatit et tout se
   lit comme une seule liste. */
.titre-groupe {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--display);
  font-size: .95rem;
  font-weight: 700;
  letter-spacing: -.018em;
  color: var(--ink);
  margin: 0 0 .85rem;
}
.titre-groupe i {
  width: 24px; height: 24px;
  display: grid;
  place-items: center;
  flex: none;
  border-radius: 8px;
  font-size: .7rem;
  color: var(--muted);
  background: rgba(16, 26, 51, .06);
  transition: background .16s ease, color .16s ease;
}
.groupe-filtre.actif .titre-groupe i {
  color: #fff;
  background: linear-gradient(135deg, var(--turquoise), var(--bleu));
}

.n-groupe {
  margin-left: auto;
  min-width: 19px;
  padding: 0 .3rem;
  text-align: center;
  font-family: var(--body);
  font-size: .66rem;
  font-weight: 600;
  line-height: 19px;
  border-radius: 100px;
  background: var(--bleu);
  color: #fff;
}
.n-groupe:empty { display: none; }

/* Volontairement discrets : c'est l'écart avec le titre de groupe qui rend
   la structure lisible. Le ton reste --ink-soft, jamais --muted, qui
   descendrait sous le seuil de contraste à cette taille. */
.rail label.form-label { font-size: .72rem; font-weight: 500; color: var(--ink-soft); margin-bottom: .3rem; }

.aide-filtre {
  font-size: .72rem;
  line-height: 1.35;
  color: var(--muted);
  margin: .55rem 0 0;
}

.rail .form-select, .rail .form-control {
  background: rgba(255, 255, 255, .72);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-sm);
  font-size: .86rem;
  color: var(--ink);
}
.rail .form-select:focus, .rail .form-control:focus {
  border-color: var(--bleu);
  box-shadow: 0 0 0 3px rgba(55, 93, 211, .16);
}

/* Sélecteur segmenté : « Tous / Avec / Sans ». Un filtre à trois états se lit
   d'un coup d'œil, là où deux cases à cocher laissaient l'utilisateur deviner
   ce que « ni l'une ni l'autre » signifie. */
.segment {
  display: flex;
  border: 1px solid var(--glass-edge);
  border-radius: 100px;
  background: rgba(255, 255, 255, .55);
  padding: 2px;
  gap: 2px;
  overflow: hidden;
}
.segment label {
  flex: 1;
  margin: 0;
  cursor: pointer;
  text-align: center;
}
.segment input { position: absolute; opacity: 0; pointer-events: none; }
.segment span {
  display: block;
  font-size: .76rem;
  line-height: 1.5;
  padding: .22rem .3rem;
  border-radius: 100px;
  color: var(--ink-soft);
  white-space: nowrap;
  transition: background .12s ease, color .12s ease;
}
.segment label:hover span { background: rgba(255, 255, 255, .9); }
.segment input:checked + span { background: var(--bleu); color: #fff; font-weight: 500; }
/* « Tous » sélectionné = absence de filtre : on le montre sans le mettre en avant. */
.segment label:first-child input:checked + span { background: rgba(16, 26, 51, .12); color: var(--ink-soft); }
.segment label:focus-within span { outline: 2px solid var(--turquoise); outline-offset: 1px; }

.bascules { display: flex; flex-wrap: wrap; gap: .35rem; }
.bascule {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  font-size: .78rem;
  padding: .3rem .6rem;
  border-radius: 100px;
  border: 1px solid var(--glass-edge);
  background: rgba(255, 255, 255, .55);
  color: var(--ink-soft);
  cursor: pointer;
  user-select: none;
}
.bascule input { display: none; }
.bascule:has(input:checked) { background: var(--bleu); border-color: var(--bleu); color: #fff; }
.bascule:focus-within { outline: 2px solid var(--turquoise); outline-offset: 2px; }

/* ------------------------ Sélecteur multiple maison ---------------------- */

.multi { position: relative; }

.multi-declencheur {
  width: 100%;
  display: flex;
  align-items: center;
  gap: .4rem;
  min-height: 36px;
  padding: .32rem .6rem;
  border-radius: var(--radius-sm);
  border: 1px solid var(--glass-edge);
  background: rgba(255, 255, 255, .72);
  color: var(--ink);
  font-size: .84rem;
  text-align: left;
  cursor: pointer;
}
.multi-declencheur:hover { background: #fff; }
.multi-declencheur:focus-visible { outline: 2px solid var(--bleu); outline-offset: 1px; }
.multi.ouvert .multi-declencheur { border-color: var(--bleu); box-shadow: 0 0 0 3px rgba(55, 93, 211, .16); }
.multi-declencheur .chevron { margin-left: auto; color: var(--muted); font-size: .7rem; transition: transform .15s ease; }
.multi.ouvert .multi-declencheur .chevron { transform: rotate(180deg); }
.multi-declencheur .vide { color: var(--muted); }

.multi-jetons { display: flex; flex-wrap: wrap; gap: .25rem; min-width: 0; }
.jeton {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  max-width: 100%;
  font-size: .74rem;
  line-height: 1.3;
  padding: .16rem .3rem .16rem .5rem;
  border-radius: 100px;
  background: rgba(55, 93, 211, .12);
  color: var(--bleu-fonce);
}
.jeton span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.jeton i { font-size: .62rem; opacity: .65; }
.jeton:hover i { opacity: 1; }
.jeton.reste { background: rgba(16, 26, 51, .08); color: var(--ink-soft); padding-right: .5rem; }

.multi-panneau {
  position: absolute;
  z-index: 1050;
  left: 0; right: 0;
  top: calc(100% + 4px);
  background: rgba(255, 255, 255, .96);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-sm);
  box-shadow: 0 18px 44px -18px rgba(16, 26, 51, .45);
  display: none;
  flex-direction: column;
  overflow: hidden;
}
.multi.ouvert .multi-panneau { display: flex; }

/* Bascule au-dessus du déclencheur quand le bas du rail est trop proche. */
.multi-panneau.vers-haut { top: auto; bottom: calc(100% + 4px); }

.multi-recherche {
  border: 0;
  border-bottom: 1px solid var(--line);
  padding: .5rem .7rem;
  font-size: .84rem;
  background: transparent;
  color: var(--ink);
}
.multi-recherche:focus { outline: none; background: rgba(55, 93, 211, .05); }

.multi-options { max-height: 240px; overflow-y: auto; padding: .3rem; scrollbar-width: thin; }
.multi-option {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .34rem .5rem;
  border-radius: 8px;
  font-size: .84rem;
  cursor: pointer;
  line-height: 1.25;
}
.multi-option:hover, .multi-option.survol { background: rgba(55, 93, 211, .09); }
/* La case est un témoin, pas une cible : tous les clics doivent atteindre le
   <label>. Sinon le navigateur coche la case, notre gestionnaire annule l'action
   par défaut, et l'annulation — qui survient APRÈS nos écouteurs — décoche ce
   que nous venions de cocher. La case restait vide alors que le jeton
   apparaissait. */
.multi-option input { accent-color: var(--bleu); flex: none; pointer-events: none; }
.multi-option .libelle { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.multi-option .n { font-size: .72rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.multi-option input:checked + .libelle { font-weight: 600; color: var(--bleu-fonce); }
.multi-vide { padding: .7rem; font-size: .82rem; color: var(--muted); text-align: center; }

.multi-pied {
  display: flex;
  gap: .5rem;
  padding: .45rem .6rem;
  border-top: 1px solid var(--line);
  font-size: .76rem;
}
.multi-pied button {
  border: 0;
  background: transparent;
  color: var(--bleu);
  padding: .12rem .2rem;
  font-size: .76rem;
  border-radius: 6px;
}
.multi-pied button:hover { background: rgba(55, 93, 211, .1); }
.multi-pied .decompte { margin-left: auto; color: var(--muted); }

/* ------------------------ Plage à deux poignées -------------------------- */

.duo { padding-top: .1rem; }

.duo-valeurs {
  display: flex;
  justify-content: space-between;
  gap: .5rem;
  margin-bottom: .4rem;
  font-size: .76rem;
  color: var(--muted);
}
.duo-v {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  transition: color .12s ease;
}
.duo.actif .duo-v { color: var(--bleu-fonce); font-weight: 500; }

.duo-rail { position: relative; height: 22px; }

.duo-piste {
  position: absolute;
  left: 0; right: 0; top: 9px;
  height: 4px;
  border-radius: 4px;
  background: rgba(16, 26, 51, .12);
}
.duo-segment {
  position: absolute;
  top: 9px;
  height: 4px;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--turquoise), var(--bleu));
}

/* pointer-events: none sur l'input, auto sur la seule poignée — sans quoi le
   curseur du dessus recouvre l'autre et le rend inatteignable. */
.duo-curseur {
  position: absolute;
  top: 0; left: 0;
  width: 100%;
  height: 22px;
  margin: 0;
  padding: 0;
  background: transparent;
  appearance: none;
  -webkit-appearance: none;
  pointer-events: none;
}
.duo-curseur:focus { outline: none; }

.duo-curseur::-webkit-slider-runnable-track { height: 22px; background: transparent; border: 0; }
.duo-curseur::-moz-range-track { height: 22px; background: transparent; border: 0; }

.duo-curseur::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  pointer-events: auto;
  width: 16px; height: 16px;
  margin-top: 3px;
  border-radius: 50%;
  background: #fff;
  border: 3px solid var(--bleu);
  box-shadow: 0 2px 6px -1px rgba(16, 26, 51, .35);
  cursor: grab;
}
.duo-curseur::-moz-range-thumb {
  pointer-events: auto;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: #fff;
  border: 3px solid var(--bleu);
  box-shadow: 0 2px 6px -1px rgba(16, 26, 51, .35);
  cursor: grab;
}
.duo-curseur:active::-webkit-slider-thumb { cursor: grabbing; border-color: var(--bleu-fonce); }
.duo-curseur:active::-moz-range-thumb { cursor: grabbing; border-color: var(--bleu-fonce); }
.duo-curseur:focus-visible::-webkit-slider-thumb { outline: 2px solid var(--turquoise); outline-offset: 2px; }
.duo-curseur:focus-visible::-moz-range-thumb { outline: 2px solid var(--turquoise); outline-offset: 2px; }

/* --------------------------------- Lignes -------------------------------- */

/* Élevé, mais pas collant : .glass enferme le z-index des menus qui s'y
   ouvrent, et chaque ligne — .glass elle aussi — forme son propre contexte
   peint plus tard. Sans ce z-index, les panneaux passaient sous la liste.
   La barre supérieure, elle, reste seule à l'écran en permanence. */
.entete-liste {
  position: relative;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  padding: .7rem 1rem;
  /* Nettement plus que l'écart entre deux lignes (.55rem), sinon l'en-tête
     se lit comme la première ligne du tableau. */
  margin-bottom: 1.1rem;
}
/* Même largeur que la première colonne d'une ligne : la case d'en-tête tombe
   exactement au-dessus de celles qu'elle commande. */
.tout-cocher { display: inline-flex; align-items: center; width: 34px; flex: none; }

.compteur { font-family: var(--display); font-size: 1.05rem; font-weight: 600; letter-spacing: -.01em; }
.compteur small { font-family: var(--body); font-weight: 400; color: var(--muted); font-size: .8rem; }

.jauge-selection {
  font-size: .78rem;
  font-weight: 600;
  color: var(--bleu-fonce);
  background: rgba(55, 93, 211, .12);
  padding: .24rem .62rem;
  border-radius: 100px;
  white-space: nowrap;
}

.liste { display: flex; flex-direction: column; gap: .55rem; }

.ligne {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) 190px 132px 150px 76px;
  gap: .85rem;
  align-items: center;
  padding: .8rem 1rem;
  cursor: pointer;
  /* background-color, pas le raccourci : la ligne sélectionnée pose un voile
     en background-image par-dessus. Avec le raccourci, le survol remettrait
     ce voile à zéro et la sélection disparaîtrait sous le curseur. */
  background-color: var(--ligne-fond);
  transition: transform .12s ease, box-shadow .12s ease, background-color .12s ease;
}
.ligne:hover {
  background-color: var(--ligne-fond-survol);
  transform: translateY(-1px);
  box-shadow: 0 16px 40px -20px rgba(16, 26, 51, .5);
}
.ligne.selectionnee {
  border-color: var(--bleu);
  background-image: linear-gradient(rgba(55, 93, 211, .07), rgba(55, 93, 211, .07));
}

/* La colonne entière coche la fiche : viser 21 px cinquante fois de suite est
   pénible. Le basculement est fait en JS, pas par un <label>. */
.c-case {
  align-self: stretch;
  display: flex;
  align-items: center;
  margin: -.8rem 0 -.8rem -1rem;
  padding: .8rem 0 .8rem 1rem;
}

.ligne-nom { font-weight: 600; font-size: .96rem; letter-spacing: -.01em; line-height: 1.25; }
.ligne-meta {
  font-size: .8rem;
  color: var(--muted);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .35rem .55rem;
  margin-top: .15rem;
}
/* Jamais vide : sinon la ligne se replie et devient plus courte que ses
   voisines. Voir la puce « absente » ci-dessous. */
.ligne-meta.expertises { min-height: 1.35rem; }

/* inline-flex : en pied de fiche, la puce d'alerte est un élément flex étiré
   à la hauteur des boutons voisins. Sans centrage interne, son texte restait
   plaqué en haut d'une pastille trop grande. */
.puce {
  display: inline-flex;
  align-items: center;
  font-size: .69rem;
  padding: .12rem .48rem;
  border-radius: 100px;
  background: rgba(32, 198, 198, .16);
  color: var(--turquoise-f);
  white-space: nowrap;
}
.puce.neutre { background: rgba(16, 26, 51, .07); color: var(--ink-soft); }
.puce.bleue { background: rgba(55, 93, 211, .12); color: var(--bleu-fonce); }
/* Une donnée manquante, pas une valeur : contour pointillé, jamais un aplat. */
.puce.absente {
  background: transparent;
  border: 1px dashed rgba(16, 26, 51, .18);
  color: #9aa6c2;
  font-style: italic;
}

.contact-ligne { font-size: .79rem; display: flex; flex-direction: column; gap: .18rem; min-width: 0; }
.contact-ligne span { display: flex; align-items: center; gap: .4rem; min-width: 0; }
.contact-ligne span > i { width: 12px; color: var(--muted); flex: none; font-size: .72rem; }
.contact-ligne .valeur { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.contact-ligne .vide { color: #9aa6c2; font-style: italic; }

/* Signature : l'horizon de disponibilité. Un rail = 90 jours. */
.horizon { --pos: 0%; position: relative; height: 26px; }
.horizon .rail-h {
  position: absolute;
  left: 0; right: 0; top: 15px;
  height: 3px;
  border-radius: 3px;
  background: linear-gradient(90deg, rgba(16, 121, 93, .55), rgba(160, 106, 8, .45), rgba(177, 51, 47, .30));
}
.horizon .point {
  position: absolute;
  top: 11px;
  left: var(--pos);
  width: 11px; height: 11px;
  margin-left: -5px;
  border-radius: 50%;
  background: #fff;
  border: 3px solid var(--ok);
}
.horizon.moyen .point { border-color: var(--warn); }
.horizon.long .point  { border-color: var(--danger); }
.horizon .jours { position: absolute; top: -2px; left: 0; font-size: .74rem; color: var(--ink-soft); }
.horizon.aucune .rail-h { background: rgba(16, 26, 51, .12); }
.horizon.aucune .point { display: none; }

/* Statuts */
.statut {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .76rem;
  font-weight: 500;
  padding: .26rem .6rem;
  border-radius: 100px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.statut::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.st-a-contacter      { background: rgba(111,123,156,.14); color: #545f80; }
.st-a-relancer       { background: rgba(160,106,8,.13);   color: #855808; }
.st-contacte         { background: rgba(91,110,245,.14);  color: #3d4dc4; }
.st-rdv-planifie     { background: rgba(129,73,196,.13);  color: #6b3ba8; }
.st-devis-envoye     { background: rgba(32,198,198,.18);  color: var(--turquoise-f); }
.st-client           { background: rgba(16,121,93,.15);   color: #0d6249; }
.st-non-interesse    { background: rgba(177,51,47,.12);   color: #92302c; }
.st-injoignable      { background: rgba(120,110,90,.15);  color: #6b6250; }
.st-ne-pas-contacter { background: rgba(16,26,51,.14);    color: #2b3550; }

.prio { font-size: .68rem; color: var(--muted); }
.prio.haute { color: var(--danger); font-weight: 600; }

.actions-ligne { display: flex; gap: .3rem; justify-content: flex-end; }

.vide-liste { padding: 3rem 1.5rem; text-align: center; color: var(--muted); }
.vide-liste i { font-size: 1.6rem; color: #b3bdd6; display: block; margin-bottom: .6rem; }

/* ------------------------------ Menu déroulant --------------------------- */

/* Un <select> natif ne peut montrer ni la pastille de couleur d'un statut ni
   une coche sur le critère courant. Le menu affiche donc exactement la puce
   qui apparaîtra dans la ligne. */
.menu { position: relative; }

.menu-etiquette { color: var(--muted); font-weight: 400; }
.menu-valeur { font-weight: 500; color: var(--ink); }
.menu-declencheur .chevron { font-size: .66rem; color: var(--muted); transition: transform .15s ease; }
.menu.ouvert .menu-declencheur { background: #fff; border-color: var(--bleu); }
.menu.ouvert .menu-declencheur .chevron { transform: rotate(180deg); }

.menu-panneau {
  position: absolute;
  z-index: 1050;
  right: 0;
  top: calc(100% + 6px);
  min-width: 232px;
  padding: .3rem;
  background: rgba(255, 255, 255, .97);
  backdrop-filter: blur(18px) saturate(150%);
  -webkit-backdrop-filter: blur(18px) saturate(150%);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-sm);
  box-shadow: 0 18px 44px -18px rgba(16, 26, 51, .45);
  display: none;
  flex-direction: column;
  gap: 1px;
}
.menu.ouvert .menu-panneau { display: flex; }

.menu-option {
  display: flex;
  align-items: center;
  gap: .5rem;
  width: 100%;
  padding: .32rem .42rem;
  border: 0;
  border-radius: 8px;
  background: transparent;
  font-size: .85rem;
  color: var(--ink-soft);
  text-align: left;
  cursor: pointer;
}
.menu-option:hover, .menu-option:focus-visible { background: rgba(55, 93, 211, .09); outline: none; }
.menu-option:focus-visible { box-shadow: 0 0 0 2px var(--turquoise) inset; }
.menu-option .n { margin-left: auto; font-size: .72rem; color: var(--muted); }

/* La coche occupe sa place même invisible : sans cela les libellés se
   décaleraient d'un cran au changement de tri. */
.menu-option .coche { width: 12px; flex: none; font-size: .7rem; opacity: 0; }
.menu-option.choisi { color: var(--ink); font-weight: 600; }
.menu-option.choisi .coche { opacity: 1; color: var(--bleu); }

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

.offcanvas.fiche {
  width: min(780px, 100vw);
  background: rgba(255, 255, 255, .84);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  border-left: 1px solid var(--glass-edge);
}
.fiche .offcanvas-header { border-bottom: 1px solid var(--line); padding: 1rem 1.25rem .85rem; }
.fiche-nom { font-family: var(--display); font-size: 1.3rem; font-weight: 700; letter-spacing: -.02em; line-height: 1.15; }
.fiche-sous { font-size: .84rem; color: var(--muted); }
.fiche .offcanvas-body { padding: 1.1rem 1.25rem 3rem; }

.bloc {
  padding: .95rem 1.05rem;
  margin-bottom: .8rem;
  background: rgba(255, 255, 255, .58);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-sm);
}
.bloc h6 {
  font-size: .7rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: .6rem;
}

/* Dans une grille, l'espacement vient de la gouttière. La marge propre du
   bloc s'y ajoutait à l'intérieur de sa colonne — combinée à h-100, elle
   débordait vers le bas et l'« Historique » se retrouvait collé dessous. */
.fiche .row .bloc { margin-bottom: 0; }
.fiche .row + .bloc { margin-top: .8rem; }

.paires { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: .7rem 1.1rem; }
.paire .k { font-size: .7rem; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); }
.paire .v { font-size: .88rem; }

.liste-simple { list-style: none; padding: 0; margin: 0; font-size: .86rem; }
.liste-simple li { padding: .32rem 0 .32rem .9rem; position: relative; border-bottom: 1px solid var(--line); }
.liste-simple li:last-child { border-bottom: 0; }
.liste-simple li::before {
  content: '';
  position: absolute;
  left: 0; top: .78rem;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--turquoise);
}

.fiche .form-control, .fiche .form-select {
  background: rgba(255, 255, 255, .82);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-sm);
  font-size: .88rem;
}
.fiche .form-control:focus, .fiche .form-select:focus {
  border-color: var(--bleu);
  box-shadow: 0 0 0 3px rgba(55, 93, 211, .16);
}
.fiche textarea { min-height: 130px; resize: vertical; }

.journal { font-size: .8rem; }
.journal li { display: flex; gap: .6rem; padding: .35rem 0; border-bottom: 1px solid var(--line); }
.journal li:last-child { border-bottom: 0; }
.journal .quand { color: var(--muted); white-space: nowrap; font-size: .74rem; }

/* Le RPPS devient un bouton : il ouvre l'Annuaire Santé. */
.rpps-lien {
  font-family: var(--mono);
  border: 1px solid rgba(55, 93, 211, .3);
  background: rgba(55, 93, 211, .08);
  color: var(--bleu-fonce);
  border-radius: 7px;
  padding: .1rem .45rem;
  font-size: .82rem;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  cursor: pointer;
}
.rpps-lien:hover { background: var(--bleu); color: #fff; border-color: var(--bleu); }
.rpps-lien i { font-size: .68rem; }

/* ------------------------- Modale Annuaire Santé ------------------------- */

.modal-annuaire .modal-dialog { max-width: 860px; }
.modal-annuaire .modal-content {
  background: rgba(255, 255, 255, .93);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius);
}
.modal-annuaire .modal-header { border-bottom: 1px solid var(--line); align-items: flex-start; }
.modal-annuaire .modal-body { max-height: min(72vh, 760px); overflow-y: auto; }

.bandeau-source {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  font-size: .76rem;
  color: var(--muted);
  padding: .5rem .75rem;
  border-radius: var(--radius-sm);
  background: rgba(32, 198, 198, .1);
  margin-bottom: .85rem;
}
.bandeau-source .officiel {
  font-weight: 600;
  color: var(--turquoise-f);
  display: inline-flex;
  align-items: center;
  gap: .3rem;
}

.exercice {
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, .6);
  padding: .85rem 1rem;
  margin-bottom: .6rem;
}
.exercice.inactif { opacity: .62; }
.exercice-titre {
  font-weight: 600;
  font-size: .92rem;
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  margin-bottom: .4rem;
}
.exercice-adresse { font-size: .84rem; color: var(--ink-soft); }
.exercice-contacts { display: flex; flex-wrap: wrap; gap: .35rem .9rem; margin-top: .5rem; font-size: .82rem; }
.exercice-contacts a { color: var(--bleu); text-decoration: none; }
.exercice-contacts a:hover { text-decoration: underline; }

.copiable {
  border: 0;
  background: transparent;
  color: var(--muted);
  font-size: .7rem;
  padding: 0 .2rem;
  border-radius: 5px;
}
.copiable:hover { color: var(--bleu); background: rgba(55, 93, 211, .1); }

.badge-mss {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  font-size: .74rem;
  padding: .16rem .5rem;
  border-radius: 100px;
  background: rgba(32, 198, 198, .16);
  color: var(--turquoise-f);
  font-family: var(--mono);
}

.chargement-annuaire { padding: 2.4rem 1rem; text-align: center; color: var(--muted); font-size: .88rem; }
.chargement-annuaire i { font-size: 1.4rem; color: var(--bleu); display: block; margin-bottom: .6rem; }

/* ------------------------------- Connexion -------------------------------- */

.page-connexion { min-height: 100vh; display: grid; place-items: center; padding: 1.5rem; }
.carte-connexion { width: 100%; max-width: 400px; padding: 2.1rem 1.9rem 1.7rem; }
.carte-connexion .logo-opticontact { margin: 0 auto .35rem; }
.carte-connexion .accroche {
  text-align: center;
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.02rem;
  letter-spacing: -.01em;
  margin-bottom: .25rem;
}
.carte-connexion p.intro { color: var(--muted); font-size: .86rem; margin-bottom: 1.4rem; text-align: center; }
.carte-connexion .form-control {
  background: rgba(255, 255, 255, .78);
  border: 1px solid var(--glass-edge);
  border-radius: var(--radius-sm);
  padding: .6rem .8rem;
}
.carte-connexion .form-control:focus { border-color: var(--bleu); box-shadow: 0 0 0 3px rgba(55, 93, 211, .18); }
.erreur-connexion { color: var(--danger); font-size: .83rem; min-height: 1.2rem; margin-top: .5rem; }
.pied-marque { text-align: center; font-size: .74rem; color: var(--muted); margin-top: 1.1rem; }
.pied-marque a { color: var(--bleu); text-decoration: none; }

/* ----------------------------- Notifications ------------------------------ */

.zone-toasts { position: fixed; right: 1rem; bottom: 1rem; z-index: 2000; display: flex; flex-direction: column; gap: .5rem; }
.toast-verre {
  padding: .6rem .9rem;
  font-size: .85rem;
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, .9);
  backdrop-filter: blur(16px);
  border: 1px solid var(--glass-edge);
  border-left: 3px solid var(--turquoise);
  box-shadow: var(--glass-shadow);
  animation: entree .25s ease;
  max-width: 380px;
}
.toast-verre.erreur { color: var(--danger); border-left-color: var(--danger); }
@keyframes entree { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* ------------------------------- Pagination ------------------------------- */

.pagination-verre {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: 1rem 0 2rem;
  font-size: .85rem;
  color: var(--ink-soft);
}

/* ============================ Page « Mes bases » ========================== */

.fil-base { display: flex; flex-direction: column; line-height: 1.15; min-width: 0; }
.retour-bases { font-size: .68rem; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); text-decoration: none; }
.retour-bases:hover { color: var(--bleu); }
.nom-base {
  font-family: var(--display);
  font-weight: 600;
  font-size: .98rem;
  letter-spacing: -.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 24vw;
}

.hero-bases { padding: 1.6rem 1.5rem 1.4rem; margin-bottom: 1rem; display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap; }
.hero-bases h1 {
  font-family: var(--display);
  font-size: 1.45rem;
  font-weight: 700;
  letter-spacing: -.025em;
  margin: .55rem 0 .25rem;
}
.hero-bases p { color: var(--ink-soft); font-size: .89rem; margin: 0; max-width: 62ch; }
.hero-chiffres { display: flex; gap: 1.6rem; margin-left: auto; }
.hero-chiffre strong {
  display: block;
  font-family: var(--display);
  font-size: 1.6rem;
  font-weight: 600;
  letter-spacing: -.03em;
  line-height: 1;
}
.hero-chiffre span { font-size: .74rem; color: var(--muted); }

.grille-bases { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: .9rem; }

.carte-base {
  padding: 1.15rem 1.15rem 1rem;
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
  transition: transform .14s ease, box-shadow .14s ease;
}
.carte-base::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: 3px;
  background: linear-gradient(90deg, var(--turquoise), var(--bleu));
  opacity: 0;
  transition: opacity .14s ease;
}
.carte-base:hover { transform: translateY(-2px); box-shadow: 0 22px 50px -24px rgba(16, 26, 51, .55); }
.carte-base:hover::before { opacity: 1; }

.carte-lien { text-decoration: none; color: inherit; display: block; flex: 1; }
.carte-entete { display: flex; align-items: baseline; gap: .5rem; }
.carte-nom { font-family: var(--display); font-size: 1.16rem; font-weight: 700; letter-spacing: -.02em; margin: 0; flex: 1; min-width: 0; }
.carte-slug { font-size: .68rem; color: var(--muted); }
.carte-desc { font-size: .82rem; color: var(--ink-soft); margin: .35rem 0 0; }

.carte-chiffre { display: flex; align-items: baseline; gap: .4rem; margin: .9rem 0 .5rem; }
.carte-chiffre strong { font-size: 2rem; font-weight: 500; letter-spacing: -.03em; line-height: 1; }
.carte-chiffre span { font-size: .8rem; color: var(--muted); }

.pipeline { display: flex; height: 6px; border-radius: 6px; overflow: hidden; background: rgba(16, 26, 51, .07); margin-bottom: .75rem; }
.pipeline span { background: currentColor; display: block; }
.pipeline.vide span { width: 100%; background: rgba(16, 26, 51, .07); }

.carte-stats { display: flex; flex-wrap: wrap; gap: .3rem .85rem; font-size: .78rem; color: var(--ink-soft); }
.carte-stats i { color: var(--muted); margin-right: .25rem; }
.carte-maj { font-size: .73rem; color: var(--muted); margin: .6rem 0 0; }

.carte-actions { display: flex; align-items: center; gap: .35rem; margin-top: .9rem; padding-top: .8rem; border-top: 1px solid var(--line); }
.carte-actions .icone-btn { cursor: pointer; }

.carte-progression { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: rgba(55, 93, 211, .15); overflow: hidden; }
.carte-progression span { display: block; height: 100%; width: 35%; background: var(--bleu); animation: defile 1.1s ease-in-out infinite; }
@keyframes defile { 0% { transform: translateX(-100%); } 100% { transform: translateX(320%); } }

.carte-ajout { align-items: flex-start; justify-content: center; gap: .5rem; border-style: dashed; }
.carte-ajout i { font-size: 1.5rem; color: var(--turquoise); }
.carte-ajout h2 { font-family: var(--display); font-size: 1.1rem; font-weight: 700; margin: 0; }
.carte-ajout p { font-size: .84rem; color: var(--ink-soft); margin: 0 0 .4rem; }

.zone-depot {
  display: flex;
  align-items: center;
  gap: .6rem;
  width: 100%;
  padding: .9rem 1rem;
  border: 1px dashed rgba(16, 26, 51, .22);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, .5);
  color: var(--muted);
  font-size: .84rem;
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease;
}
.zone-depot i { font-size: 1.05rem; }
.zone-depot:hover, .zone-depot.survol { border-color: var(--bleu); background: #fff; color: var(--ink-soft); }
.zone-depot.rempli { border-style: solid; border-color: var(--turquoise); color: var(--turquoise-f); }

.modal-content.glass { background: rgba(255, 255, 255, .88); }

/* -------------------------------- Responsive ------------------------------ */

@media (max-width: 1200px) {
  .ligne { grid-template-columns: 34px minmax(0, 1fr) 170px 120px 140px 60px; }
}

@media (max-width: 991px) {
  .ligne {
    grid-template-columns: 34px 1fr auto;
    grid-template-areas:
      'case identite actions'
      '.    contact  contact'
      '.    dispo    statut';
    row-gap: .5rem;
  }
  .ligne .c-case { grid-area: case; }
  .ligne .c-identite { grid-area: identite; }
  .ligne .c-contact { grid-area: contact; }
  .ligne .c-dispo { grid-area: dispo; }
  .ligne .c-statut { grid-area: statut; justify-self: start; }
  .ligne .c-actions { grid-area: actions; }
  /* En mobile la case n'occupe que la première rangée : la marge négative du
     bas déborderait sur les contacts. */
  .c-case { align-self: start; margin-bottom: 0; padding-bottom: 0; }
  .rail { position: static; max-height: none; }
  .rail-entete { position: static; margin: -1rem -1rem .9rem; }
  .hero-chiffres { margin-left: 0; }
}

@media (max-width: 767px) {
  .fil-base { display: none; }
  .marque .sous-produit { display: none; }
  .logo-opticontact { height: 24px; }
  .menu-panneau { min-width: 210px; }
}

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