/* CRM Locations Exoboost — aligné sur le thème boutique (Instrument Sans, bleu #307CF9, fond #f4f4f4) */
:root {
  --blue: #307CF9; --blue-dark: #1a5fd4; --blue-light: #e8f0fe;
  --black: #0d0d0d; --text: #232323; --white: #fff;
  --bg: #f4f4f4; --grey-100: #f0f2f8; --grey-200: #dde1ec; --grey-400: #646a80; /* audit 30/08 : ex #8f95aa, 2.9:1, illisible en 10-12px */ --grey-600: #555b72;
  --ok: #1F9D55; --warn: #E8850C; --danger: #EA0606;
  /* Encres et fonds d'etat (audit 30/08) : les encres passent 4.5:1 sur leur fond teinte,
     les couleurs vives restent pour les points, bordures et barres (graphiques, pas du texte). */
  --ok-bg: #ddf3e6; --ok-ink: #157a41; --warn-bg: #fff4e0; --warn-ink: #9a5b00;
  --danger-bg: #fde2e2; --danger-ink: #c11414; --violet: #7a3ff2; --violet-bg: #efe8fd;
  --bar-live: var(--blue); --bar-future: #b9d1fb; --bar-done: #cfd4df; --bar-late: var(--danger); --bar-caution: var(--violet);
  --radius: 12px; --radius-md: 10px; --radius-sm: 8px;
  --shadow: 0 4px 24px rgba(48,124,249,.10); --shadow-lg: 0 12px 48px rgba(48,124,249,.16);
  --font: 'Instrument Sans', system-ui, sans-serif; --mono: 'Space Mono', ui-monospace, monospace;
  /* compat anciens noms */
  --ink: var(--text); --ink-soft: var(--grey-600); --line: var(--grey-200); --accent: var(--blue); --accent-ink: var(--blue-dark); --surface: var(--white);
}
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }
body { font-family: var(--font); background: var(--bg); color: var(--text); font-size: 15px; line-height: 1.5; }
h1 { font-size: 26px; font-weight: 700; margin: 0; letter-spacing: -0.02em; line-height: 1.15; }
button, input, select, textarea { font-family: inherit; }

/* ---- topbar ---- */
.topbar {
  display: flex; align-items: center; gap: 32px; height: 64px; padding: 0 28px;
  background: var(--white); border-bottom: 1px solid var(--grey-200);
  position: sticky; top: 0; z-index: 30;
}
.brand { display: flex; align-items: center; gap: 12px; }
.brand-logo { height: 30px; width: auto; display: block; }
.brand-sub { font-family: var(--mono); font-size: 11px; color: var(--grey-400); text-transform: uppercase; letter-spacing: .18em; padding-left: 12px; border-left: 1px solid var(--grey-200); }
.tabs { display: flex; gap: 2px; height: 100%; }
.tab {
  border: 0; background: none; color: var(--grey-600); padding: 0 16px; cursor: pointer;
  font-size: 15px; font-weight: 600; border-bottom: 3px solid transparent; border-top: 3px solid transparent;
}
.tab:hover { color: var(--black); }
.tab.active { color: var(--black); border-bottom-color: var(--blue); }
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 16px; }
.today-label { font-family: var(--mono); font-size: 12px; color: var(--grey-400); text-transform: capitalize; }

/* ---- generic ---- */
/* 1800 et plus 1500 : la page respire sur grand ecran (retour Saad 27/08). */
.view { padding: 28px; max-width: 1800px; margin: 0 auto; }
.view-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 18px; flex-wrap: wrap; }
.center-msg { padding: 60px 20px; text-align: center; color: var(--grey-600); }
.center-msg.error { color: var(--danger-ink); }
.btn {
  border: 1.5px solid var(--grey-200); background: var(--white); color: var(--text);
  border-radius: var(--radius-sm); padding: 8px 16px; cursor: pointer; font-size: 14px; font-weight: 600; line-height: 1.2;
}
.btn:hover { border-color: var(--blue); color: var(--blue-dark); }
.btn.primary { background: var(--blue); border-color: var(--blue); color: var(--white); font-weight: 700; }
.btn.primary:hover { background: var(--blue-dark); border-color: var(--blue-dark); color: var(--white); }
.btn.ghost { background: transparent; }
.mono { font-family: var(--mono); }
.toast {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  background: var(--black); color: var(--white); padding: 11px 18px; border-radius: var(--radius-sm); font-size: 14px; z-index: 100; box-shadow: var(--shadow-lg);
}
.check-label { color: var(--grey-600); font-size: 14px; display: flex; gap: 8px; align-items: center; }
/* Focus clavier visible partout (audit 30/08). Les champs gardent leur anneau bleu existant :
   la regle .field input:focus, plus specifique, continue de neutraliser l'outline. */
:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.check-label input { accent-color: var(--blue); width: 16px; height: 16px; }

/* ---- planning / gantt ---- */
.range-ctrl { display: flex; align-items: center; gap: 8px; }
#range-label { font-size: 13px; color: var(--grey-600); min-width: 150px; text-align: center; }
.gantt { background: var(--white); border: 1px solid var(--grey-200); border-radius: var(--radius); overflow-x: auto; box-shadow: var(--shadow); }
.gantt-grid { display: grid; min-width: 900px; }
.g-cell { border-bottom: 1px solid var(--grey-200); border-right: 1px solid var(--grey-100); min-height: 50px; position: relative; }
.g-head { background: var(--grey-100); font-family: var(--mono); font-size: 10px; color: var(--grey-400); display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 46px; text-transform: uppercase; letter-spacing: .04em; }
.g-head .dnum { font-family: var(--font); font-size: 14px; color: var(--text); font-weight: 600; letter-spacing: 0; }
.g-head.weekend { background: #e9ecf4; }
.g-head.is-today { background: var(--blue-light); }
.g-head.is-today .dnum { color: var(--blue); font-weight: 700; }
.g-machine {
  position: sticky; left: 0; z-index: 5; background: var(--white);
  border-right: 1px solid var(--grey-200); padding: 8px 16px; display: flex; flex-direction: column; justify-content: center;
}
.g-machine .m-name { font-weight: 700; font-size: 14px; letter-spacing: -0.01em; }
.g-machine .m-status { font-size: 12px; color: var(--grey-400); }
.g-row-bg.weekend { background: #f8f9fc; }
/* Marque le DEBUT de la journee en cours, pas son milieu : une location qui commence
   aujourd hui doit demarrer sur cette ligne. A 50% elle tombait une demi-colonne a
   droite des barres, qui semblaient donc commencer la veille. */
.g-today-line { position: absolute; top: 0; bottom: 0; left: -1px; width: 2px; background: var(--blue); opacity: .9; z-index: 2; }
.g-bar {
  position: absolute; top: 10px; height: 30px; border-radius: var(--radius-sm); z-index: 3;
  color: var(--white); font-size: 12px; font-weight: 700; display: flex; align-items: center;
  padding: 0 10px; overflow: hidden; white-space: nowrap; cursor: pointer;
  box-shadow: 0 1px 2px rgba(13,13,13,.08);
}
/* text-overflow ne s'applique pas au conteneur flex lui-meme : sans cette boite
   interne, un nom trop long etait coupe net au lieu de finir par des points. */
.g-bar-txt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
/* Barre coupee par le bord de la fenetre : cote plat, la location continue au-dela. */
.g-bar.clip-l { border-top-left-radius: 0; border-bottom-left-radius: 0; }
.g-bar.clip-r { border-top-right-radius: 0; border-bottom-right-radius: 0; }
.g-bar:hover { filter: brightness(.94); box-shadow: var(--shadow); }
.g-bar[style*="bar-future"] { color: var(--blue-dark); }
.g-bar.done { color: var(--grey-600); }
.legend { display: flex; gap: 20px; margin-top: 12px; font-size: 13px; color: var(--grey-600); flex-wrap: wrap; }
.legend .sw { display: inline-block; width: 12px; height: 12px; border-radius: 3px; margin-right: 6px; vertical-align: -1px; }

/* ---- kanban ---- */
.kanban { display: flex; gap: 14px; overflow-x: auto; align-items: flex-start; padding-bottom: 12px; }
.kb-col { background: var(--grey-100); border: 1px solid var(--grey-200); border-radius: var(--radius); min-width: 320px; width: 320px; flex-shrink: 0; }
.kb-col-head {
  padding: 12px 14px; font-weight: 700; font-size: 13px; text-transform: uppercase; letter-spacing: .06em;
  display: flex; justify-content: space-between; align-items: center; border-bottom: 2px solid var(--blue);
}
.kb-col-head .count { font-family: var(--mono); font-weight: 400; font-size: 12px; color: var(--grey-400); text-transform: none; letter-spacing: 0; }
.kb-col.alert .kb-col-head { color: var(--danger-ink); border-bottom-color: var(--danger); }
.kb-cards { padding: 10px; display: flex; flex-direction: column; gap: 8px; min-height: 30px; }
.kb-card { background: var(--white); border: 1px solid var(--grey-200); border-radius: var(--radius-md); padding: 12px 14px; cursor: pointer; }
.kb-card:hover { border-color: var(--blue); box-shadow: var(--shadow); }
.kb-card .ref { font-weight: 700; font-size: 14px; }
.kb-card .meta { font-size: 13px; color: var(--grey-600); margin-top: 3px; }
.kb-card .mach { font-family: var(--mono); font-size: 11px; margin-top: 6px; color: var(--blue-dark); }
.kb-card .flag { font-size: 12px; color: var(--warn); margin-top: 6px; font-weight: 600; }

/* ---- clients ---- */
.clients-layout { display: grid; grid-template-columns: 280px 1fr; gap: 18px; padding: 28px; max-width: 1800px; margin: 0 auto; }
.clients-list { background: var(--white); border: 1px solid var(--grey-200); border-radius: var(--radius); padding: 12px; align-self: start; box-shadow: var(--shadow); }
#client-search { width: 100%; padding: 10px 12px; border: 1.5px solid var(--grey-200); border-radius: var(--radius-sm); font-size: 14px; margin-bottom: 10px; background: var(--bg); }
#client-search:focus { outline: none; border-color: var(--blue); background: var(--white); }
#client-ul { list-style: none; margin: 0; padding: 0; max-height: 70vh; overflow-y: auto; }
#client-ul li { padding: 10px 12px; border-radius: var(--radius-sm); cursor: pointer; font-weight: 600; }
#client-ul li:hover { background: var(--blue-light); }
#client-ul li.active { background: var(--blue); color: var(--white); }
#client-ul li .sub { display: block; font-size: 12px; font-weight: 400; color: inherit; opacity: .7; }
.client-detail { min-height: 300px; }
.card { background: var(--white); border: 1px solid var(--grey-200); border-radius: var(--radius); padding: 20px; margin-bottom: 16px; box-shadow: var(--shadow); }
.card h2 { font-size: 18px; font-weight: 700; margin: 0 0 14px; letter-spacing: -0.01em; }
.field-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px 18px; }
.field label { display: block; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .12em; color: var(--grey-400); margin-bottom: 4px; }
.field input, .field select, .field textarea {
  width: 100%; padding: 9px 11px; border: 1.5px solid var(--grey-200); border-radius: var(--radius-sm);
  font-size: 14px; background: var(--white); color: var(--text);
}
.field textarea { min-height: 72px; resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-light); }
.row-line { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 10px 8px; margin: 0 -8px; border-bottom: 1px solid var(--grey-100); font-size: 14px; cursor: pointer; border-radius: 6px; }
.row-line:hover { background: var(--blue-light); }
.row-line .r-main { font-weight: 600; }
.row-line .r-sub { color: var(--grey-600); font-size: 13px; }
.badge { display: inline-block; padding: 3px 10px; border-radius: 999px; font-size: 11px; font-weight: 700; background: var(--grey-100); color: var(--grey-600); white-space: nowrap; }
.badge.b5 { background: var(--blue-light); color: var(--blue-dark); }
.badge.b9 { background: var(--ok-bg); color: var(--ok-ink); }
.badge.balert { background: var(--danger-bg); color: var(--danger-ink); }

/* ---- drawer ---- */
.drawer-backdrop { position: fixed; inset: 0; background: rgba(13,13,13,.45); z-index: 40; }
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(580px, 96vw); background: var(--white);
  z-index: 50; overflow-y: auto; box-shadow: -12px 0 48px rgba(13,13,13,.18); padding: 24px 28px;
}
.drawer-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; margin-bottom: 18px; padding-bottom: 14px; border-bottom: 1px solid var(--grey-200); }
.drawer-head h2 { font-size: 22px; font-weight: 700; margin: 0; letter-spacing: -0.02em; }
/* Rythme des sections : un filet clair au-dessus de chaque titre, comme la maquette du
   01/09. Sans lui les huit blocs du volet se lisent comme une seule colonne de champs. */
.drawer section { margin: 0; padding: 22px 0; border-top: 1px solid var(--grey-200); }
.drawer section:first-of-type { padding-top: 0; border-top: 0; }
.drawer h3 { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .1em; color: var(--grey-600); margin: 0 0 14px; }
/* L'apercu du message reste une zone de saisie, mais la maquette la montre en gris neutre
   et affichee en entier. Le bleu la faisait passer pour un encart, et la hauteur par defaut
   d'un textarea (2 lignes) coupait le texte : autoGrow() dans app.js l'ajuste au contenu. */
.sms-preview {
  display: block; width: 100%; background: var(--grey-100); border: 1px solid var(--grey-200);
  border-radius: var(--radius-md); padding: 13px 14px; color: var(--text);
  font-size: 15px; line-height: 1.5; white-space: pre-wrap; margin: 12px 0; resize: vertical;
  overflow: hidden; min-height: 76px;
}
.sms-preview:focus { outline: none; border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-light); }
.sms-actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }

/* ---- volet simplifie (maquette Gauthier du 01/09) ---- */
/* Deux colonnes fixes : la maquette aligne les champs par paires (Modele/Etape,
   Date debut/Date fin, Loyer initial/Loyer final). L'auto-fill global en donnait 1 ou 3
   selon la largeur, donc jamais l'alignement demande. */
.drawer .field-grid { grid-template-columns: 1fr 1fr; gap: 16px 18px; }
/* Etiquettes en casse normale, comme la maquette. Les capitales espacees du reste de
   l'appli donnaient huit lignes de titres qui criaient plus fort que les valeurs, et le
   volet se lisait comme un formulaire d'administration au lieu d'une fiche. */
.drawer .field label {
  font-size: 14px; font-weight: 400; text-transform: none; letter-spacing: 0;
  color: var(--grey-600); margin-bottom: 6px;
}
.drawer .field input, .drawer .field select, .drawer .field textarea {
  padding: 11px 12px; font-size: 15px; border-width: 1px; border-radius: var(--radius-md);
}
.drawer .field input[readonly], .drawer .field input:disabled {
  background: var(--grey-100); color: var(--grey-600); border-color: var(--grey-200); cursor: default;
}
/* Les lignes de calcul (loyer, caution) sous les champs. :empty les efface quand il n'y a
   rien a dire, sinon un cadre gris vide reste affiche sous chaque location. */
.drawer .calc {
  background: var(--grey-100); border-radius: var(--radius-sm); padding: 10px 12px;
  font-size: 13px; color: var(--grey-600); margin-top: 10px;
}
.drawer .calc:empty { display: none; }
/* Encart d'information (extensions proposables). Le jaune reste reserve a la note client
   et aux alertes : deux pastilles jaunes dans le meme volet ne hierarchisent plus rien. */
.hint {
  background: var(--grey-100); border-left: 3px solid var(--blue); border-radius: var(--radius-sm);
  padding: 11px 13px; font-size: 14px; color: var(--grey-600); margin-top: 12px;
}
/* Mention accolee a un titre de section : « 2e temps », « horodatage a l'envoi ». */
.drawer h3 .h3-note { font-weight: 600; text-transform: none; letter-spacing: 0; color: var(--blue); }
.drawer h3 .h3-note.mut { color: var(--grey-400); }
.ctrl-ligne { font-size: 14px; padding: 4px 0; }
.lien-fiche { color: var(--blue-dark); cursor: pointer; text-decoration: underline; }
.lien-fiche:hover { color: var(--blue); }
.mail-apercu { background: var(--grey-100); border-radius: var(--radius-sm); padding: 12px; margin-top: 8px; font-size: 14px; color: var(--text); }
.mail-apercu-corps { white-space: pre-wrap; margin-top: 6px; }
/* Tout ce que la maquette ne montre plus mais qui reste indispensable : suivi transporteur,
   cloture, issue de location, autres canaux. Replie par defaut, jamais supprime. */
.drawer details.avance { border-top: 1px solid var(--grey-200); padding: 22px 0; margin: 0; }
.drawer details.avance section { border-top: 0; padding-bottom: 0; }
/* Le titre etait plus petit et plus clair que tous les autres titres du volet
   (11px gris-400 contre 12px gris-600 pour les h3), donc c'est celui qu'on voyait le
   moins alors que c'est le seul sur lequel il faut cliquer. Il passe a l'echelle des
   h3, et il vire au bleu une fois ouvert : c'est ce qui dit que la section est
   depliee, sinon rien ne distingue son contenu du reste du volet. */
.drawer details.avance > summary {
  cursor: pointer; font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .1em; color: var(--grey-600); list-style: none;
}
.drawer details.avance[open] > summary { color: var(--blue-dark); margin-bottom: 4px; }
.drawer details.avance > summary::-webkit-details-marker { display: none; }
.drawer details.avance > summary::before { content: '\25B8'; display: inline-block; width: 16px; color: var(--blue); }
.drawer details.avance[open] > summary::before { content: '\25BE'; }
.drawer details.avance > *:not(summary) { margin-top: 14px; }
/* Le bouton d'enregistrement est unique et en bas, il suit le defilement. Les marges
   negatives le font aller d'un bord a l'autre du volet : sinon le texte des sections
   passait dans les gouttieres a gauche et a droite du bandeau et donnait l'impression
   que le bouton flottait au milieu du contenu. */
.drawer-save {
  position: sticky; bottom: 0; z-index: 2; background: var(--white);
  margin: 24px -28px -24px; padding: 16px 28px 24px; border-top: 1px solid var(--grey-200);
  box-shadow: 0 -8px 20px rgba(13, 13, 13, .05);
}

/* ---- liste des communications ---- */
.comm-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 10px 0; border-bottom: 1px solid var(--grey-100); font-size: 14px; }
.comm-row > summary { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; cursor: pointer; list-style: none; }
.comm-row > summary::-webkit-details-marker { display: none; }
.comm-pliable { display: block; }
/* Le titre s'enroule au lieu d'etre rabote. Avant, la pastille de canal, le statut, le
   bouton d'envoi et l'horodatage se partageaient une seule ligne et il ne restait
   au titre que « [auto J+4] W… ». La file d'envoi passe donc sous la ligne (.comm-file)
   et la ligne redevient celle de la maquette : canal, titre, horodatage. */
.comm-row .c-titre { flex: 1 1 140px; min-width: 0; }
.comm-file { flex: 0 0 100%; display: flex; align-items: center; gap: 8px; }
.comm-file .btn { font-size: 12px; padding: 5px 11px; }
.comm-row .c-quand { font-family: var(--mono); font-size: 12px; color: var(--grey-600); white-space: nowrap; margin-left: auto; }
.comm-corps { white-space: pre-wrap; color: var(--grey-600); font-size: 13px; padding: 8px 0 4px 10px; border-left: 2px solid var(--grey-200); margin-top: 8px; }
.badge.c-sms { background: var(--blue-light); color: var(--blue-dark); }
.badge.c-mail { background: var(--violet-bg); color: var(--violet); }
.badge.c-wa { background: var(--ok-bg); color: var(--ok-ink); }
.badge.c-appel { background: var(--warn-bg); color: var(--warn-ink); }
.comm-item { padding: 10px 0; border-bottom: 1px solid var(--grey-100); font-size: 14px; }
.comm-item .c-head { display: flex; gap: 8px; align-items: center; color: var(--grey-600); font-size: 12px; margin-bottom: 3px; }
.note-flag { background: #FFF6E9; border: 1px solid #F3DDB8; border-radius: var(--radius-md); padding: 12px 14px; font-size: 14px; margin-bottom: 14px; white-space: pre-wrap; }

@media (max-width: 800px) {
  .clients-layout { grid-template-columns: 1fr; padding: 14px; }
  .topbar { gap: 12px; padding: 0 14px; height: 56px; }
  .brand-logo { height: 24px; }
  .brand-sub, .today-label { display: none; }
  .tab { padding: 0 10px; font-size: 14px; }
  .view { padding: 14px; }
  h1 { font-size: 22px; }
}
@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }

/* fenêtres logistiques (envoi J-3 / retour J+2) + suggestion machine */
.g-ghost { position: absolute; height: 30px; border: 1.5px dashed var(--grey-400); border-radius: var(--radius-sm); z-index: 2; opacity: .75; pointer-events: none; }
.legend .sw-ghost { background: transparent; border: 1.5px dashed var(--grey-400); }

/* Contrat non signe : liseré sur le bord gauche de la barre. Demande de Lukas.
   Un liseré et non une couleur de fond, parce que le fond porte deja l'etape :
   deux informations differentes ne peuvent pas se partager le meme canal visuel.
   inset plutot que border, sinon la barre s'elargit et se decale d'un pixel. */
.g-bar.unsigned { box-shadow: inset 4px 0 0 var(--danger), 0 1px 2px rgba(13,13,13,.08); }
.legend .sw-unsigned { background: transparent; border: 1px solid var(--grey-400); box-shadow: inset 4px 0 0 var(--danger); }
#machine-hint { margin-top: 6px; }
#machine-hint .btn { font-size: 12px; padding: 4px 10px; }
.hint-alert { color: var(--danger-ink); font-size: 12px; font-weight: 600; }

/* ---- tableaux (Parc, Entretien, Incidents) ---- */
.tbl-wrap { background: var(--white); border: 1px solid var(--grey-200); border-radius: var(--radius); overflow-x: auto; }
.tbl { width: 100%; border-collapse: collapse; font-size: 14px; }
.tbl th {
  text-align: left; padding: 12px 14px; white-space: nowrap;
  font-family: var(--mono); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em;
  color: var(--grey-400); background: var(--grey-100); border-bottom: 1px solid var(--grey-200);
}
.tbl td { padding: 12px 14px; border-bottom: 1px solid var(--grey-200); vertical-align: top; }
.tbl tbody tr:last-child td { border-bottom: 0; }
.tbl tr.clickable { cursor: pointer; }
.tbl tr.clickable:hover td { background: var(--blue-light); }
.tbl .strong { font-weight: 600; color: var(--black); }
.tbl .num { text-align: right; font-family: var(--mono); }
.tbl .mono { font-family: var(--mono); font-size: 13px; }
.tbl .wrap { white-space: pre-wrap; min-width: 220px; color: var(--grey-600); }
.tbl .center-msg { padding: 40px 20px; }
.cell-sub { display: block; font-size: 12px; color: var(--grey-400); margin-top: 2px; }
.ent-details { margin-top: 12px; border-top: 1px solid var(--grey-200); padding-top: 10px; }
.ent-details summary { cursor: pointer; font-size: 13px; font-weight: 600; color: var(--grey-600); margin-bottom: 10px; }
.ent-details summary:hover { color: var(--blue-dark); }
.tbl .linkcell { color: var(--blue-dark); cursor: pointer; }
.tbl .linkcell:hover { text-decoration: underline; text-underline-offset: 2px; }

/* ---- page de connexion ---- */
.login-body { display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 24px; }
.login-card {
  background: var(--white); border: 1px solid var(--grey-200); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 36px 32px; width: 100%; max-width: 380px; text-align: center;
}
.login-logo { height: 34px; width: auto; display: block; margin: 0 auto 6px; }
.login-sub {
  font-family: var(--mono); font-size: 11px; color: var(--grey-400);
  text-transform: uppercase; letter-spacing: .18em; margin-bottom: 28px;
}
.login-card form { text-align: left; }
.login-btn { width: 100%; margin-top: 20px; padding: 11px 16px; font-size: 15px; }
.login-btn:disabled { opacity: .6; cursor: default; }
.login-error {
  color: var(--danger-ink); font-size: 13px; margin: 14px 0 0;
  background: var(--danger-bg); border-radius: var(--radius-sm); padding: 9px 12px;
}
.logout-btn { font-size: 13px; padding: 6px 12px; }
.badge.bplan { background: var(--warn-bg); color: var(--warn-ink); }
.card-sep { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--grey-400); margin: 22px 0 12px; padding-top: 16px; border-top: 1px solid var(--grey-200); }
.tbl a { color: var(--blue-dark); }

/* Chronologie (panneau location) et derniere action (carte pipeline) */
.kb-card .kb-last { font-size: 12px; color: var(--grey-600); margin-top: 6px; }
.chrono { border-left: 2px solid var(--grey-200); margin-top: 12px; padding-left: 14px; }
.chrono-ev { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; padding: 7px 0; border-bottom: 1px solid var(--grey-100); font-size: 14px; }
.chrono-ev:last-child { border-bottom: 0; }
.chrono-date { font-family: var(--mono); font-size: 11px; color: var(--grey-600); min-width: 118px; }
.chrono-label { font-weight: 600; }
.chrono-detail { color: var(--grey-600); font-size: 13px; }
.chrono-ev.futur { opacity: .55; }
.chrono-ev.incident .chrono-label { color: var(--danger-ink); }
.chrono-now { font-family: var(--mono); font-size: 11px; color: var(--blue-dark); text-transform: uppercase; letter-spacing: .08em; margin: 4px 0; position: relative; }
.chrono-now::before { content: ''; position: absolute; left: -19px; top: 50%; width: 10px; height: 2px; background: var(--blue); }
.chrono-attente { background: var(--warn-bg); color: var(--warn-ink); border-radius: var(--radius-sm); padding: 10px 12px; font-size: 13px; margin-top: 10px; }
.chrono-attente strong { display: block; margin-bottom: 4px; font-size: 12px; text-transform: uppercase; letter-spacing: .06em; }

/* Régularisation (panneau location) */
.regul { margin-top: 12px; padding: 12px 14px; border-radius: var(--radius-sm); background: var(--grey-100); font-size: 14px; }
.regul.danger { background: var(--danger-bg); }
.regul strong { display: block; margin-bottom: 8px; }
.regul-etape { display: flex; gap: 8px; align-items: baseline; padding: 3px 0; }
.regul-note { margin-top: 8px; font-size: 13px; color: var(--grey-600); }
.regul.danger .regul-note { color: #9a2a2a; font-weight: 600; }
.regul-warn { color: var(--warn); font-size: 13px; margin-bottom: 6px; font-weight: 600; }

/* ---- Chronologie sur carte pipeline + journal d'actions (25/08, demande Lukas) ---- */
.kb-chrono { margin-top: 8px; border-top: 1px solid var(--grey-100); padding-top: 6px; }
.kb-ev { display: flex; align-items: baseline; gap: 6px; font-size: 12px; padding: 2px 0; color: var(--grey-600); white-space: nowrap; overflow: hidden; }
.kb-ev-date { font-family: var(--mono); font-size: 10px; flex: none; min-width: 72px; color: var(--grey-400); }
.kb-chip { flex: none; font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; padding: 1px 6px; border-radius: 999px; background: var(--grey-100); color: var(--grey-600); }
.kb-ev-label { flex: 1; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; }
.kb-ev.b-attente .kb-ev-label { color: var(--warn-ink); }
.kb-ev.b-attente .kb-chip { background: var(--warn-bg); color: var(--warn-ink); }
.kb-ev.b-ok .kb-ev-label { color: var(--ok-ink); }
.kb-ev.b-ok .kb-chip { background: var(--ok-bg); color: var(--ok-ink); }
.kb-ev.b-fait .kb-ev-label { color: var(--blue-dark); }
.kb-ev.b-fait .kb-chip { background: var(--blue-light); color: var(--blue-dark); }
.kb-ev.b-incident .kb-ev-label { color: var(--danger-ink); }
.kb-ev.b-incident .kb-chip { background: var(--danger-bg); color: var(--danger-ink); }

.badge.b-attente { background: var(--warn-bg); color: var(--warn-ink); }
.badge.b-ok { background: var(--ok-bg); color: var(--ok-ink); }
.badge.b-fait { background: var(--blue-light); color: var(--blue-dark); }
.badge.b-incident { background: var(--danger-bg); color: var(--danger-ink); }

.chrono-pliable summary { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; cursor: pointer; list-style: none; }
.chrono-pliable summary::before { content: '▸'; font-size: 11px; color: var(--grey-400); }
.chrono-pliable[open] summary::before { content: '▾'; }
.chrono-contenu { white-space: pre-wrap; background: var(--grey-100); border-radius: var(--radius-sm); padding: 10px 12px; margin: 6px 0 4px; font-size: 13px; }

.journal-form { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-top: 10px; }
.journal-form select, .journal-form input { padding: 8px 10px; border: 1px solid var(--grey-200); border-radius: var(--radius-sm); font-size: 13px; }
.journal-form input[list] { width: 110px; }

/* ---- Redesign carte pipeline (25/08 soir, valide sur maquette) ---- */
.kb-l1 { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
/* flex: none + nowrap : sans ca, une reference longue comprimait les dates et les
   cassait en deux lignes de trois caracteres. */
.kb-dates { font-family: var(--mono); font-size: 11px; color: var(--grey-400); flex: none; white-space: nowrap; }
/* Client et modele, sous la reference (02/09). Gris et non gras : la carte doit se
   lire de haut en bas, reference d'abord, pas trois informations de meme poids. */
.kb-sous { font-size: 13px; color: var(--grey-600); margin-top: 2px; line-height: 1.4; }
.kb-strip { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 8px; }
.kb-tag { font-size: 10.5px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: var(--grey-100); color: var(--grey-600); }
.kb-tag.t-ok { background: var(--blue-light); color: var(--blue-dark); font-family: var(--mono); font-weight: 400; }
.kb-tag.t-quiet { background: var(--grey-100); color: var(--grey-400); }
.kb-tag.t-warn { background: var(--warn-bg); color: var(--warn-ink); }
.kb-tag.t-bad { background: var(--danger-bg); color: var(--danger-ink); }
.kb-tag.t-violet { background: var(--violet-bg); color: var(--violet); }
.kb-plus summary { font-size: 11px; color: var(--grey-400); cursor: pointer; padding: 2px 0; list-style: none; }
.kb-plus summary::before { content: '▸ '; }
.kb-plus[open] summary::before { content: '▾ '; }
.kanban.compact .kb-chrono, .kanban.compact .meta, .kanban.compact .kb-dates { display: none; }
.kanban.compact .kb-card { padding: 8px 12px; }
.kanban.compact .kb-strip { margin-top: 5px; }

/* ---- Pipeline v15 : filtre par phase + colonnes vides amincies (30/08).
   Reponse au « trop de scroll » : un clic sur une phase ne montre que ses colonnes,
   et en vue Toutes, une colonne vide se replie en bandeau vertical de 44px.
   La structure du process reste visible, la largeur morte disparait. ---- */
.kb-phases { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px; }
.kb-phase { border: 1.5px solid var(--grey-200); background: var(--white); color: var(--grey-600);
  border-radius: 999px; padding: 5px 14px; font-size: 13px; font-weight: 600; cursor: pointer; }
.kb-phase:hover { border-color: var(--blue); color: var(--blue-dark); }
.kb-phase.on { background: var(--black); color: var(--white); border-color: var(--black); }
.kb-phase.quiet { color: var(--grey-400); }
/* Pastille « contient des bloquants » : un point rouge, jamais un second nombre,
   le compte de la phase est deja entre parentheses. */
.kb-phase .al { display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  background: var(--danger); margin-left: 7px; vertical-align: 1px; }
.kb-col-mince { flex: none; width: 44px; background: var(--grey-100); border: 1px solid var(--grey-200);
  border-radius: var(--radius); padding: 12px 0; display: flex; flex-direction: column; align-items: center;
  gap: 10px; min-height: 200px; cursor: pointer; }
.kb-col-mince:hover { border-color: var(--blue); }
.kb-col-mince:hover .mince-t { color: var(--blue-dark); }
.kb-col-mince .mince-n { font-family: var(--mono); font-size: 11px; color: var(--grey-400); }
.kb-col-mince .mince-c { font-family: var(--mono); font-size: 10px; color: var(--grey-600);
  background: var(--grey-200); border-radius: 999px; padding: 1px 6px; }
.kb-col-mince .mince-t { writing-mode: vertical-rl; font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; color: var(--grey-400); white-space: nowrap; }

/* ---- Carte pipeline v15 (30/08) : la representation du bloc de la maquette Lukas.
   Pastille verte = fait, horodatage reel · grise = pas encore fait · cercle rouge = bloquant.
   Les lignes MAIL / SMS avec un contenu enregistre se deplient dessus. ---- */
/* Echelle relevee le 02/09 : 12px sur 1.45 avec des horodatages a 10px se lisait mal
   sur une colonne etroite, remarque de Gauthier a la relecture du pipeline. Une carte
   gagne environ 12px de haut, ce qui reste sous la hauteur d'une colonne. */
.kb15 { margin-top: 9px; padding-top: 8px; border-top: 1px solid var(--grey-100); display: flex; flex-direction: column; }
.kb15-li, .kb15-fold summary { display: flex; align-items: baseline; gap: 8px; font-size: 13px; line-height: 1.55; padding: 3px 0; }
.kb15-fold summary { cursor: pointer; list-style: none; }
.kb15-fold summary::-webkit-details-marker { display: none; }
/* inline-block : hors des cartes (legende), un span inline ignorerait width/height
   et la version rouge degenerait en trait vertical. */
.kb15-dot { display: inline-block; flex: none; width: 9px; height: 9px; border-radius: 50%;
  background: var(--ok); align-self: center; vertical-align: -1px; }
.kb15-dot.g { background: var(--grey-200); }
.kb15-dot.r { background: var(--white); border: 2.5px solid var(--danger); width: 8px; height: 8px; }
.kb15-l { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb15-li.fut .kb15-l { color: var(--grey-600); }
.kb15-l.bad { color: var(--danger-ink); font-weight: 600; }
.kb15-t { flex: none; margin-left: auto; font-family: var(--mono); font-size: 11px; color: var(--grey-600); padding-left: 6px; }
.kb15-fold summary .kb15-l { color: var(--blue-dark); }
.kb15-fold summary:hover .kb15-l { text-decoration: underline; }
.kb15-msg { background: var(--blue-light); border: 1px solid #cbdcfb; border-radius: var(--radius-sm); padding: 9px 11px; margin: 4px 0 6px 16px; font-size: 12px; white-space: pre-wrap; color: var(--text); }
.kanban.compact .kb15 { display: none; }

/* ---- Colonnes V11 + parcours par carte (26/08, alignement Pipeline Global V11) ---- */
.kb-col-taches { padding: 6px 14px; font-size: 11px; color: var(--grey-400); border-bottom: 1px solid var(--grey-200); line-height: 1.5; }
.kb-vide { color: var(--grey-400); text-align: center; font-size: 13px; padding: 8px; }
.kb-parcours { margin-top: 8px; border-top: 1px solid var(--grey-100); padding-top: 6px; }
.kb-jl { display: flex; gap: 6px; align-items: baseline; font-size: 11.5px; padding: 1px 0; color: var(--grey-600); white-space: nowrap; overflow: hidden; }
.kb-jl-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--grey-200); align-self: center; }
.kb-jl.ok .kb-jl-dot { background: var(--ok); }
.kb-jl.file .kb-jl-dot { background: #e08c00; }
.kb-jl.absent .kb-jl-dot { background: #fff; border: 2px solid var(--danger); }
.kb-jl.ok .kb-jl-t { color: var(--text); }
.kb-jl.file .kb-jl-t { color: var(--warn-ink); font-weight: 700; }
.kb-jl.absent .kb-jl-t { color: var(--danger-ink); }
.kb-jl.futur { opacity: .55; }
.kb-jl-d { font-size: 10.5px; color: var(--grey-400); overflow: hidden; text-overflow: ellipsis; }
.kb-jl.absent .kb-jl-d { color: var(--danger-ink); opacity: .85; }
.kb-next { margin-top: 6px; font-size: 11.5px; font-weight: 700; color: var(--warn-ink); background: var(--warn-bg); border-radius: 6px; padding: 4px 8px; }
.kanban.compact .kb-parcours { display: none; }

/* Cases de verification du questionnaire Nouvel appareil (Q9-Q10 V11, 26/08) */
.intake-check { display: flex; gap: 8px; align-items: center; font-size: 13px; padding: 3px 0; cursor: pointer; }
.intake-check input { width: 15px; height: 15px; }

/* Machine vendue : la ligne reste au planning, barree (Lukas 26/08). */
.g-machine.g-vendu { opacity: .55; }
.g-machine.g-vendu .m-name { text-decoration: line-through; }

/* Glisser le calendrier (retour Karol 26/08) : pas de selection de texte pendant le drag. */
#gantt { user-select: none; cursor: grab; }
#gantt:active { cursor: grabbing; }

/* Board pipeline : defilement au glisser, sans fleches (retour Saad 27/08). */
.kanban { cursor: grab; user-select: none; }
.kanban:active { cursor: grabbing; }

/* ---- Saisie de l'etat des lieux (edl-form.js) ----
   Plein ecran plutot qu'un panneau lateral : la saisie est sequentielle, une section a la
   fois, et l'operateur a les mains prises par l'exosquelette qu'il controle. Tout ce qui
   n'est pas la section en cours est une occasion de se tromper de ligne. */
.edl-backdrop { position: fixed; inset: 0; background: rgba(13,13,13,.45); z-index: 60; }
.edl {
  position: fixed; inset: 3vh 50% auto auto; transform: translateX(50%);
  width: min(880px, 94vw); max-height: 94vh; z-index: 61;
  display: flex; flex-direction: column;
  background: var(--white); border-radius: var(--radius); box-shadow: var(--shadow-lg);
}
.edl-head {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 18px; border-bottom: 1px solid var(--line);
}
.edl-head > div:first-child { display: flex; flex-direction: column; }
.edl-sub { color: var(--grey-400); font-size: 13px; }
.edl-etape { margin-left: auto; color: var(--grey-600); font-size: 13px; }
.edl-body { overflow-y: auto; padding: 18px; display: flex; flex-direction: column; gap: 14px; }
.edl-card { border: 1px solid var(--line); border-radius: var(--radius-md); padding: 16px; }
.edl-card h3 { margin: 0 0 12px; font-size: 16px; }
.edl-note { color: var(--grey-600); font-size: 13px; margin: 10px 0 0; }
.edl-foot {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 18px; border-top: 1px solid var(--line);
}
.edl-msg { flex: 1; font-size: 13px; color: var(--warn-ink); }

.edl-point { padding: 10px 0; border-bottom: 1px solid var(--grey-100); }
.edl-point:last-of-type { border-bottom: 0; }
.edl-point.sig { background: var(--danger-bg); margin: 0 -16px; padding: 10px 16px; border-radius: var(--radius-sm); }
.edl-point-haut { display: flex; align-items: center; gap: 14px; }
.edl-point-lib { flex: 1; }
.edl-etats { display: flex; gap: 6px; flex-shrink: 0; }
.edl-etat {
  border: 1px solid var(--grey-200); background: var(--white); color: var(--grey-600);
  border-radius: var(--radius-sm); padding: 6px 12px; font: inherit; font-size: 13px; cursor: pointer;
}
.edl-etat.on { background: var(--ok-bg); border-color: var(--ok); color: var(--ok-ink); font-weight: 600; }
.edl-etat.rouge.on { background: var(--danger-bg); border-color: var(--danger); color: var(--danger-ink); }
.edl-signale { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.edl-req { color: var(--danger-ink); font-size: 12px; }
.edl-choix { display: flex; gap: 16px; flex-wrap: wrap; }
.edl-choix.col { flex-direction: column; gap: 8px; }
.edl-question { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.edl-question-lib { font-weight: 600; margin-bottom: 8px; }
.edl-sinon { margin-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.edl-total { margin: 12px 0; padding: 10px 12px; background: var(--blue-light); border-radius: var(--radius-sm); }

/* ---- Prises de vue de l'etat des lieux ----
   « Comme les applications » (Lukas, 12/09) : un bouton qui declenche l'appareil photo et
   l'apercu du cliche juste en dessous. Les onze restent toutes affichees, l'operateur
   choisit laquelle il prend et laquelle il refait. Les cibles sont volontairement hautes :
   la saisie se fait au telephone, en entrepot, souvent gante. */
.edl-photo { display: flex; flex-direction: column; gap: 10px; }
.edl-photo-bouton { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.edl-photo-bouton .btn { min-height: 44px; }
.edl-photo-statut { font-size: 13px; }
.edl-photo-apercu {
  align-self: flex-start; max-width: 100%; max-height: 320px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); object-fit: contain;
}
.edl-photo-compteur { margin: 12px 0 10px; font-size: 14px; }
/* minmax plus large que .field-grid : chaque prise de vue porte deux boutons, un apercu
   et son lien. A 210px les boutons passaient a la ligne un par un. */
.edl-photo-liste {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 18px;
}
