/*!
 * Project Control Center
 * Copyright 2026 LS CORP. Tous droits reserves.
 *
 * Licence proprietaire — voir LICENCE.md. Reproduction, redistribution et
 * creation d oeuvres derivees interdites sans autorisation ecrite de LS CORP.
 */
/* ==========================================================================
   Chantier — design system
   Langage visuel repris des maquettes SecuRoad V4/V5 :
   sidebar navy, accent teal, cartes claires, fiche 360 orientée décision.
   Tout passe par des variables : changer la palette = changer :root.
   ========================================================================== */

/* --- 1. Jetons ----------------------------------------------------------- */
:root {
  color-scheme: light;

  --bg:        #f3f5f7;
  --surface:   #ffffff;
  --surface-2: #f8fafb;
  --surface-3: #eef2f4;
  --line:      #dfe5e9;
  --line-2:    #edf0f2;

  --text:       #17212b;
  --text-muted: #697782;
  --text-faint: #8b969f;

  --nav-top:    #172530;
  --nav-bottom: #101920;
  --nav-item:   #cad5dc;
  --nav-hover:  #22323f;
  --nav-label:  #6f8290;

  --accent:      #0b8e95;
  --accent-deep: #117983;
  --accent-hover:#097a80;
  --accent-soft: #e8f6f6;
  --accent-text: #ffffff;

  --ok:     #2d8b57;  --ok-soft:     #e8f5ed;
  --warn:   #b3760f;  --warn-soft:   #fff2db;
  --danger: #c94a4a;  --danger-soft: #fdecec;
  --info:   #3975cf;  --info-soft:   #eaf1ff;
  --purple: #7358bd;  --purple-soft: #f0ebff;
  --neutral:#53616c;  --neutral-soft:#eef2f4;

  --radius:    10px;
  --radius-sm: 8px;
  --radius-lg: 14px;
  --shadow:    0 1px 5px rgba(0, 0, 0, .04);
  --shadow-lg: 0 14px 38px rgba(12, 24, 35, .16);

  --sidebar-w: 258px;
  --topbar-h:  66px;

  --font: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  --mono: "SFMono-Regular", ui-monospace, "Cascadia Mono", Consolas, monospace;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg:        #121a20;
    --surface:   #1a242c;
    --surface-2: #212d36;
    --surface-3: #2a3740;
    --line:      #2c3a44;
    --line-2:    #26333c;
    --text:       #e6edf1;
    --text-muted: #9aabb6;
    --text-faint: #6e8290;
    --accent:      #2bb3ba;
    --accent-deep: #55c9cf;
    --accent-hover:#3ec3c9;
    --accent-soft: #10333a;
    --accent-text: #06181b;
    --ok:     #4cb97d;  --ok-soft:     #14301f;
    --warn:   #d9a13f;  --warn-soft:   #33270f;
    --danger: #e7726f;  --danger-soft: #3a1c1c;
    --info:   #6e9ce8;  --info-soft:   #16233a;
    --purple: #9d86e0;  --purple-soft: #241d3a;
    --neutral:#93a3ad;  --neutral-soft:#253138;
    --shadow:    0 1px 5px rgba(0, 0, 0, .35);
    --shadow-lg: 0 14px 38px rgba(0, 0, 0, .5);
  }
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --bg:        #121a20;
  --surface:   #1a242c;
  --surface-2: #212d36;
  --surface-3: #2a3740;
  --line:      #2c3a44;
  --line-2:    #26333c;
  --text:       #e6edf1;
  --text-muted: #9aabb6;
  --text-faint: #6e8290;
  --accent:      #2bb3ba;
  --accent-deep: #55c9cf;
  --accent-hover:#3ec3c9;
  --accent-soft: #10333a;
  --accent-text: #06181b;
  --ok:     #4cb97d;  --ok-soft:     #14301f;
  --warn:   #d9a13f;  --warn-soft:   #33270f;
  --danger: #e7726f;  --danger-soft: #3a1c1c;
  --info:   #6e9ce8;  --info-soft:   #16233a;
  --purple: #9d86e0;  --purple-soft: #241d3a;
  --neutral:#93a3ad;  --neutral-soft:#253138;
  --shadow:    0 1px 5px rgba(0, 0, 0, .35);
  --shadow-lg: 0 14px 38px rgba(0, 0, 0, .5);
}

/* --- 2. Base ------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.45;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent-deep); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 { margin: 0; font-weight: 700; line-height: 1.2; }
h1 { font-size: 26px; letter-spacing: -.015em; }
h2 { font-size: 15px; }
h3 { font-size: 14px; }

p { margin: 0 0 10px; }
code, .mono { font-family: var(--mono); font-size: .9em; }
::selection { background: var(--accent-soft); }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

/* --- 3. Coque applicative ------------------------------------------------ */
/* La fenêtre ne défile pas : c'est la zone de contenu qui défile, sous une
   tête de page qui reste en place. Le menu et le titre restent donc toujours
   visibles, quelle que soit la longueur de l'écran. */
.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  grid-template-areas: "sidebar main";
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

.sidebar {
  grid-area: sidebar;
  display: flex;
  flex-direction: column;
  background: linear-gradient(var(--nav-top), var(--nav-bottom));
  color: var(--nav-item);
  padding: 18px 13px 0;
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  overflow-y: auto;
}

.main {
  grid-area: main;
  min-width: 0;
  display: flex;
  flex-direction: column;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

.brand {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 4px 8px 19px;
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}
.brand-mark {
  width: 40px; height: 40px; flex: 0 0 40px;
  border-radius: 9px;
  background: var(--accent);
  color: #fff;
  display: grid; place-items: center;
  font-weight: 800; font-size: 15px;
}
.brand-name { color: #fff; font-size: 17px; font-weight: 700; display: block; }
.brand-sub  { color: #8ea0ae; font-size: 11.5px; display: block; }

/* Le nom prend la place, la bascule de thème se range à droite. */
.brand > div { flex: 1; min-width: 0; }
.brand .foot-theme { margin-right: -4px; }

/* --- 4. Navigation ------------------------------------------------------- */
.nav-group { margin-bottom: 4px; }
/* dégagement pour que le pied collant ne masque jamais le dernier lien */
.nav-group:last-of-type { margin-bottom: 58px; }
.nav-label {
  margin: 20px 10px 7px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 1.1px;
  text-transform: uppercase;
  color: var(--nav-label);
}
.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 11px;
  margin: 2px 0;
  border-radius: var(--radius-sm);
  color: var(--nav-item);
  text-decoration: none;
  font-size: 13.5px;
}
.nav-item:hover { background: var(--nav-hover); color: #fff; text-decoration: none; }
.nav-item.is-active {
  background: var(--nav-hover);
  color: #fff;
  font-weight: 600;
  box-shadow: inset 3px 0 var(--accent);
}
.nav-item .ico { width: 16px; flex: 0 0 16px; opacity: .9; }
.nav-item .count {
  margin-left: auto;
  padding: 2px 7px;
  border-radius: 20px;
  background: rgba(255, 255, 255, .09);
  font-size: 10px;
  font-variant-numeric: tabular-nums;
}

/* Reste visible même quand la navigation déborde : collé en bas du panneau.
   Porte l'identité de la personne connectée et la version. */
.sidebar-foot {
  position: sticky;
  bottom: 0;
  margin: auto -13px 0;
  padding: 12px 16px 14px;
  background: var(--nav-bottom);
  border-top: 1px solid rgba(255, 255, 255, .08);
  font-size: 11px;
  color: var(--nav-label);
}
.sidebar-foot .user-side {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px;
  margin: -6px -6px 10px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.sidebar-foot .user-side:hover { background: rgba(255, 255, 255, .07); }
/* Le bloc du nom ouvre « Mon compte ». C'est donc un bouton — atteignable au
   clavier — mais il ne doit pas en avoir l'air : le navigateur lui donnerait
   sinon un fond, une bordure et sa propre police. */
.sidebar-foot button.user-side {
  width: 100%;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
}
.sidebar-foot .user-side .nom { display: block; font-size: 12.5px; font-weight: 650; color: #fff; }
.sidebar-foot .user-side .grp { display: block; font-size: 10.5px; color: #8ea0ae; }
/* Deux pastilles côte à côte : la version et le lien « Données ». Le retour à
   la ligne est autorisé — la barre latérale se resserre sur petit écran, et
   deux pastilles serrées valent mieux qu'une coupée. */
.sidebar-foot .foot-meta {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 6px;
}

/* Le lien de confidentialité emprunte l'habit de la pastille de version, sans
   sa pastille verte : celle-ci dit « l'application tourne », ce qu'un lien vers
   un document n'a pas à annoncer. */
.lien-confid { text-decoration: none; }
.lien-confid::before { display: none; }
.sidebar-foot .ver-chip {
  border-color: rgba(255, 255, 255, .14);
  background: rgba(255, 255, 255, .07);
  color: #cfe3e4;
}
.sidebar-foot .ver-chip:hover { border-color: var(--accent); color: #fff; }
.sidebar-foot .ver {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 8px;
  border-radius: 20px;
  background: rgba(255, 255, 255, .07);
  color: #cfe3e4;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.sidebar-foot .date { display: block; margin-top: 6px; }

/* --- 4 bis. Sélecteur de société et recherche, dans le menu --------------- */
.sidebar-switcher {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  margin: 14px 0 9px;
  padding: 8px 10px;
  font: inherit;
  font-size: 12.5px;
  text-align: left;
  color: #e3ebf0;
  background: rgba(255, 255, 255, .06);
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.sidebar-switcher:hover { background: rgba(255, 255, 255, .11); }
.sidebar-switcher .lieu { flex: 1; min-width: 0; line-height: 1.25; }
.sidebar-switcher .soc { display: block; font-weight: 650; }
.sidebar-switcher .ctx { display: block; font-size: 10.5px; color: #8ea0ae; }
.sidebar-switcher .caret { color: #8ea0ae; font-size: 10px; }

.sidebar-search {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 10px;
  font: inherit;
  font-size: 12.5px;
  text-align: left;
  color: #94a5b1;
  background: rgba(0, 0, 0, .22);
  border: 1px solid rgba(255, 255, 255, .07);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.sidebar-search:hover { border-color: rgba(255, 255, 255, .18); color: #cfe3e4; }
.sidebar-search .txt { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-search kbd {
  font-family: var(--font);
  font-size: 10px;
  padding: 1px 5px;
  border: 1px solid rgba(255, 255, 255, .14);
  border-radius: 4px;
}

/* cloche de notifications, au pied du menu */
.foot-bell {
  position: relative;
  padding: 6px 9px;
  font-size: 14px;
  line-height: 1;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .12);
  border-radius: var(--radius-sm);
  color: #cfe3e4;
  cursor: pointer;
}
.foot-bell:hover { border-color: var(--accent); }
.foot-bell .n {
  position: absolute;
  top: -6px; right: -6px;
  min-width: 16px; height: 16px;
  padding: 0 4px;
  border-radius: 8px;
  background: var(--danger);
  color: #fff;
  font-size: 9.5px; font-weight: 800;
  line-height: 16px;
  text-align: center;
}
.sidebar-foot .user-side { flex: 1; }
.sidebar-foot .ligne-user { display: flex; align-items: center; gap: 9px; margin-bottom: 10px; }

/* --- 5. Barre supérieure (retirée des écrans, conservée pour mémoire) ----- */
.topbar {
  height: var(--topbar-h);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 20px;
  position: sticky;
  top: 0;
  z-index: 10;
}
.topbar-spacer { flex: 1; }

.search {
  flex: 1;
  max-width: 620px;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 13px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 9px;
  color: var(--text-faint);
  font-size: 13px;
}
.search kbd {
  margin-left: auto;
  font-family: var(--font);
  font-size: 10.5px;
  padding: 1px 6px;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--surface);
}

.switcher {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 11px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
}
.switcher:hover { border-color: var(--text-faint); }
.switcher-avatar {
  width: 21px; height: 21px;
  border-radius: 5px;
  background: var(--purple);
  color: #fff;
  display: grid; place-items: center;
  font-size: 10px; font-weight: 800;
}
.switcher .sep   { color: var(--text-faint); }
.switcher .caret { color: var(--text-faint); font-size: 10px; }

/* Identité de la personne connectée, dans la barre du haut */
.user-chip {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 4px 10px 4px 4px;
  border-radius: 22px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  cursor: pointer;
}
.user-chip:hover { border-color: var(--border-strong); }
.user-chip .who { line-height: 1.2; }
.user-chip .nom { display: block; font-size: 12.5px; font-weight: 650; }
.user-chip .grp { display: block; font-size: 10.5px; color: var(--text-muted); }
@media (max-width: 1100px) { .user-chip .who { display: none; } }

/* Pastille de version dans la barre du haut */
.ver-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 20px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 700;
  color: var(--text-muted);
  cursor: pointer;
}
.ver-chip::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--ok);
}
.ver-chip:hover { border-color: var(--accent); color: var(--accent-deep); }

.avatar {
  width: 34px; height: 34px; flex: 0 0 34px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  display: grid; place-items: center;
  font-size: 12px; font-weight: 700;
}
.avatar.sm   { width: 24px; height: 24px; flex-basis: 24px; font-size: 10px; }
.avatar.gray { background: var(--surface-3); color: var(--text-muted); }

/* --- 6. Contenu ---------------------------------------------------------- */
.content { padding: 22px; flex: 1; min-height: 0; overflow-y: auto; }

/* Tête fixe : hors de la zone défilante, elle ne bouge jamais. */
.page-head {
  flex: none;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  padding: 18px 22px 15px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.page-head .grow { flex: 1; min-width: 0; }
.page-sub { margin-top: 6px; color: var(--text-muted); font-size: 13px; }
.breadcrumb { font-size: 12px; color: var(--text-faint); margin-bottom: 6px; }
.breadcrumb a { color: var(--text-muted); }

/* --- 7. Boutons ---------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 13px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover { background: var(--surface-2); text-decoration: none; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn-dark { background: #22313d; border-color: #22313d; color: #fff; }
.btn-dark:hover { background: #2c3e4c; }
.btn-ghost { background: transparent; border-color: transparent; color: var(--text-muted); }
.btn-ghost:hover { background: var(--surface-2); color: var(--text); }
.btn-danger { background: var(--danger-soft); border-color: var(--danger-soft); color: var(--danger); }
.btn-danger:hover { border-color: var(--danger); }
.btn-block { width: 100%; justify-content: center; padding: 11px; font-size: 14px; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn-sm { padding: 6px 10px; font-size: 12px; }

/* --- 8. Cartes ----------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  min-width: 0;
}
.card-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line-2);
}
.card-head .grow { flex: 1; min-width: 0; }
.card-body { padding: 15px; }
.card-foot {
  padding: 11px 16px;
  border-top: 1px solid var(--line-2);
  background: var(--surface-2);
  border-radius: 0 0 var(--radius) var(--radius);
  font-size: 12px;
  color: var(--text-muted);
}

/* --- 9. Grilles ---------------------------------------------------------- */
.grid { display: grid; gap: 13px; }
.grid-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-2-1 { grid-template-columns: 1.5fr 1fr; }

/* Santé à gauche, le reste à droite. Ces deux-là étaient en style inline :
   passés en classes pour que l'adaptatif puisse les empiler, il leur fallait
   aussi leur règle de base — sans elle, tout retombait en une colonne. */
.grid-sante2 { grid-template-columns: 300px minmax(0, 1fr); }
.grid-sante3 { grid-template-columns: 280px minmax(0, 1fr) 320px; }
.grid-1-2 { grid-template-columns: 1fr 1.5fr; }

.stack { display: flex; flex-direction: column; gap: 13px; }
.row { display: flex; align-items: center; gap: 9px; }
.row.wrap { flex-wrap: wrap; }
.row.top { align-items: flex-start; }
.row .grow { flex: 1; min-width: 0; }

/* --- 10. Tuiles KPI ------------------------------------------------------ */
.kpi { padding: 14px 15px; }
.kpi-label { font-size: 11px; color: var(--text-muted); margin-bottom: 9px; font-weight: 500; }
.kpi-value {
  font-size: 21px;
  font-weight: 800;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}
.kpi-value .unit { font-size: 14px; font-weight: 600; color: var(--text-muted); }
.kpi-note { display: block; margin-top: 7px; font-size: 11.5px; color: var(--text-muted); }
.kpi-note.up   { color: var(--ok); }
.kpi-note.down { color: var(--danger); }

.t-ok { color: var(--ok); } .t-warn { color: var(--warn); }
.t-danger { color: var(--danger); } .t-accent { color: var(--accent-deep); }
/* Les deux dernières de l'échelle des statuts : bleu « c'est daté », violet
   « rien n'est parti ». Voir Planning::badge(), qui est la seule table. */
.t-info { color: var(--info); } .t-purple { color: var(--purple); }
.pos { color: var(--ok); } .neg { color: var(--warn); }

/* Une perte n'est pas une marge basse : même taille que le reste, mais
   rouge vif et en gras — le tableau reste lisible, la perte se repère. */
.perte { color: var(--danger); font-weight: 800; }

/* --- 11. Pastilles ------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 9px;
  border-radius: 20px;
  font-size: 10.5px;
  font-weight: 800;
  letter-spacing: .01em;
  white-space: nowrap;
  background: var(--neutral-soft);
  color: var(--neutral);
}
.badge.ok     { background: var(--ok-soft);     color: var(--ok); }
.badge.warn   { background: var(--warn-soft);   color: var(--warn); }
.badge.danger { background: var(--danger-soft); color: var(--danger); }
.badge.info   { background: var(--info-soft);   color: var(--info); }
.badge.accent { background: var(--accent-soft); color: var(--accent-deep); }
.badge.purple { background: var(--purple-soft); color: var(--purple); }

.dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: 0 0 6px; }

/* --- 11 bis. L'état porté par le menu lui-meme ----------------------------
   Le parcours administratif montrait un menu deroulant *et* une pastille a
   cote : deux objets pour un seul etat, et rien ne disait lequel faisait foi.
   Le menu se teinte maintenant tout seul.

   Les fonds restent les variantes « soft » : un tableau de dix lignes toutes
   teintees se lit encore, ce qui ne serait pas le cas avec des aplats vifs.

   Deux vocabulaires partagent l'echelle — celui des demarches et celui du
   chantier — parce que les deux tableaux se lisent du meme oeil :

     violet  rien n'est parti      a-faire · a-planifier
     jaune   c'est engage          introduit · planifie · prevu
     bleu    c'est en train        en-cours
     vert    c'est acquis          termine · fait
     rouge   il faut y retourner   refuse · bloque · en-retard */
.sel-etat { font-weight: 700; }
.sel-etat[data-etat="a-faire"],
.sel-etat[data-etat="a-planifier"] { background: var(--purple-soft); color: var(--purple); }
.sel-etat[data-etat="planifie"],
.sel-etat[data-etat="prevu"]       { background: var(--info-soft);   color: var(--info); }
.sel-etat[data-etat="introduit"],
.sel-etat[data-etat="en-cours"]    { background: var(--warn-soft);   color: var(--warn); }
.sel-etat[data-etat="termine"],
.sel-etat[data-etat="fait"]        { background: var(--ok-soft);     color: var(--ok); }
.sel-etat[data-etat="refuse"],
.sel-etat[data-etat="bloque"],
.sel-etat[data-etat="en-retard"]   { background: var(--danger-soft); color: var(--danger); }

/* Les options du menu ouvert. Windows et Linux les peignent ; macOS les rend
   a sa facon et les ignore — le menu ferme, lui, est teinte partout, et c'est
   celui qu'on lit dans un tableau. */
.sel-etat option { background: var(--surface); color: var(--text); font-weight: 600; }
.sel-etat option[value="À faire"],
.sel-etat option[value="À planifier"] { background: var(--purple-soft); color: var(--purple); }
.sel-etat option[value="Planifié"]    { background: var(--info-soft);   color: var(--info); }
.sel-etat option[value="Introduit"],
.sel-etat option[value="En cours"]    { background: var(--warn-soft);   color: var(--warn); }
.sel-etat option[value="Terminé"],
.sel-etat option[value="Fait"]        { background: var(--ok-soft);     color: var(--ok); }
.sel-etat option[value="Refusé"],
.sel-etat option[value="Bloqué"]      { background: var(--danger-soft); color: var(--danger); }

/* En lecture seule il n'y a pas de menu a teinter : le mot porte sa couleur. */
.etat-mot                  { font-weight: 800; }
.etat-mot.etat-a-faire,
.etat-mot.etat-a-planifier { color: var(--purple); }
.etat-mot.etat-planifie,
.etat-mot.etat-prevu       { color: var(--info); }
.etat-mot.etat-introduit,
.etat-mot.etat-en-cours    { color: var(--warn); }
.etat-mot.etat-termine,
.etat-mot.etat-fait        { color: var(--ok); }
.etat-mot.etat-refuse,
.etat-mot.etat-bloque,
.etat-mot.etat-state,
.etat-mot.etat-annule,
.etat-mot.etat-en-retard   { color: var(--danger); }

.tag {
  display: inline-flex;
  padding: 2px 7px;
  border: 1px solid var(--line);
  border-radius: 5px;
  font-size: 11px;
  color: var(--text-muted);
  background: var(--surface);
}

/* --- 12. Tableaux --------------------------------------------------------
   Un tableau long défile dans son propre cadre, en-tête figée : le reste de
   l'écran — titres, onglets, pieds de carte — ne bouge pas. */
.table-wrap { overflow: auto; max-height: 62vh; }

/* Un tableau qu'on **lit** d'un bout à l'autre, au lieu de le consulter ligne
   à ligne : il défile en largeur quand l'écran est étroit, et jamais en
   hauteur. C'est ce qui le distingue de « .table-wrap », dont le plafond de
   62vh a du sens pour un registre de mille lignes et aucun pour un document
   qu'on parcourt — un inventaire de destinataires qu'il faudrait faire défiler
   dans une fenêtre de 300 px ne se lit pas.
   Sans conteneur du tout, cinq colonnes de prose sur un téléphone ne
   débordent pas : elles se compriment en cinq rubans d'un mot de large. C'est
   pire qu'un débordement, parce que rien ne signale que le tableau est devenu
   illisible — la page a l'air correcte. */
.table-large { overflow-x: auto; }
.table-large > .tbl { min-width: 620px; }

table.tbl { width: 100%; border-collapse: separate; border-spacing: 0; }
.tbl th {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: 10px 13px;
  text-align: left;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .35px;
  text-transform: uppercase;
  color: #67737d;
  white-space: nowrap;
}
.tbl td {
  padding: 11px 13px;
  border-bottom: 1px solid var(--line-2);
  font-size: 12.5px;
  vertical-align: middle;
}
/* **Ce qui ne se voit pas mais s'entend.** Une colonne d'icônes a besoin d'un
   en-tête : sans lui, un lecteur d'écran annonce une colonne sans nom, et le
   tableau entier devient plus difficile à parcourir. Mais le mot n'a rien à
   faire à l'écran — l'icône se comprend seule. La règle classique : on sort
   l'élément du flux sans le retirer de l'arbre d'accessibilité, ce que
   « display:none » ferait. */
.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;
}

/* **Un en-tête de ligne n'est pas un en-tête de colonne.** Dans un tableau
   clef/valeur — « PHP : 8.3.2 » — la première cellule est bien un en-tête, et
   c'est ce que « th scope="row" » dit à un lecteur d'écran : il annonce alors
   « PHP, 8.3.2 » au lieu de deux cellules sans rapport. Mais la règle ci-dessus
   le rendrait collant, minuscule et en capitales, parce qu'elle est écrite pour
   la ligne de titre. On lui redonne l'allure d'une cellule ordinaire, un peu
   plus appuyée. */
.tbl tbody th {
  position: static;
  z-index: auto;
  padding: 11px 13px;
  background: transparent;
  border-bottom: 1px solid var(--line-2);
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: normal;
  text-transform: none;
  color: var(--text);
  white-space: normal;
}
.tbl tbody tr:hover th { background: var(--surface-2); }
.tbl tbody tr:last-child th { border-bottom: none; }
.tbl tbody tr:hover td { background: var(--surface-2); }
.tbl tbody tr:last-child td { border-bottom: none; }
.tbl .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tbl .strong { font-weight: 700; }
.tbl .id, .ref { color: var(--accent-deep); font-weight: 800; font-size: 12.5px; }
/* Jalon contractuel et interventions qui l'ont produit : deux niveaux de
   lecture dans un seul tableau. */
.tbl-jalons tr.jalon td { border-top: 1px solid var(--line); }
.tbl-jalons tr.jalon:first-child td { border-top: none; }
.tbl-jalons tr.intervention td { color: var(--text-muted); font-size: 12px; }
.tbl-jalons tr.intervention td:nth-child(2) { padding-left: 30px; position: relative; }
.tbl-jalons tr.intervention td:nth-child(2)::before {
  content: "";
  position: absolute;
  left: 14px; top: 50%;
  width: 8px; height: 1px;
  background: var(--line);
}

.tbl-group td {
  background: var(--surface-3);
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .35px;
  color: var(--text-muted);
  padding: 7px 13px;
}

/* --- 13. Jauges ---------------------------------------------------------- */
.bar {
  height: 7px;
  min-width: 60px;
  background: var(--surface-3);
  border-radius: 10px;
  overflow: hidden;
}
.bar > span { display: block; height: 100%; background: var(--accent); border-radius: 10px; }
.bar > span.ok { background: var(--ok); }
.bar > span.warn { background: var(--warn); }
.bar > span.danger { background: var(--danger); }

/* Frise opérationnelle (fiche marché) : même barre, mais sur une piste qui
   porte un repère. « .bar » coupe ce qui dépasse et ne sert que de jauge ; ici
   il faut poser un trait à une date, donc un contexte positionné. */
.frise-piste {
  position: relative;
  /* Plus épaisse que la jauge « .bar » de sept pixels dont elle vient : celle-ci
     accompagne un chiffre déjà lisible à côté, la frise EST l'information, et
     elle se lit à vingt lignes de distance. */
  height: 10px;
  min-width: 60px;
  background: var(--surface-3);
  border-radius: 10px;
}
.frise-piste > span {
  position: absolute;
  top: 0;
  height: 100%;
  background: var(--accent);
  border-radius: 10px;
}
.frise-piste > span.ok { background: var(--ok); }
.frise-piste > span.warn { background: var(--warn); }
.frise-piste > span.danger { background: var(--danger); }
.frise-piste > span.info { background: var(--info); }
.frise-piste > span.purple { background: var(--purple); }
/* La période statée, hachurée par-dessus la barre. Hachures et non aplat : un
   aplat de plus aurait fait une quatrième couleur à retenir, alors que la
   hachure se lit sans légende — c'est du temps rayé du délai. Même geste que la
   frise de la fiche chantier dans la maquette. */
.frise-state {
  position: absolute;
  top: 0;
  height: 100%;
  border-radius: 3px;
  /* Creux opaques et non transparents : au-dessus d'une barre verte, un creux
     transparent aurait laissé voir le vert — un délai qui court là où il est
     suspendu. */
  background: repeating-linear-gradient(
    -45deg,
    var(--warn) 0 4px,
    var(--surface-3) 4px 8px
  );
  box-shadow: inset 0 0 0 1px var(--warn);
  z-index: 2;
}

/* Le trait du jour dépasse la piste en haut et en bas : posé à l'intérieur, il
   se serait confondu avec la barre qu'il traverse. */
.frise-jour {
  position: absolute;
  top: -3px;
  bottom: -3px;
  width: 2px;
  margin-left: -1px;
  background: var(--danger);
  border-radius: 2px;
  opacity: .8;
}
.frise-axe {
  position: relative;
  height: 15px;
  margin-top: 3px;
  font-weight: 400;
}
.frise-axe > span {
  position: absolute;
  top: 0;
  font-size: 10px;
  white-space: nowrap;
  color: var(--text-muted);
}
.frise-axe > .deb { left: 0; }
.frise-axe > .fin { right: 0; }
.frise-axe > .auj {
  transform: translateX(-50%);
  color: var(--danger);
  font-weight: 600;
}
.frise-hors {
  font-size: 10px;
  font-weight: 400;
  color: var(--text-muted);
  margin-top: 3px;
}

/* Flux financier : commandé → facturé → payé, en une barre segmentée */
.flow {
  display: flex;
  height: 12px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--surface-3);
}
.flow > span { display: block; height: 100%; }
.flow > span.paye    { background: var(--ok); }
.flow > span.facture { background: var(--accent); }
.flow > span.encours { background: var(--warn); }
/* --- Jauge d'enveloppe ----------------------------------------------------
   Un marché à bordereau se lit sur un axe : de zéro au plafond, avec le
   plancher quelque part au milieu. Une barre de pourcentage seule ne disait ni
   où était ce plancher, ni combien il restait — juste « 61,9 % », qui ne
   répond à aucune question qu'on se pose devant une commande à engager.

   La jauge porte donc trois choses sur le même axe : ce qui est commandé, le
   plancher en curseur, et les montants aux deux bouts.                      */
.jauge {
  position: relative;
  height: 26px;
  background: var(--surface-3);
  border-radius: 6px;
  overflow: visible;
  margin: 6px 0 2px;
}
.jauge > .rempli {
  position: absolute; inset: 0 auto 0 0;
  background: var(--accent);
  border-radius: 6px 0 0 6px;
  max-width: 100%;
}
.jauge > .rempli.depasse { background: var(--danger); border-radius: 6px; }

/* Le curseur du plancher : un trait plein qui traverse la jauge, avec son
   étiquette au-dessus. Un repère qu'on ne peut pas confondre avec le
   remplissage. */
.jauge > .curseur {
  position: absolute; top: -5px; bottom: -5px;
  width: 2px;
  background: var(--text);
  border-radius: 2px;
}
.jauge > .curseur::after {
  content: attr(data-lab);
  position: absolute; bottom: calc(100% + 3px); left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: 10.5px; font-weight: 700;
  color: var(--text-faint);
}
.jauge-bornes {
  display: flex; justify-content: space-between;
  font-size: 11.5px; color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
/* Le montant commandé, écrit dans la jauge quand il y tient. */
.jauge > .rempli > b {
  position: absolute; right: 8px; top: 50%;
  transform: translateY(-50%);
  font-size: 12px; color: #fff; white-space: nowrap;
}

.flow-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin-top: 11px;
  font-size: 12px;
}
.flow-legend > span { display: flex; align-items: center; gap: 7px; }
.flow-legend i { width: 10px; height: 10px; border-radius: 3px; flex: 0 0 10px; }
.flow-legend b { font-variant-numeric: tabular-nums; }

/* --- Histogramme de charge ------------------------------------------------
   Colonnes empilées, avec une ligne de capacité en pointillé.
   La hauteur des segments se pilote en style inline (height en %).          */
/* Aire de tracé : 150 px de haut. Les hauteurs de barres sont données en px
   dans le HTML, ce qui garde l'échelle exacte et lisible à la relecture.   */
.chart {
  position: relative;
  display: flex;
  align-items: flex-end;
  gap: 10px;
  height: 150px;
  margin: 22px 0 26px;
}
.chart-col {
  position: relative;
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  height: 100%;
  min-width: 0;
}
.chart-stack {
  position: relative;
  width: 100%;
  max-width: 46px;
  display: flex;
  flex-direction: column-reverse;
  border-radius: 5px 5px 0 0;
  overflow: visible;
}
.chart-stack > span:not(.chart-val):first-child { border-radius: 5px 5px 0 0; }
.chart-stack > span { display: block; width: 100%; }
.chart-stack > span.a { background: var(--accent); }
.chart-stack > span.b { background: var(--purple); }
.chart-stack > span.over { background: var(--danger); }
.chart-val {
  position: absolute;
  top: -18px; left: 50%;
  transform: translateX(-50%);
  font-size: 10.5px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.chart-col .lab {
  position: absolute;
  bottom: -21px; left: 0; right: 0;
  text-align: center;
  font-size: 10.5px;
  color: var(--text-muted);
  white-space: nowrap;
}
.chart-capacity {
  position: absolute;
  left: 0; right: 0;
  border-top: 2px dashed var(--danger);
  pointer-events: none;
}

/* Bande « normale » : moyenne ± un écart-type.
   Un mois dont la barre dépasse la bande sort de l'ordinaire.          */
.chart-band {
  position: absolute;
  left: 0; right: 0;
  background: var(--accent-soft);
  border-top: 1px solid var(--border-strong);
  border-bottom: 1px solid var(--border-strong);
  pointer-events: none;
  z-index: 0;
}
.chart-band span {
  position: absolute;
  right: 0; top: 50%;
  transform: translateY(-50%);
  padding: 1px 6px;
  font-size: 10px; font-weight: 700;
  color: var(--accent-deep);
  background: var(--surface);
  border-radius: 4px;
}
/* Empilement : bande au fond, colonnes au-dessus, ligne de moyenne par-dessus.
   Ne jamais redéclarer « position » ici — .chart-capacity doit rester absolute. */
.chart-col      { z-index: 1; }
.chart-capacity { z-index: 2; }
.chart-capacity span {
  position: absolute;
  right: 0; top: -16px;
  font-size: 10px; font-weight: 700;
  color: var(--danger);
  background: var(--surface);
  padding: 0 5px;
}

/* Variante dense : beaucoup de colonnes, barres fines */
.chart.dense { gap: 4px; margin-bottom: 34px; }
.chart.dense .chart-stack { max-width: none; border-radius: 3px 3px 0 0; }
.chart.dense .chart-col .lab { bottom: -18px; font-size: 9.5px; }
.chart.dense .chart-col .yr {
  position: absolute;
  bottom: -32px; left: 0;
  font-size: 10px; font-weight: 700;
  color: var(--text-faint);
  white-space: nowrap;
}
.chart-stack > span.passe { background: #a9b6c0; }
.chart-stack > span.prev  { background: var(--surface-3); border: 1px dashed var(--border-strong); border-bottom: 0; }
:root[data-theme="dark"] .chart-stack > span.passe { background: #5b6c78; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .chart-stack > span.passe { background: #5b6c78; }
}

/* --- Charge de travail : la couleur dit la charge -------------------------
   Sous la moyenne en vert, dans la moyenne en orange, au-dessus en rouge.

   Des teintes **pastel** et non les couleurs sémantiques pleines : douze
   colonnes en vert vif, orange vif et rouge vif font un écran qui crie, et un
   écran qui crie tout le temps ne dit plus rien. Ces trois-là se distinguent
   au premier coup d'oeil sans emporter la page — elles sont assez saturées
   pour qu'on les nomme, assez pâles pour qu'on lise les chiffres par-dessus.

   Elles ne sont pas dérivées de --ok/--warn/--danger : une opacité appliquée à
   la couleur pleine laisserait voir le fond au travers, et deux barres
   voisines de hauteurs différentes n'auraient alors pas la même teinte.      */
.chart-stack > span.charge-sous   { background: #a8cfb8; }
.chart-stack > span.charge-sur    { background: #e8c98f; }
.chart-stack > span.charge-dessus { background: #e3a9a9; }
.chart-stack > span.charge-neutre { background: #c3ccd3; }

/* Le mois à venir n'est pas d'une autre couleur : c'est la même, en retrait.
   La charge et le calendrier sont deux informations, et elles tiennent
   ensemble ainsi — alors qu'une couleur unique devait choisir laquelle dire. */
.chart-stack > span.charge-avenir { opacity: .55; }

:root[data-theme="dark"] .chart-stack > span.charge-sous   { background: #4a7a5e; }
:root[data-theme="dark"] .chart-stack > span.charge-sur    { background: #8a7241; }
:root[data-theme="dark"] .chart-stack > span.charge-dessus { background: #8c5a5a; }
:root[data-theme="dark"] .chart-stack > span.charge-neutre { background: #4d5a64; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .chart-stack > span.charge-sous   { background: #4a7a5e; }
  :root:not([data-theme="light"]) .chart-stack > span.charge-sur    { background: #8a7241; }
  :root:not([data-theme="light"]) .chart-stack > span.charge-dessus { background: #8c5a5a; }
  :root:not([data-theme="light"]) .chart-stack > span.charge-neutre { background: #4d5a64; }
}

/* --- Frise de délais et d'autorisations ----------------------------------
   Une ligne par objet suivi : délai contractuel, exécution réelle, validité
   de chaque autorisation. Les positions sont en % de l'axe de temps.       */
.gantt { font-size: 12px; }

.gantt-axis {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  margin-left: 168px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 5px;
  margin-bottom: 8px;
}
.gantt-axis span {
  text-align: center;
  font-size: 10.5px;
  color: var(--text-faint);
  border-left: 1px solid var(--line-2);
}
.gantt-axis span:first-child { border-left: none; }

.gantt-row { display: flex; align-items: center; gap: 10px; padding: 5px 0; }
.gantt-row .who {
  width: 158px; flex: 0 0 158px;
  font-weight: 600;
  font-size: 11.5px;
  line-height: 1.3;
}
.gantt-row .who small { display: block; font-weight: 400; color: var(--text-faint); font-size: 10.5px; }

.gantt-track {
  position: relative;
  flex: 1;
  height: 22px;
  background: linear-gradient(to right, var(--line-2) 1px, transparent 1px) repeat-x;
  background-size: calc(100% / 12) 100%;
  border-radius: 3px;
}
.gantt-sep { height: 1px; background: var(--line-2); margin: 7px 0 7px 168px; }

/* Les lignes de travaux, intercalees au milieu des demarches. Un trait a
   gauche suffit a dire « ici, ce n'est plus du papier » — une seconde couleur
   de fond ferait un tableau a deux niveaux de lecture pour une seule
   information. */
.gantt-row .who.travaux {
  border-left: 3px solid var(--accent);
  padding-left: 7px;
  margin-left: -10px;
}

/* Une etape sans aucune date. Elle s'affiche quand meme : c'est le trou qu'on
   cherche, et une ligne absente ne se remarque pas. */
.gantt-rien {
  position: absolute;
  left: 4px;
  top: 4px;
  font-size: 10px;
  color: var(--text-faint);
  font-style: italic;
}

.gantt-bar {
  position: absolute;
  top: 3px; bottom: 3px;
  border-radius: 4px;
  display: flex; align-items: center;
  padding: 0 7px;
  font-size: 10.5px; font-weight: 700;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
}
.gantt-bar.contrat  { background: var(--accent); }
.gantt-bar.reel     { background: var(--ok); }
.gantt-bar.depasse  { background: var(--danger); }
.gantt-bar.valide   { background: var(--ok); }
.gantt-bar.expire   { background: var(--neutral); }
.gantt-bar.attente  { background: var(--warn); }
/* période de statage : hachures, le délai ne court pas */
.gantt-bar.state {
  background: repeating-linear-gradient(45deg,
    var(--warn) 0 5px, transparent 5px 10px);
  border: 1px solid var(--warn);
  color: var(--warn);
}
/* La même hachure, mais **posée par-dessus la barre du délai** : le statage est
   une portion de ce délai, pas une ligne de plus. Les creux sont opaques et non
   transparents — au-dessus d'une barre verte, des creux transparents auraient
   laissé voir le vert, c'est-à-dire un délai qui court là où il est suspendu. */
.gantt-bar.state.zone {
  z-index: 2;
  background: repeating-linear-gradient(45deg,
    var(--warn) 0 5px, var(--surface-3) 5px 10px);
}
.gantt-bar.na {
  background: none;
  border: 1px dashed var(--border-strong);
  color: var(--text-faint);
  font-weight: 500;
}

/* Deuxième frise : l'après-réception se compte en années, pas en mois. */
.gantt-axis.axe-3 { grid-template-columns: repeat(3, 1fr); }
.gantt-long .gantt-track { background-size: calc(100% / 3) 100%; }
.gantt-titre {
  font-size: 12.5px;
  font-weight: 700;
  margin-bottom: 9px;
}
.gantt-titre small { display: block; font-weight: 400; font-size: 11px; color: var(--text-muted); }

/* écart entre la date prévue et la date réalisée */
.gantt-ecart {
  position: absolute;
  top: 50%;
  height: 3px;
  margin-top: -1.5px;
  border-radius: 2px;
}
.gantt-ecart.tard   { background: var(--danger); }
.gantt-ecart.avance { background: var(--ok); }

/* jalon ponctuel */
.gantt-pin {
  position: absolute;
  top: 50%;
  width: 11px; height: 11px;
  margin: -5.5px 0 0 -5.5px;
  border-radius: 3px;
  background: var(--purple);
  transform: rotate(45deg);
  z-index: 2;
}
.gantt-pin.ok    { background: var(--ok); }
.gantt-pin.tard  { background: var(--danger); }
.gantt-pin.prevu { background: var(--surface); border: 2px solid var(--text-faint); }
.gantt-pin::after {
  content: attr(data-lab);
  position: absolute;
  left: 14px; top: -1px;
  transform: rotate(-45deg);
  transform-origin: left center;
  font-size: 10px; font-weight: 600;
  color: var(--text-muted);
  white-space: nowrap;
}

/* repère « aujourd'hui » */
.gantt-today {
  position: absolute;
  top: -4px; bottom: -4px;
  width: 2px;
  background: var(--danger);
  z-index: 3;
}
.gantt-today::after {
  content: "aujourd’hui";
  position: absolute;
  top: -19px; left: 50%;
  transform: translateX(-50%);
  font-size: 9.5px; font-weight: 700;
  color: var(--danger);
  background: var(--surface);
  padding: 0 4px;
  white-space: nowrap;
}

/* --- Sélecteur de période -------------------------------------------------- */
.segmented {
  display: inline-flex;
  padding: 2px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
/* Les liens y sont admis au même titre que les boutons : dans Sysop, chaque
   module de « Base de données » a sa propre adresse — on peut le mettre en
   signet, et seul celui qu'on demande est construit. */
.segmented button,
.segmented a {
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  padding: 6px 13px;
  border: none;
  border-radius: 5px;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
}
.segmented button:hover,
.segmented a:hover { color: var(--text); text-decoration: none; }
.segmented button.is-active,
.segmented a.is-active {
  background: var(--surface);
  color: var(--accent-deep);
  box-shadow: var(--shadow);
}

/* Histogramme apparié : deux barres par période */
.chart-pair { display: flex; align-items: flex-end; gap: 3px; height: 100%; }
.chart-pair > span {
  flex: 1;
  max-width: 22px;
  border-radius: 3px 3px 0 0;
  position: relative;
}
.chart-pair > span.fact { background: var(--accent); }
.chart-pair > span.cout { background: #9aa8b2; }
:root[data-theme="dark"] .chart-pair > span.cout { background: #5b6c78; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .chart-pair > span.cout { background: #5b6c78; }
}

/* Barre de charge par ressource */
.load { display: flex; align-items: center; gap: 11px; padding: 8px 0; font-size: 12.5px; }
.load .who { width: 108px; flex: 0 0 108px; font-weight: 600; }
.load .track {
  position: relative;
  flex: 1;
  height: 16px;
  border-radius: 4px;
  background: var(--surface-3);
  overflow: hidden;
}
.load .track > i {
  display: block; height: 100%;
  background: var(--accent);
  border-radius: 4px;
}
.load .track > i.over { background: var(--danger); }
.load .track > i.ok   { background: var(--ok); }
.load .pct {
  width: 78px; flex: 0 0 78px;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
}

/* Compteur ouvert / total */
.count-big { display: flex; align-items: baseline; gap: 6px; }
.count-big .n { font-size: 23px; font-weight: 800; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.count-big .tot { font-size: 14px; font-weight: 600; color: var(--text-muted); font-variant-numeric: tabular-nums; }

.meter-row { display: flex; align-items: center; gap: 9px; }
.meter-row .pct {
  min-width: 38px;
  text-align: right;
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}

/* ligne libellé / jauge / valeur */
.statline {
  display: grid;
  grid-template-columns: 150px 1fr 62px;
  gap: 10px;
  align-items: center;
  margin: 11px 0;
  font-size: 12.5px;
}
.statline b { text-align: right; font-variant-numeric: tabular-nums; }

/* --- 14. Étapes / jalons ------------------------------------------------- */
.steps { display: flex; align-items: stretch; gap: 2px; overflow-x: auto; padding-bottom: 2px; }
.step {
  flex: 1 0 128px;
  padding: 10px 12px;
  background: var(--surface-2);
  border-top: 3px solid var(--line);
}
.step:first-child { border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.step:last-child  { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.step-name { font-size: 12px; font-weight: 700; }
.step-meta { margin-top: 3px; font-size: 11px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.step.done    { border-top-color: var(--ok);     background: var(--ok-soft); }
.step.done .step-name { color: var(--ok); }
.step.current { border-top-color: var(--accent); background: var(--accent-soft); }
.step.current .step-name { color: var(--accent-deep); }
.step.blocked { border-top-color: var(--danger); background: var(--danger-soft); }
.step.blocked .step-name { color: var(--danger); }
.step.todo .step-name { color: var(--text-muted); }

/* --- 15. Hero de fiche --------------------------------------------------- */
.hero {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 18px;
  margin-bottom: 13px;
}
.hero-top { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.hero-id { display: flex; gap: 13px; min-width: 0; }
.hero-icon {
  width: 52px; height: 52px; flex: 0 0 52px;
  border-radius: 12px;
  background: var(--accent-soft);
  color: var(--accent-deep);
  display: grid; place-items: center;
  font-size: 23px; font-weight: 800;
}
.hero h1 { font-size: 23px; margin-bottom: 5px; }
.hero-sub { color: var(--text-muted); font-size: 13px; }
.hero-stats {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 10px;
  margin-top: 16px;
  padding-top: 15px;
  border-top: 1px solid var(--line);
}
.hero-stats small { display: block; font-size: 10.5px; color: var(--text-muted); }
.hero-stats b { display: block; margin-top: 4px; font-size: 13.5px; font-variant-numeric: tabular-nums; }

/* --- 16. Score de santé -------------------------------------------------- */
.score-box { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 6px 0; }
.score-ring {
  --val: 62;
  --col: var(--warn);
  width: 108px; height: 108px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: conic-gradient(var(--col) calc(var(--val) * 1%), var(--surface-3) 0);
  position: relative;
}
.score-ring::after {
  content: "";
  position: absolute;
  inset: 11px;
  border-radius: 50%;
  background: var(--surface);
}
.score-ring b {
  position: relative;
  z-index: 1;
  font-size: 30px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.score-label { font-weight: 700; font-size: 13px; }
.score-subs { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; }

/* anneau compact, pour les listes */
.score-ring.sm { width: 46px; height: 46px; }
.score-ring.sm::after { inset: 6px; }
.score-ring.sm b { font-size: 14px; }

/* pastille de score dans un tableau */
.score-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-variant-numeric: tabular-nums;
}
.score-chip .n {
  width: 30px; height: 30px;
  border-radius: 8px;
  display: grid; place-items: center;
  font-size: 12.5px; font-weight: 800;
}
.score-chip .n.ok     { background: var(--ok-soft);     color: var(--ok); }
.score-chip .n.warn   { background: var(--warn-soft);   color: var(--warn); }
.score-chip .n.danger { background: var(--danger-soft); color: var(--danger); }

/* --- 17. Décisions prioritaires ------------------------------------------ */
.decision {
  display: flex;
  gap: 11px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line-2);
}
.decision:last-child { border-bottom: none; }
.decision .grow { flex: 1; min-width: 0; }
.decision-title { font-weight: 700; font-size: 13px; }
.decision-desc { margin-top: 3px; font-size: 12px; color: var(--text-muted); }
.decision .when { font-size: 11px; color: var(--text-faint); white-space: nowrap; }
.prio {
  flex: 0 0 auto;
  align-self: flex-start;
  padding: 3px 8px;
  border-radius: 6px;
  font-size: 10.5px;
  font-weight: 800;
}
.prio.p1 { background: var(--danger-soft); color: var(--danger); }
.prio.p2 { background: var(--warn-soft);   color: var(--warn); }
.prio.p3 { background: var(--info-soft);   color: var(--info); }

/* --- 18. Barre d'action contextuelle ------------------------------------- */
.action-strip {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 12px 16px;
  border-radius: var(--radius);
  background: #1c2a35;
  color: #e6eef3;
  font-size: 13px;
  margin-bottom: 13px;
}
.action-strip .grow { flex: 1; min-width: 200px; }
.action-strip .btn { background: #2a3b48; border-color: #334756; color: #e6eef3; }
.action-strip .btn:hover { background: #35495a; }
.action-strip .btn-primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.action-strip .btn-primary:hover { background: var(--accent-hover); }

/* --- 19. Onglets --------------------------------------------------------- */
/* La barre d'onglets colle au haut de la zone défilante : on sait toujours
   où l'on est, même au bas d'un tableau long. */
.tabs {
  position: sticky;
  top: 0;
  z-index: 4;
  /* comble la gouttière laissée au-dessus par le retrait du conteneur,
     sinon une carte défilante apparaîtrait dans cette bande */
  box-shadow: 0 -22px 0 var(--bg);
  display: flex;
  gap: 2px;
  padding: 0 8px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius) var(--radius) 0 0;
  overflow-x: auto;
}
.tab {
  padding: 13px;
  font: inherit;
  font-size: 12.5px;
  color: var(--text-muted);
  background: none;
  border: none;
  border-bottom: 3px solid transparent;
  cursor: pointer;
  white-space: nowrap;
}
.tab:hover { color: var(--text); }
/* Un onglet peut être un vrai lien : Sysop ouvre neuf écrans distincts, dont
   certains interrogent le réseau ou comptent des centaines de milliers de
   lignes. Les rendre tous d'un coup pour n'en regarder qu'un serait absurde —
   chacun a donc son adresse. L'œil ne voit pas la différence. */
a.tab { text-decoration: none; display: inline-block; }
.tab.is-active { color: var(--accent-deep); border-bottom-color: var(--accent); font-weight: 800; }
.tab .count {
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 9px;
  background: var(--surface-3);
  font-size: 10.5px;
  color: var(--text-muted);
}
.tab-panel {
  display: none;
  padding: 17px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-top: 0;
  border-radius: 0 0 var(--radius) var(--radius);
}
.tab-panel.is-active { display: block; }
/* onglets sans conteneur (pages de liste) */
.tabs.plain { background: none; border: 0; border-bottom: 1px solid var(--line); border-radius: 0; padding: 0; margin-bottom: 16px; }
.tabs.plain + .tab-panel,
.tabs.plain ~ .tab-panel { background: none; border: 0; padding: 0; }

/* Adresse composée, mise en avant au-dessus des champs qui la constituent */
.adresse-composee {
  padding: 13px 15px;
  background: var(--accent-soft);
  border: 1px solid var(--accent-soft);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
}
.adresse-composee .ligne {
  font-size: 16px;
  font-weight: 700;
  letter-spacing: -.01em;
  color: var(--accent-deep);
}
.adresse-composee .gps {
  margin-top: 4px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--text-muted);
}
.adresse-composee .note { margin-top: 7px; font-size: 11.5px; color: var(--text-muted); }

/* --- 20. Champs d'information ------------------------------------------- */
.info-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px 18px; }
.info-field { padding: 9px 0; border-bottom: 1px solid var(--line-2); }
/* Une légende au-dessus d'une valeur en lecture seule : c'est un intitulé, pas
   une étiquette de formulaire. « label » y désignait un contrôle qui n'existe
   pas, et un lecteur d'écran annonçait « étiquette » sans rien à étiqueter. */
.info-field label,
.info-field .lib { display: block; font-size: 10px; color: var(--text-muted); margin-bottom: 4px; }
.info-field b { font-size: 12.5px; }

/* --- 21. Alertes --------------------------------------------------------- */
.alert {
  display: flex;
  gap: 11px;
  align-items: flex-start;
  padding: 11px 13px;
  margin-bottom: 9px;
  border: 1px solid var(--line);
  border-left: 4px solid var(--warn);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 12.5px;
}
.alert:last-child { margin-bottom: 0; }
.alert .grow { flex: 1; min-width: 0; }
.alert strong { display: block; font-size: 12.5px; margin-bottom: 3px; }
.alert small, .alert .desc { color: var(--text-muted); font-size: 12px; }
.alert.danger { border-left-color: var(--danger); background: var(--danger-soft); }
.alert.warn   { border-left-color: var(--warn); }
.alert.info   { border-left-color: var(--info);   background: var(--info-soft); }
.alert.ok     { border-left-color: var(--ok);     background: var(--ok-soft); }

.notice {
  padding: 12px 13px;
  border: 1px solid var(--accent-soft);
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-size: 12.5px;
}

/* --- 22. Kanban ---------------------------------------------------------- */
.kanban { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 11px; }
.kanban-col {
  padding: 10px;
  min-height: 180px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.kanban-col h4 {
  display: flex;
  justify-content: space-between;
  margin: 2px 2px 10px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .35px;
  color: var(--text-muted);
}
.task {
  padding: 10px;
  margin-bottom: 8px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 7px;
}
.task b { font-size: 12px; }
.task small { display: block; margin-top: 5px; color: var(--text-muted); font-size: 11.5px; }

/* --- 23. Chronologie ----------------------------------------------------- */
.timeline { margin-left: 8px; padding-left: 19px; border-left: 2px solid var(--line); }
.event { position: relative; padding-bottom: 17px; }
.event:last-child { padding-bottom: 0; }
.event::before {
  content: "";
  position: absolute;
  left: -25px; top: 4px;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--surface);
  box-shadow: 0 0 0 2px var(--accent);
}
.event b { font-size: 12.5px; }
.event small { display: block; margin-top: 3px; color: var(--text-muted); font-size: 11.5px; }

/* --- 24. Flux d'activité ------------------------------------------------- */
.feed { display: flex; flex-direction: column; }
.feed-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--line-2);
  font-size: 12.5px;
}
.feed-item:last-child { border-bottom: none; }
.feed-item .grow { flex: 1; min-width: 0; }
.feed-item .when { margin-left: auto; font-size: 11.5px; color: var(--text-faint); white-space: nowrap; }
.feed-item .who { font-weight: 700; }

/* --- 25. Formulaires ----------------------------------------------------- */
.field { margin-bottom: 14px; }
.field > label { display: block; font-size: 12.5px; font-weight: 600; margin-bottom: 6px; }
.field .hint { margin-top: 5px; font-size: 11.5px; color: var(--text-faint); }

/* Variante enveloppante : le libellé et le champ dans un même <label>. Cliquer
   le libellé met le champ au focus sans qu'il faille inventer un id par
   contrôle — sur l'écran d'administration il y en aurait une trentaine. */
.champ { display: block; }
.champ > span { display: block; font-size: 12.5px; font-weight: 600; margin-bottom: 6px; }

.input, select.input, textarea.input {
  width: 100%;
  padding: 10px 12px;
  font: inherit;
  font-size: 13.5px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.input::placeholder { color: var(--text-faint); }

.check { display: flex; align-items: flex-start; gap: 9px; font-size: 12.5px; }
.check input { margin-top: 2px; flex: 0 0 auto; }

.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 11px; }

/* --- 26. Authentification ------------------------------------------------ */
.auth { min-height: 100vh; display: grid; grid-template-columns: minmax(0, 1fr) 480px; }
.auth-aside {
  padding: 48px 52px;
  background: linear-gradient(160deg, #101920 0%, #0b5f65 100%);
  color: #e6f2f3;
  display: flex;
  flex-direction: column;
}
.auth-aside .brand-name { color: #fff; }
.auth-aside .brand-sub { color: #8fb6b9; }
.auth-aside h2 { margin: auto 0 18px; max-width: 15em; font-size: 27px; line-height: 1.25; color: #fff; }
.auth-aside ul { margin: 0 0 auto; padding: 0; list-style: none; font-size: 13.5px; }
.auth-aside li { display: flex; gap: 9px; padding: 6px 0; color: #b7d4d6; }
.auth-aside li::before { content: "—"; opacity: .55; }
.auth-aside .foot { font-size: 11.5px; color: #7fa7aa; }

.auth-panel {
  padding: 48px 52px;
  background: var(--surface);
  border-left: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.auth-panel h1 { margin-bottom: 7px; }
.auth-panel .lead { margin-bottom: 25px; color: var(--text-muted); font-size: 13.5px; }
.auth-sep { display: flex; align-items: center; gap: 11px; margin: 19px 0; font-size: 11.5px; color: var(--text-faint); }
.auth-sep::before, .auth-sep::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.auth-foot { margin-top: 26px; font-size: 11.5px; color: var(--text-faint); }

/* Appairage du second facteur : QR à gauche, clé à droite. */
.appairage { display: flex; gap: 18px; align-items: flex-start; flex-wrap: wrap; }
.appairage-qr {
  flex: none;
  display: grid; place-items: center;
  width: 190px; height: 190px;
  padding: 6px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.appairage-qr svg { display: block; width: 100%; height: auto; }
.appairage-cle { flex: 1; min-width: 200px; }

/* La clé se coupe entre les groupes, jamais au milieu de l'un d'eux. */
.cle-totp {
  font-size: 15px;
  letter-spacing: 1px;
  line-height: 1.7;
  word-spacing: 4px;
  overflow-wrap: break-word;
  word-break: keep-all;
}

.otp { display: flex; gap: 9px; margin: 6px 0 4px; }
.otp input {
  width: 50px; height: 58px;
  text-align: center;
  font-family: var(--mono);
  font-size: 22px; font-weight: 700;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}
.otp input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.otp input.filled { border-color: var(--accent); background: var(--accent-soft); }

/* Six cases de 50 px débordent d'un écran de 375 : elles rétrécissent.
   On garde une largeur explicite plutôt que « auto » : un champ texte a une
   largeur intrinsèque d'une vingtaine de caractères, et en flex celle-ci
   remonte jusqu'à la grille parente, qui s'étire alors bien au-delà de
   l'écran. */
@media (max-width: 480px) {
  .otp { gap: 6px; }
  .otp input { width: 40px; flex: 1 1 40px; min-width: 0; height: 52px; font-size: 19px; }
}

/* --- 26 bis. Fenêtre modale ---------------------------------------------- */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(8, 16, 22, .55);
  z-index: 100;
}
/* « hidden » ne suffit pas ici, et c'est un piège classique : la feuille de
   l'agent utilisateur pose [hidden]{display:none}, mais une règle d'auteur qui
   fixe display — ci-dessous, flex — la bat, quelle que soit sa spécificité.
   Une modale rendue masquée par le serveur restait donc ouverte en permanence,
   par-dessus la page. Il faut rendre la règle explicite. */
/* Le corps d'une version du journal des modifications : du texte rendu depuis
   CHANGELOG.md. Les titres y sont des sous-titres de carte, pas des titres de
   page — sans cette règle, un « ### » du fichier s'affiche plus gros que le
   numéro de version au-dessus. */
.notes-version p { margin: 0 0 9px; font-size: 12.5px; line-height: 1.55; }
.notes-version h4 {
  margin: 14px 0 7px;
  font-size: 12px; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--text-muted);
}
.notes-version h4:first-child { margin-top: 0; }
.notes-version ul { margin: 0 0 9px; padding-left: 18px; }
.notes-version li { font-size: 12.5px; line-height: 1.55; margin-bottom: 4px; }
.notes-version code {
  font-size: 11.5px; padding: 1px 4px; border-radius: 4px;
  background: var(--surface-2);
}
.notes-version > :last-child { margin-bottom: 0; }

.modal[hidden],
.modal-backdrop[hidden],
/* Le panneau des notifications est tombé dans le même piège : « .notifs » pose
   display:flex, et le panneau rendu masqué par le serveur restait affiché en
   permanence par-dessus la page. Toute règle d'auteur qui fixe « display »
   doit prévoir son [hidden] — c'est la deuxième fois ici. */
.notifs[hidden] { display: none !important; }

.modal {
  position: fixed;
  z-index: 101;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  width: min(760px, 94vw);
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.modal-head {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 15px 18px;
  border-bottom: 1px solid var(--line);
}
.modal-head .grow { flex: 1; min-width: 0; }
.modal-close {
  font: inherit;
  font-size: 18px;
  line-height: 1;
  padding: 4px 9px;
  background: none;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
}
.modal-close:hover { background: var(--surface-2); color: var(--text); }
.modal-body { padding: 2px 18px 18px; overflow-y: auto; }
.modal-foot {
  padding: 11px 18px;
  border-top: 1px solid var(--line);
  background: var(--surface-2);
  font-size: 12px;
  color: var(--text-muted);
}

/* --- Zone de depot de fichiers -------------------------------------------
   C'est un <label> qui enveloppe le champ de fichiers : elle s'ouvre donc au
   clic et au clavier sans aucun script, et le glisser-deposer n'est qu'un
   raccourci ajoute par-dessus. Une zone qui ne marcherait qu'au glisser
   laisserait sans rien quiconque ne peut pas glisser — pave tactile, lecteur
   d'ecran, main qui tremble. */
.depot {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 26px 18px;
  border: 2px dashed var(--line);
  border-radius: 10px;
  background: var(--surface-2);
  cursor: pointer;
  text-align: center;
  transition: border-color .12s, background .12s;
}
.depot:hover,
.depot:focus-within      { border-color: var(--accent); background: var(--accent-soft); }
.depot.survol            { border-color: var(--accent); background: var(--accent-soft); }
.depot-ico               { font-size: 26px; line-height: 1; }
.depot-titre             { font-weight: 700; }

/* Le champ lui-meme est invisible mais reste dans le flux : le masquer par
   « display:none » le sortirait de la navigation au clavier, et la zone ne
   s'ouvrirait plus a la barre d'espace. */
.depot-champ {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  overflow: hidden;
}
.depot { position: relative; }

/* Ce qu'on vient de choisir. Sans cette liste, on lache dix fichiers et rien
   ne bouge a l'ecran : on recommence, et l'on en depose vingt. */
.depot-liste:not(:empty) {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
  width: 100%;
  color: var(--text-muted);
  text-align: left;
}

/* --- Dossiers de documents ------------------------------------------------
   Les dossiers a gauche, leur contenu a droite. La colonne de gauche est fixe :
   un dossier vide s'affiche quand meme, grise. « Photos — apres : vide » sur un
   chantier receptionne dit quelque chose ; une liste qui ne montre que ce qui
   existe ne le dirait pas. */
.grid-dossiers { display: grid; grid-template-columns: 300px 1fr; gap: 14px; }
@media (max-width: 1100px) {
  .grid-dossiers { grid-template-columns: 1fr; }
}

.dossiers { display: flex; flex-direction: column; gap: 2px; }
.dossier {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 7px 9px;
  border-radius: 7px;
  color: var(--text);
  text-decoration: none;
  border: 1px solid transparent;
}
.dossier:hover { background: var(--surface-2); }
.dossier.is-active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent-deep);
}
.dossier .ico  { font-size: 14px; line-height: 1.35; }
.dossier .grow { flex: 1; min-width: 0; }
.dossier b     { display: block; font-size: 12.5px; font-weight: 700; }
.dossier small { display: block; font-size: 10.5px; line-height: 1.3; }
.dossier .cpt {
  flex: 0 0 auto;
  min-width: 20px;
  text-align: center;
  font-size: 10.5px;
  font-weight: 800;
  color: var(--text-muted);
}
/* Un dossier vide reste lisible et cliquable : il se remplira. */
.dossier.vide b   { font-weight: 600; color: var(--text-muted); }
.dossier.vide .cpt { color: var(--text-faint); }

/* déclencheurs cliquables */
[data-version] { cursor: pointer; }
[data-version]:hover { border-color: var(--accent); color: var(--accent-deep); }
.sidebar-foot [data-version]:hover { background: rgba(255, 255, 255, .16); color: #fff; }

.modal.modal-lg { width: min(1000px, 96vw); }

/* --- Aperçu de document --------------------------------------------------- */
.doc-view { display: grid; grid-template-columns: 1fr 280px; gap: 16px; }
@media (max-width: 820px) { .doc-view { grid-template-columns: 1fr; } }

.doc-canvas {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  min-height: 380px;
  display: grid;
  place-items: center;
  padding: 18px;
  overflow: auto;
}
.doc-canvas svg { max-width: 100%; height: auto; border-radius: 4px; }
.doc-canvas .page {
  box-shadow: 0 2px 14px rgba(16, 24, 40, .18);
  background: #fff;
}

.doc-meta .row-meta {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 0;
  border-bottom: 1px solid var(--line-2);
  font-size: 12.5px;
}
.doc-meta .row-meta:last-child { border-bottom: none; }
.doc-meta .row-meta span:first-child { color: var(--text-muted); }
.doc-meta .row-meta span:last-child { font-weight: 600; text-align: right; }

/* déclencheurs d'aperçu */
[data-doc] { cursor: pointer; }
tr[data-doc]:hover td { background: var(--accent-soft); }
.tag[data-doc]:hover { border-color: var(--accent); color: var(--accent-deep); }

/* entrée de version, partagée par la modale et le sommaire */
.rel { padding: 15px 0; border-bottom: 1px solid var(--line-2); }
.rel:last-child { border-bottom: none; }
.rel-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.rel-head .v { font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums; }
.rel-head .when { color: var(--text-faint); font-size: 12px; }
.rel ul { margin: 0; padding-left: 18px; font-size: 12.5px; color: var(--text-muted); }
.rel li { padding: 2px 0; }
.rel li b { color: var(--text); }

/* --- 27. Divers ---------------------------------------------------------- */
.muted { color: var(--text-muted); }
.faint { color: var(--text-faint); }
.small { font-size: 11.5px; }
.nowrap { white-space: nowrap; }
.right { text-align: right; }
.mt-1 { margin-top: 9px; } .mt-2 { margin-top: 17px; } .mt-3 { margin-top: 25px; }
.mb-0 { margin-bottom: 0; } .mb-1 { margin-bottom: 9px; } .mb-2 { margin-bottom: 17px; }
.divider { height: 1px; background: var(--line-2); margin: 14px 0; }
.empty { padding: 36px 20px; text-align: center; color: var(--text-faint); font-size: 12.5px; }

.mock-banner {
  position: fixed;
  right: 14px; bottom: 14px;
  z-index: 50;
  display: flex; align-items: center; gap: 10px;
  padding: 8px 13px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 22px;
  box-shadow: var(--shadow-lg);
  font-size: 11.5px;
  color: var(--text-muted);
}
.mock-banner button {
  font: inherit; font-size: 11.5px;
  padding: 0; border: none; background: none;
  color: var(--accent-deep); cursor: pointer;
}

/* --- 28. Titre de fiche et pastille de coordonnées ----------------------- */
.h1-row { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }

.geo-chip {
  font: inherit;
  font-family: var(--mono);
  font-size: 11.5px;
  letter-spacing: .2px;
  padding: 4px 10px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  white-space: nowrap;
}
.geo-chip:hover { border-color: var(--accent); color: var(--accent-deep); }

/* --- 29. Onglet Carte ---------------------------------------------------- */
.carte-grid { display: grid; grid-template-columns: 1fr 280px; gap: 15px; align-items: start; }

.carte-plan-zone { min-width: 0; }

.carte-leaflet {
  /* s'ajuste à la hauteur disponible : jamais écrasée sur un petit écran,
     jamais démesurée sur un grand */
  height: clamp(380px, calc(100vh - 340px), 840px);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  z-index: 0;                 /* reste sous les modales */
}
.carte-leaflet .leaflet-control-layers,
.carte-leaflet .leaflet-bar {
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
}
.carte-leaflet .leaflet-control-layers-base label { font-size: 12px; }
.carte-leaflet .leaflet-popup-content { margin: 10px 14px; min-width: 186px; font-size: 12.5px; }
.carte-leaflet.leaflet-container { font: inherit; }

/* Étiquette permanente du site : lisible sans clic, sur plan comme sur satellite. */
.carte-etiquette.leaflet-tooltip {
  padding: 3px 9px;
  border: none;
  border-radius: 20px;
  background: var(--accent);
  color: var(--accent-text);
  font-weight: 800;
  font-size: 11.5px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .3);
}
.carte-etiquette.leaflet-tooltip-top::before { border-top-color: var(--accent); }

.carte-plan {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}

.carte-aside { display: flex; flex-direction: column; }

.carte-adresse {
  padding: 11px 13px;
  margin-bottom: 11px;
  background: var(--accent-soft);
  border-radius: var(--radius-sm);
}
.carte-adresse .ligne { font-size: 13.5px; font-weight: 700; color: var(--text); }
.carte-adresse .gps {
  margin-top: 5px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--accent-deep);
}

.carte-field { padding: 8px 0; border-bottom: 1px solid var(--line-2); }
.carte-field label { display: block; font-size: 10px; color: var(--text-muted); margin-bottom: 3px; }
.carte-field b { font-size: 12.5px; }

.carte-liens { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 13px; }

.carte-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 7px 20px;
  margin-top: 13px;
  font-size: 11.5px;
  color: var(--text-muted);
}
.carte-legend span { display: inline-flex; align-items: center; gap: 7px; }
.carte-legend i { display: inline-block; flex: none; }
.carte-legend i.pt { width: 11px; height: 11px; border-radius: 50%; background: var(--accent); }
.carte-legend i.rd { width: 18px; height: 7px; border-radius: 2px; background: var(--line); border: 1px solid var(--line); }
.carte-legend i.rz { width: 12px; height: 12px; border-radius: 50%; border: 1.4px dashed var(--accent); }
.carte-legend i.ar { width: 12px; height: 0; border-top: 2px solid var(--accent-deep); }

/* --- 30. Colonnes de marché dans le portefeuille ------------------------- */
.col-marche  { min-width: 172px; max-width: 260px; }
.col-fenetre { min-width: 158px; }

/* Les chiffres ne se coupent jamais ; leurs en-têtes, si. */
.tbl thead th.num { white-space: normal; }
.tbl thead th.col-long { min-width: 104px; max-width: 128px; }

/* Fiche marché : le contrat à gauche, la durée et les clauses à droite. */
.marche-grid { display: grid; grid-template-columns: 1.15fr 1fr; gap: 15px 26px; }
.marche-grid > section { min-width: 0; }

.bloc-titre {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 4px;
}

.info-grid.col-1 { grid-template-columns: 1fr; }
.info-grid.col-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.bar-xs { height: 5px; margin: 5px 0 4px; }

/* Référence de document cliquable, en ligne dans un tableau. */
.lien-doc {
  font-weight: 700;
  color: var(--accent-deep);
  cursor: pointer;
  border-bottom: 1px dotted var(--accent);
}
.lien-doc:hover { border-bottom-style: solid; }

/* Étape courante et avancement, dans la liste des sous-projets. */
.col-etape { min-width: 158px; }
.etape-lib { font-size: 12px; white-space: nowrap; }
.etape-jauge { display: flex; align-items: center; gap: 7px; margin-top: 4px; }
.etape-jauge .bar { flex: 1; margin: 0; }
.etape-jauge em {
  font-style: normal;
  font-size: 10.5px;
  font-weight: 700;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

/* Actions en fin de ligne : situer le site, ouvrir sa discussion. */
.col-actions { white-space: nowrap; text-align: right; }
.ico-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px; height: 26px;
  margin-left: 3px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-muted);
  font-size: 13px;
  text-decoration: none;
}
.ico-btn:hover { border-color: var(--accent); color: var(--accent-deep); text-decoration: none; }
.ico-btn .n {
  position: absolute;
  top: -6px; right: -6px;
  min-width: 15px;
  padding: 0 3px;
  border-radius: 20px;
  background: var(--danger);
  color: #fff;
  font-size: 9px; font-weight: 800; line-height: 15px;
}
/* Un compteur de messages n'est pas une alerte : le rouge est réservé à ce qui
   ne va pas. Une discussion qui existe se signale, elle n'inquiète pas. */
.ico-btn .n.msg { background: var(--accent); }

/* --- 31. Volet de discussion ---------------------------------------------
   Un volet plutôt qu'un onglet : on lit la fiche et on écrit en même temps.
   Un onglet aurait remplacé le contenu qu'on est justement en train de
   commenter. -------------------------------------------------------------- */
.btn-discussion .n {
  margin-left: 2px;
  padding: 1px 6px;
  border-radius: 20px;
  background: var(--danger);
  color: #fff;
  font-size: 10px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
}
.btn-discussion .n:empty { display: none; }

.volet-fond {
  position: fixed;
  inset: 0;
  z-index: 59;
  background: rgba(12, 24, 35, .28);
}

.volet {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 60;
  width: min(430px, 100%);
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border-left: 1px solid var(--line);
  box-shadow: var(--shadow-lg);
  transform: translateX(101%);
  transition: transform .18s ease-out;
  visibility: hidden;
}
.volet.is-open { transform: none; visibility: visible; }

.volet-tete {
  flex: none;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 15px 16px 13px;
  border-bottom: 1px solid var(--line);
}
.volet-tete h2 { font-size: 15px; }
.volet-fermer {
  font: inherit; font-size: 15px;
  width: 30px; height: 30px;
  border: none; border-radius: var(--radius-sm);
  background: none; color: var(--text-muted);
  cursor: pointer;
}
.volet-fermer:hover { background: var(--surface-3); color: var(--text); }

.volet-gens {
  flex: none;
  display: flex; align-items: center; gap: 5px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--line-2);
}
.volet-gens .pastille {
  width: 24px; height: 24px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface-3);
  color: var(--text-muted);
  font-size: 9.5px; font-weight: 800;
}
.volet-gens .pastille.terrain { background: var(--accent-soft); color: var(--accent-deep); }
.volet-gens .small { margin-left: 7px; }

.volet-filtres {
  flex: none;
  display: flex; gap: 5px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--line-2);
}
.volet-filtres .seg {
  font: inherit; font-size: 11.5px; font-weight: 600;
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
}
.volet-filtres .seg.is-active {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent-deep);
}

/* le fil : seule partie qui défile */
.fil { flex: 1; min-height: 0; overflow-y: auto; padding: 4px 16px 14px; }

.fil-jour {
  margin: 16px 0 10px;
  text-align: center;
  font-size: 10.5px; font-weight: 700;
  letter-spacing: .4px; text-transform: uppercase;
  color: var(--text-faint);
}

.msg { display: flex; gap: 10px; padding: 9px 0; }
/* sans cette ligne, le display:flex ci-dessus l'emporte sur [hidden]
   et les filtres du fil ne masquent rien */
.msg[hidden], .fil-jour[hidden] { display: none; }
.msg-avatar {
  width: 30px; height: 30px; flex: 0 0 30px;
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface-3);
  color: var(--text-muted);
  font-size: 10.5px; font-weight: 800;
}
.msg-avatar.terrain { background: var(--accent); color: var(--accent-text); }
.msg-corps { min-width: 0; flex: 1; }
.msg-tete {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 7px;
  margin-bottom: 3px;
  font-size: 12.5px;
}
.msg-tete .role {
  padding: 1px 7px;
  border-radius: 20px;
  background: var(--surface-3);
  color: var(--text-muted);
  font-size: 9.5px; font-weight: 700;
  letter-spacing: .3px; text-transform: uppercase;
}
.msg-tete .role.terrain { background: var(--accent-soft); color: var(--accent-deep); }
.msg-tete .quand { margin-left: auto; font-size: 11px; color: var(--text-faint); }
.msg-texte { font-size: 12.5px; color: var(--text); overflow-wrap: anywhere; }

/* --- Pièces jointes d'un message -----------------------------------------
   Une photo de chantier se regarde, elle ne se télécharge pas : dans une
   conversation, une pièce jointe qu'il faut ouvrir dans un autre onglet n'est
   jamais ouverte. Les vignettes sont donc dans le fil, et le clic mène au
   fichier d'origine — c'est la même pièce, rangée dans les documents.       */
.msg-pieces {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 7px;
}
.msg-photo {
  display: block;
  /* Une hauteur fixe et une largeur libre : dix photos de formats différents
     alignées sur leur base se lisent comme une planche-contact. */
  height: 92px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--surface-3);
}
.msg-photo img { display: block; height: 100%; width: auto; object-fit: cover; }
.msg-photo:hover { border-color: var(--accent); }
/* Ce qui n'est pas une image porte son nom et son poids : on ne devine pas ce
   qu'on va télécharger. */
.msg-fichier {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 9px;
  font-size: 11.5px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
}
.msg-fichier:hover { border-color: var(--accent); }

/* un message privé ne sort pas du tenant : accent violet, comme sa pastille */
/* Un message privé ne sort pas du tenant. Il se distingue à l'œil, parce
   qu'un accès externe en lecture peut suivre le reste du fil. */
.msg.prive {
  padding: 11px 12px;
  margin: 9px 0;
  border-left: 3px solid var(--purple);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: var(--purple-soft);
}

.volet-gens .pastille.externe {
  background: var(--surface);
  border: 1px dashed var(--text-faint);
  color: var(--text-faint);
}

/* Le composeur **est** la zone de dépôt : on lâche une photo sur la
   conversation, pas sur un rectangle à côté d'elle. Le survol se signale par le
   cadre, sans rien déplacer — une zone qui grandit à l'approche du curseur fait
   sauter le bouton qu'on visait. */
.composeur.survol {
  outline: 2px dashed var(--accent);
  outline-offset: -4px;
  background: var(--accent-soft);
}
.depot-liste:empty { display: none; }

/* Le composeur prend la teinte du privé : on voit à qui l'on écrit. */
.composeur.est-prive { background: var(--purple-soft); }
.composeur.est-prive textarea { border-color: var(--purple); }

.msg-photos { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 8px; }
.vignette {
  display: flex; align-items: center; gap: 7px;
  padding: 7px 10px;
  font: inherit; font-size: 11.5px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  cursor: pointer;
}
.vignette:hover { border-color: var(--accent); color: var(--accent-deep); }
.vignette .vg-ico { font-size: 14px; }

.composeur {
  flex: none;
  padding: 11px 16px;
  border-top: 1px solid var(--line);
  background: var(--surface-2);
}
.composeur-genre {
  display: flex; align-items: center; gap: 14px;
  margin-bottom: 8px;
  font-size: 11.5px; color: var(--text-muted);
}
.composeur-genre label { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.composeur textarea {
  width: 100%;
  padding: 9px 11px;
  font: inherit; font-size: 12.5px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  resize: vertical;
}
.composeur textarea:focus { outline: none; border-color: var(--accent); }
.composeur-pj { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.composeur-pj .pj {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 9px;
  border: 1px dashed var(--line);
  border-radius: 20px;
  font-size: 11px; color: var(--text-muted);
  background: var(--surface);
}
.composeur-pj .pj button {
  font: inherit; border: none; background: none; cursor: pointer;
  color: var(--text-faint); padding: 0;
}
.composeur-bas { display: flex; align-items: center; gap: 8px; margin-top: 9px; }

.volet-pied {
  flex: none;
  padding: 10px 16px 12px;
  border-top: 1px solid var(--line-2);
  font-size: 11px;
  color: var(--text-muted);
  background: var(--surface);
}

@media (max-width: 520px) {
  .volet { width: 100%; }
}

/* --- 32. Recherche globale ----------------------------------------------- */
.palette {
  position: fixed;
  top: 12vh; left: 50%;
  transform: translateX(-50%);
  z-index: 101;
  width: min(720px, calc(100vw - 32px));
  max-height: 70vh;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.palette-saisie {
  flex: none;
  display: flex; align-items: center; gap: 11px;
  padding: 14px 17px;
  border-bottom: 1px solid var(--line);
  color: var(--text-muted);
}
.palette-saisie input {
  flex: 1;
  font: inherit; font-size: 15px;
  color: var(--text);
  background: none;
  border: none;
  outline: none;
}
.palette-res { flex: 1; min-height: 0; overflow-y: auto; padding: 6px; }
.palette-item {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 11px;
  border-radius: var(--radius-sm);
  color: inherit;
  text-decoration: none;
}
.palette-item:hover, .palette-item:focus { background: var(--surface-2); text-decoration: none; }
.palette-item .cat {
  flex: 0 0 84px;
  font-size: 10px; font-weight: 700;
  letter-spacing: .4px; text-transform: uppercase;
  color: var(--text-faint);
}
.palette-item b { display: block; font-size: 13px; }
.palette-item small { display: block; font-size: 11.5px; color: var(--text-muted); }
.palette-vide { padding: 16px 17px; font-size: 12.5px; color: var(--text-muted); }

/* --- 33. Notifications ---------------------------------------------------- */
.notifs {
  position: fixed;
  z-index: 70;
  width: min(400px, calc(100vw - 24px));
  max-height: 62vh;
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.notifs-tete {
  flex: none;
  display: flex; align-items: center; gap: 10px;
  padding: 11px 13px;
  border-bottom: 1px solid var(--line);
}
.notifs-corps { flex: 1; min-height: 0; overflow-y: auto; }

.notif {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 13px;
  border-bottom: 1px solid var(--line-2);
  color: inherit; text-decoration: none;
}
.notif:last-child { border-bottom: none; }
.notif:hover { background: var(--surface-2); text-decoration: none; }
.notif b { display: block; font-size: 12.5px; }
.notif small { display: block; margin-top: 2px; font-size: 11.5px; color: var(--text-muted); }
.notif .quand { flex: none; font-size: 10.5px; color: var(--text-faint); }
.notif .puce {
  flex: 0 0 8px; width: 8px; height: 8px;
  margin-top: 5px;
  border-radius: 50%;
  background: var(--text-faint);
}
.notif .puce.danger { background: var(--danger); }
.notif .puce.warn   { background: var(--warn); }
.notif .puce.accent { background: var(--accent); }

.notifs-pied {
  flex: none;
  padding: 10px 13px;
  border-top: 1px solid var(--line-2);
  background: var(--surface-2);
  font-size: 11px; color: var(--text-muted);
}

/* --- 34. Filtres à sélection multiple ------------------------------------ */
.multi { position: relative; }
.multi-btn {
  display: inline-flex; align-items: center; gap: 9px;
  width: auto;
  cursor: pointer;
  text-align: left;
}
.multi.est-actif .multi-btn {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-weight: 600;
}
.multi-liste {
  position: absolute;
  top: calc(100% + 5px); left: 0;
  z-index: 20;
  min-width: 260px;
  /* Un nom de marché tient parfois sur une ligne entière — « SPW-2025-RADARS
     — fourniture et pose de radars fixes ». Sans plafond, le panneau prenait
     la largeur du plus long, sortait de l'écran par la droite sur un
     téléphone, et c'était la zone de contenu qui se mettait à défiler de côté.
     Le « 100vw - 28px » garde une gouttière même quand le filtre est collé au
     bord droit de la barre. */
  max-width: min(420px, calc(100vw - 28px));
  max-height: 320px;
  overflow-y: auto;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg);
}
.multi-actions {
  display: flex; gap: 6px;
  padding: 3px 5px 7px;
  border-bottom: 1px solid var(--line-2);
  margin-bottom: 5px;
}
.multi-actions button {
  font: inherit; font-size: 11px; font-weight: 600;
  padding: 3px 9px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
}
.multi-actions button:hover { border-color: var(--accent); color: var(--accent-deep); }
.multi-liste label {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 8px;
  border-radius: var(--radius-sm);
  font-size: 12.5px;
  cursor: pointer;
}
.multi-liste label:hover { background: var(--surface-2); }
/* Le libellé plie maintenant que le panneau est plafonné : « min-width: 0 »
   parce qu'un élément flex refuse par défaut de descendre sous sa largeur de
   contenu minimale, et que sans cette ligne le plafond ci-dessus serait
   simplement débordé par l'intérieur. */
.multi-liste label > span { min-width: 0; overflow-wrap: anywhere; }
.multi-liste .cpt { flex: none; font-size: 11px; color: var(--text-faint); font-variant-numeric: tabular-nums; }

/* --- 35. Tri des colonnes ------------------------------------------------- */
.tbl th.triable { cursor: pointer; user-select: none; }
.tbl th.triable:hover { color: var(--accent-deep); }
.tbl th.triable::after {
  content: "\2195";
  margin-left: 5px;
  opacity: .3;
  font-weight: 400;
}
.tbl th.tri-asc::after  { content: "\2191"; opacity: 1; color: var(--accent); }
.tbl th.tri-desc::after { content: "\2193"; opacity: 1; color: var(--accent); }

/* --- 36. Formulaires de réglages ------------------------------------------ */
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 13px 16px; }
.form-grid > label { display: block; font-size: 11.5px; color: var(--text-muted); }
.form-grid > label.col-2 { grid-column: 1 / -1; }
.form-grid > label > .input,
.form-grid > label > .champ-secret { margin-top: 5px; }

.champ-secret { position: relative; display: block; }
.champ-secret .input { padding-right: 38px; }
.champ-secret .oeil {
  position: absolute;
  top: 50%; right: 6px;
  transform: translateY(-50%);
  width: 26px; height: 26px;
  font: inherit; font-size: 13px;
  border: none; border-radius: var(--radius-sm);
  background: none; color: var(--text-faint);
  cursor: pointer;
}
.champ-secret .oeil:hover { background: var(--surface-3); color: var(--text); }

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

/* --- 37. Bouton menu et bascule de thème ---------------------------------- */
/* Le bouton menu n'existe que sous 900 px, là où la barre latérale se retire. */
.burger {
  display: none;
  position: fixed;
  top: 10px; left: 10px;
  z-index: 62;
  width: 40px; height: 40px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  box-shadow: var(--shadow);
  cursor: pointer;
}
.burger span {
  display: block;
  width: 18px; height: 2px;
  margin: 3px auto;
  border-radius: 2px;
  background: var(--text);
}
.menu-fond {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 58;
  background: rgba(12, 24, 35, .34);
}

.foot-theme {
  flex: none;
  width: 30px; height: 30px;
  font: inherit; font-size: 14px;
  border: none; border-radius: var(--radius-sm);
  background: none;
  color: var(--nav-item);
  cursor: pointer;
}
.foot-theme:hover { background: rgba(255, 255, 255, .09); color: #fff; }

/* --- 37 bis. Impression ---------------------------------------------------
   Un export PDF passe par l'impression : on ne sort que le tableau demandé,
   en paysage, avec son en-tête répétée à chaque page. */
@media print {
  body.mode-impression .sidebar,
  body.mode-impression .burger,
  body.mode-impression .page-head .row,
  body.mode-impression .volet,
  body.mode-impression .volet-fond,
  body.mode-impression .notifs,
  body.mode-impression .palette,
  body.mode-impression .modal-backdrop,
  body.mode-impression [data-filtres],
  body.mode-impression .col-actions,
  body.mode-impression .tabs { display: none !important; }

  body.mode-impression .app,
  body.mode-impression .main,
  body.mode-impression .content {
    display: block;
    height: auto;
    overflow: visible;
  }

  /* Seule la carte marquée sort, le reste du contenu est masqué — mais il faut
     laisser passer le *chemin* qui y mène. Sur une page à onglets, la carte vit
     dans un <section class="tab-panel"> qui, lui, n'est pas marqué, et qui est
     même masqué quand ce n'est pas l'onglet ouvert : sans ces deux règles,
     l'impression rendait une page blanche. Le script marque les ancêtres. */
  body.mode-impression .content > *:not(.a-imprimer):not(.chemin-impression),
  body.mode-impression .chemin-impression > *:not(.a-imprimer):not(.chemin-impression) {
    display: none !important;
  }
  body.mode-impression .chemin-impression,
  body.mode-impression .a-imprimer { display: block !important; }

  body.mode-impression .a-imprimer {
    border: none;
    box-shadow: none;
  }
  body.mode-impression .table-wrap { max-height: none; overflow: visible; }
  body.mode-impression .tbl { font-size: 9px; }
  body.mode-impression .tbl th { position: static; }
  body.mode-impression .tbl thead { display: table-header-group; }
  body.mode-impression .tbl tr { break-inside: avoid; }
  /* Une barre dans un tableau double une colonne chiffrée : elle ne sert qu'à
     l'écran. Une barre de tableau de bord, elle, EST l'information — la masquer
     imprimait un dashboard sans ses jauges. */
  body.mode-impression .tbl .bar { display: none; }
  /* La frise de la fiche marché est gardée à l'impression : elle n'est le
     doublon d'aucune colonne. Les dates disent quand ; la barre dit par rapport
     aux autres chantiers et par rapport à aujourd'hui. */

  @page { size: A4 landscape; margin: 10mm; }
}

/* --- 38. Adaptatif --------------------------------------------------------
   Trois paliers : on resserre les grilles, puis on retire la barre latérale
   au profit d'un panneau glissant, puis on passe tout en une colonne. */
@media (max-width: 1300px) {
  .grid-6 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .grid-sante3 { grid-template-columns: 280px minmax(0, 1fr); }
  .hero-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .info-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 1100px) {
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid-3, .grid-2-1, .grid-1-2 { grid-template-columns: 1fr; }
  .kanban { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .carte-grid { grid-template-columns: 1fr; }
  .marche-grid { grid-template-columns: 1fr; }
}

/* Sous 900 px la barre latérale devient un panneau que l'on ouvre. */
@media (max-width: 900px) {
  .app { grid-template-columns: 1fr; grid-template-areas: "main"; }

  .burger { display: block; }

  .sidebar {
    position: fixed;
    top: 0; left: 0;
    z-index: 60;
    width: var(--sidebar-w);
    transform: translateX(-101%);
    transition: transform .18s ease-out;
    box-shadow: var(--shadow-lg);
  }
  .app.menu-ouvert .sidebar { transform: none; }
  .app.menu-ouvert .menu-fond { display: block; }

  .grid-sante2, .grid-sante3 { grid-template-columns: 1fr; }
  .grid-6, .grid-4, .grid-2, .kanban { grid-template-columns: 1fr; }
  .hero-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  /* place pour le bouton menu, qui flotte au-dessus de la tête */
  .page-head { padding-left: 60px; }

  .auth { grid-template-columns: minmax(0, 1fr); }
  .auth-panel { min-width: 0; }
  .auth-aside { display: none; }
  .auth-panel { padding: 32px 24px; }
}

/* Téléphone : la tête doit rester une tête, pas la moitié de l'écran. */
@media (max-width: 620px) {
  .content { padding: 13px; }

  .page-head { flex-direction: column; align-items: stretch; gap: 10px; padding: 13px 13px 12px 58px; }
  .page-head h1 { font-size: 19px; }
  .page-head .page-sub { font-size: 12px; }
  .page-head .breadcrumb { font-size: 11px; }
  .page-head > .row { padding-left: 0; }
  .page-head .btn { flex: 1; justify-content: center; padding: 8px 10px; font-size: 12px; }

  .h1-row { gap: 7px; }
  .geo-chip { font-size: 10.5px; }

  .tabs { top: -13px; box-shadow: 0 -13px 0 var(--bg); }
  .tab { padding: 11px 10px; font-size: 12px; }

  .card-head { flex-wrap: wrap; }
  .info-grid, .info-grid.col-2, .form-grid { grid-template-columns: 1fr; }
  .table-wrap { max-height: none; }

  /* les frises ne se compriment pas : elles défilent */
  .gantt { min-width: 620px; }
  .gantt-wrap, .card-body:has(> .gantt) { overflow-x: auto; }

  .volet { width: 100%; }
  .notifs { left: 8px !important; right: 8px; width: auto; }
  .palette { top: 6vh; width: calc(100vw - 16px); }

  .carte-leaflet { height: 58vh; }
  .col-marche, .col-fenetre { min-width: 140px; }
}
